Pandas DataFrame基于多个条件的分组添加新的列值

时间:2020-01-16 07:55:33

标签: python python-3.x pandas dataframe group-by

我有一个如下的DataFrame

       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

我想通过将PrevoiousMonthQty和{{1}分组的逻辑,向此数据框添加一个额外的列Qty,并在(Color, Month)列中填充值}是Month

我期望的目标DataFrame看起来像这样

enter image description here

一些逻辑解释可以看作是

enter image description here

任何帮助将不胜感激。

非常感谢您。

3 个答案:

答案 0 :(得分:2)

找到上个月后,可以使用Multindexmap

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)

输出:

       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

详细信息:

第1步:通过将Month列转换为日期时间并使用pd.Timedelta减去1个月来查找上个月。

第2步:创建一个多索引系列,以数量作为值,以ColorMonth作为索引。

Step3 :使用Colorprev_month系列创建一个MultiIndex并将其映射回新列(也用0填充nan)

答案 1 :(得分:1)

使用DataFrame.pivot来调整DataFrame的形状,并在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  

然后将numpy.rollDataFrame.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

答案 2 :(得分:1)

这是使用merge的另一种方法-我们将prv_month键“合并”,我们将assign内联:

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))

[出]

   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