如何根据其他/以前的groupby结果运行groupby?

时间:2019-01-30 13:06:05

标签: python pandas pandas-groupby

让我们假设您正在全球范围内销售产品,并且想要在主要城市的某个地方建立销售办事处。您的决定将完全基于销售数字。

这将是您的(简化的)销售数据:

df={
'Product':'Chair',
'Country': ['USA','USA', 'China','China','China','China','India', 
'India','India','India','India','India', 'India'],
'Region': ['USA_West','USA_East', 'China_West','China_East','China_South','China_South', 'India_North','India_North', 'India_North','India_West','India_West','India_East','India_South'],
'City': ['A','B', 'C','D','E', 'F', 'G','H','I', 'J','K', 'L', 'M'],
'Sales':[1000,1000, 1200,200,200, 200,500 ,350,350,100,700,50,50]  
}

dff=pd.DataFrame.from_dict(df)

dff

根据数据,您应前往城市“ G”。

逻辑应该像这样:

1)使用最高(销售)查找国家/地区

2)在该国家/地区中,找到Max(sales)

3)在该地区,找到具有最高(销售额)的城市

我尝试过:groupby('Product', 'City').apply(lambda x: x.nlargest(1)),但这是行不通的,因为它将建议使用城市“ C”。这是全球销量最高的城市,但中国不是销量最高的国家。

我可能必须经历几个groupby循环。根据结果​​,过滤原始数据帧并在下一级再次进行分组。

要增加复杂性,您还出售其他产品(不仅是“椅子”,还出售其他家具)。您必须将每次迭代的结果(例如,每个产品具有最高销售量的国家/地区)存储在某个位置,然后在groupby的下一次迭代中使用它。

您有什么想法,如何在pandas / python中实现呢?

2 个答案:

答案 0 :(得分:3)

想法是每个级别的汇总sum,其中top1值是Series.idxmax,用于boolean indexing的下一级过滤:

max_country = dff.groupby('Country')['Sales'].sum().idxmax()
max_region = dff[dff['Country'] == max_country].groupby('Region')['Sales'].sum().idxmax()
max_city = dff[dff['Region'] == max_region].groupby('City')['Sales'].sum().idxmax()
print (max_city)
G

答案 1 :(得分:0)

一种方法是添加分组总计,然后对数据框进行排序。通过使用偏好逻辑对所有数据进行排序,这超出了您的要求:

df = pd.DataFrame.from_dict(df)

factors = ['Country', 'Region', 'City']
for factor in factors:
    df[f'{factor}_Total'] = df.groupby(factor)['Sales'].transform('sum')

res = df.sort_values([f'{x}_Total' for x in factors], ascending=False)

print(res.head(5))

   City Country Product       Region  Sales  Country_Total  Region_Total  \
6     G   India   Chair  India_North    500           2100          1200   
7     H   India   Chair  India_North    350           2100          1200   
8     I   India   Chair  India_North    350           2100          1200   
10    K   India   Chair   India_West    700           2100           800   
9     J   India   Chair   India_West    100           2100           800   

    City_Total  
6          500  
7          350  
8          350  
10         700  
9          100  

因此,对于最需要的用户,可以使用res.iloc[0],对于第二个res.iloc[1],依此类推。