长到宽的数据。熊猫

时间:2016-01-25 08:28:32

标签: python pandas

我正在尝试将我的数据框架从一个长格式,其中我有一个带有分类变量的列,变成一种宽格式,其中每个类别都有自己的价格列。目前,我的数据如下所示:

date-time            date       vendor    payment_type   price
03-10-15 10:00:00    03-10-15     A1            1          50
03-10-15 10:00:00    03-10-15     A1            2          60
03-10-15 10:00:00    03-11-15     A1            1          45
03-10-15 10:00:00    03-11-15     A1            2          70
03-10-15 10:00:00    03-12-15     B1            1          40
03-10-15 10:00:00    03-12-15     B1            2          45
03-10-15 10:00:00    03-10-15     C1            1          60
03-10-15 10:00:00    03-10-15     C1            1          65

我的目标是为每个供应商的价格和每种付款类型以及每天一行设置一列。当每天有多个值时,我想使用最大值。最终结果看起来应该是这样的。

Date       A1_Pay1   A2_Pay2 ... C1_Pay1   C1_Pay2
03-10-15     50        60    ...   65        NaN
03-11-15     45        70    ...   NaN       NaN
03-12-15     NaN       NaN   ...   NaN       NaN

我尝试使用unstack和pivot,但我要么得不到我想要的,要么得到关于Date不是唯一索引的错误。

有什么想法吗?

1 个答案:

答案 0 :(得分:4)

您可以使用pivot_table

#convert column payment_type to string
df['payment_type'] = df['payment_type'].astype(str)

df = pd.pivot_table(df, index='date', columns=['vendor', 'payment_type'], aggfunc=max)

#remove top level of multiindex
df.columns = df.columns.droplevel(0)

#reset multicolumns
df.columns = ['_Pay'.join(col).strip() for col in df.columns.values]

print df
            A1_Pay1  A1_Pay2  B1_Pay1  B1_Pay2  C1_Pay1
date                                                   
2015-03-10       50       60      NaN      NaN       65
2015-03-11       45       70      NaN      NaN      NaN
2015-03-12      NaN      NaN       40       45      NaN

编辑:

如果您需要其他统计信息,可以将其作为列表添加到aggfunc

#convert column payment_type to string
df['payment_type'] = df['payment_type'].astype(str)
df = pd.pivot_table(df, index='date', columns=['vendor', 'payment_type'], 
                                      aggfunc=[np.mean, np.max, np.median])
print df
              mean                    amax                 median              \
             price                   price                  price               
vendor          A1      B1        C1    A1      B1      C1     A1      B1       
payment_type     1   2   1   2     1     1   2   1   2   1      1   2   1   2   
date                                                                            
2015-03-10      50  60 NaN NaN  62.5    50  60 NaN NaN  65     50  60 NaN NaN   
2015-03-11      45  70 NaN NaN   NaN    45  70 NaN NaN NaN     45  70 NaN NaN   
2015-03-12     NaN NaN  40  45   NaN   NaN NaN  40  45 NaN    NaN NaN  40  45   



vendor          C1  
payment_type     1  
date                
2015-03-10    62.5  
2015-03-11     NaN  
2015-03-12     NaN 
#remove top level of multiindex
df.columns = df.columns.droplevel(1)
#reset multicolumns
df.columns = ['_Pay'.join(col).strip() for col in df.columns.values]
print df
            mean_PayA1_Pay1  mean_PayA1_Pay2  mean_PayB1_Pay1  \
date                                                            
2015-03-10               50               60              NaN   
2015-03-11               45               70              NaN   
2015-03-12              NaN              NaN               40   

            mean_PayB1_Pay2  mean_PayC1_Pay1  amax_PayA1_Pay1  \
date                                                            
2015-03-10              NaN             62.5               50   
2015-03-11              NaN              NaN               45   
2015-03-12               45              NaN              NaN   

            amax_PayA1_Pay2  amax_PayB1_Pay1  amax_PayB1_Pay2  \
date                                                            
2015-03-10               60              NaN              NaN   
2015-03-11               70              NaN              NaN   
2015-03-12              NaN               40               45   

            amax_PayC1_Pay1  median_PayA1_Pay1  median_PayA1_Pay2  \
date                                                                
2015-03-10               65                 50                 60   
2015-03-11              NaN                 45                 70   
2015-03-12              NaN                NaN                NaN   

            median_PayB1_Pay1  median_PayB1_Pay2  median_PayC1_Pay1  
date                                                                 
2015-03-10                NaN                NaN               62.5  
2015-03-11                NaN                NaN                NaN  
2015-03-12                 40                 45                NaN