【问题标题】:How to run a groupby based on result of other/previous groupby?如何根据其他/前一个 groupby 的结果运行 groupby?
【发布时间】:2019-01-30 21:18:19
【问题描述】:

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

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

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) 查找具有 Max(sales) 的国家/地区

2) 在那个国家,找到 Max(sales) 的地区

3) 在那个地区,找到 Max(sales) 的城市

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

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

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

你有什么想法,我如何在 pandas/python 中实现它?

【问题讨论】:

    标签: python pandas pandas-groupby


    【解决方案1】:

    想法是每个级别聚合sumSeries.idxmax 为 top1 值,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
    

    【讨论】:

    • 完美运行!谢谢,耶斯瑞尔!我不知道 idxmax() 方法。
    【解决方案2】:

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

    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],等等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-29
      • 2020-07-04
      • 2014-01-09
      • 1970-01-01
      • 2016-03-12
      • 1970-01-01
      相关资源
      最近更新 更多