Reputation: 1622
I have a DataFrame as below
Color Month Quantity
index
0 1 1 34047
1 1 2 36654
2 2 3 37291
3 2 4 35270
4 3 5 35407
5 1 12 9300
I want to add a more extra column PrevoiousMonthQty
to this Dataframe with the filled values in the Qty
column by the logic that we will group by (Color, Month)
and the Month
is the Previous Month
The target DataFrame I expected looks like this
Some logic explanation can be seen as
Any helps would be very much appreciated.
Thank you very much.
Upvotes: 1
Views: 1042
Reputation: 75080
Here is a way using Multindex
and map
after finding the previous month:
prev_month = pd.to_datetime(df['Month'],format='%m').sub(pd.Timedelta(1,unit='m')).dt.month
m = df.set_index(['Color','Month'])['Quantity']
final = (df.assign(Prev_Month_Value=pd.MultiIndex.from_arrays([df['Color'],prev_month])
.map(m).fillna(0)))
#To assign into the existing df,use below code instead of df.assign() which returns a copy
#df['Previous Month Value'] = (pd.MultiIndex.from_arrays([df['Color'],prev_month])
# .map(m).fillna(0)
Output:
Color Month Quantity Prev_Month_Value
index
0 1 1 34047 9300.0
1 1 2 36654 34047.0
2 2 3 37291 0.0
3 2 4 35270 37291.0
4 3 5 35407 0.0
5 1 12 9300 0.0
Details:
Step1 : Find previous month by converting
Month
column to datetime and subtract 1 month usingpd.Timedelta
.Step2: Create a multiindex series with Quantity as value and
Color
andMonth
as index.Step3: Create a MultiIndex using
Color
andprev_month
series and map it back as new column (also fill nan with 0)
Upvotes: 2
Reputation: 862641
Use DataFrame.pivot
for reshape DataFrame and add full months by DataFrame.reindex
:
df1 = df.pivot('Color','Month','Oty').reindex(columns=range(1,13))
print (df1)
Month 1 2 3 4 5 6 7 8 9 10 11 \
Color
1 34047.0 36654.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 NaN NaN 37291.0 35270.0 NaN NaN NaN NaN NaN NaN NaN
3 NaN NaN NaN NaN 35407.0 NaN NaN NaN NaN NaN NaN
Month 12
Color
1 9300.0
2 NaN
3 NaN
Then use numpy.roll
with DataFrame.join
:
s = pd.DataFrame(np.roll(df1.to_numpy(), 1, axis=1),
index=df1.index,
columns=df1.columns).stack().rename('Previous Month')
df = df.join(s, on=['Color','Month']).fillna({'Previous Month':0})
print (df)
Index Color Month Oty Previous Month
0 0 1 1 34047 9300.0
1 1 1 2 36654 34047.0
2 2 2 3 37291 0.0
3 3 2 4 35270 37291.0
4 4 3 5 35407 0.0
5 5 1 12 9300 0.0
Upvotes: 1
Reputation: 18647
Here is another approach using merge
- we'll "merge" on a prv_month
key which we'll assign
inline:
df['PreviousQty'] = (df.assign(prv_month=df['Month'].sub(1).where(lambda x: x!=0, 12))
.merge(df,
how='left',
left_on=['Color', 'prv_month'],
right_on=['Color', 'Month'])['Qty_y'].fillna(0))
[out]
Color Month Qty PreviousQty
0 1 1 34047 9300.0
1 1 2 36654 34047.0
2 2 3 37291 0.0
3 2 4 35270 37291.0
4 3 5 35407 0.0
5 1 12 9300 0.0
Upvotes: 3