根据Pandas中的另一个Columns值有条件地划分列

时间:2016-12-12 16:01:19

标签: python pandas

我有一个像这样的数据框:

Fruit Brand  Supermarket    Sold Revenue    
Apple   A       X            9     2
Apple   A       Y            2     0.5
Apple   B       X            2     1
Orange  A       X            4     1.3
Orange  B       Y            0     0
Banana  A       X            3     0
Apple   B       Z            0     0
.......

我想要做的是总结这些相对于水果类型和品牌的列。即品牌A的苹果,品牌B的苹果等等。

但是有一个转折,我也想要'已售出'和'收入'每个超市(X,Y,Z)分为三列,如:

Fruit Brand  Supermarket    Sold_x Sold_y Sold_z Revenue_x Revenue_y Revenue_z  
 Apple  A       X            9     0        0     2          0          0
 Apple  A       Y            0     2        0     0          0.5        0

在Pandas中最有效的方法是什么?

3 个答案:

答案 0 :(得分:1)

这个解决方案怎么样? 基本上我会做两个随后的groupby,第一个分为Fruit and Brand,第二个分组为超市。

cols = ['Fruit', 'Brand', 'Supermarket', 'Sold', 'Revenue']    
df = pd.DataFrame([['Apple',   'A',       'X',            9,     2],
['Apple',   'A',       'Y',            2,     0.5],
['Apple',   'B',       'X',            2,     1],
['Orange',  'A',       'X',            4,     1.3],
['Orange', 'B',       'Y',            0,     0],
['Banana',  'A',       'X',            3,     0],
['Apple',   'B',       'Z',            0,    0]], columns = cols)


out = {}
for key, group in df.groupby(['Fruit', 'Brand']):
    out[key] = {}

    for subkey, subgroup in group.groupby('Supermarket'):

        out[key][subkey] = subgroup[['Supermarket', 'Sold', 'Revenue']].add_suffix("_"+subkey.lower())

    out[key] = pd.concat(out[key], axis = 1)

out = pd.concat(out, axis = 0)
out.columns = out.columns.droplevel(0)

out = out.reset_index(level = 2, drop = True)\
         .fillna(0)\
         .reset_index().rename(columns = {'level_0' : 'Fruit', 'level_1' : 'Brand'})\
         .loc[:, ['Fruit', 'Brand', 'Sold_x', 'Sold_y', 'Sold_z', 'Revenue_x', 'Revenue_y', 'Revenue_z']]

最终结果如下:

out
Out[60]: 
    Fruit Brand  Sold_x  Sold_y  Sold_z  Revenue_x  Revenue_y  Revenue_z
0   Apple     A     9.0     0.0     0.0        2.0        0.0        0.0
1   Apple     A     0.0     2.0     0.0        0.0        0.5        0.0
2   Apple     B     2.0     0.0     0.0        1.0        0.0        0.0
3   Apple     B     0.0     0.0     0.0        0.0        0.0        0.0
4  Banana     A     3.0     0.0     0.0        0.0        0.0        0.0
5  Orange     A     4.0     0.0     0.0        1.3        0.0        0.0
6  Orange     B     0.0     0.0     0.0        0.0        0.0        0.0

答案 1 :(得分:1)

这看起来像pivot_table的完美工作:

df.pivot_table(index=['Fruit', 'Brand'], columns='Supermarket').fillna(0)

Out[8]: 
             Sold           Revenue          
Supermarket     X    Y    Z       X    Y    Z
Fruit  Brand                                 
Apple  A      9.0  2.0  0.0     2.0  0.5  0.0
       B      2.0  0.0  0.0     1.0  0.0  0.0
Banana A      3.0  0.0  0.0     0.0  0.0  0.0
Orange A      4.0  0.0  0.0     1.3  0.0  0.0
       B      0.0  0.0  0.0     0.0  0.0  0.0

现在您只需要重命名列。

答案 2 :(得分:1)

df.set_index(['Fruit', 'Brand', 'Supermarket']).unstack(fill_value=0.)

enter image description here