如何基于列内爆(熊猫的反向爆炸)

kri*_*oti 14 numpy explode implode pandas

我有一个像下面这样的数据框 df

  NETWORK       config_id       APPLICABLE_DAYS  Case    Delivery  
0   Grocery     5399            SUN               10       1        
1   Grocery     5399            MON               20       2       
2   Grocery     5399            TUE               30       3        
3   Grocery     5399            WED               40       4       
Run Code Online (Sandbox Code Playgroud)

我想内爆(将 Applicable_days 从多行组合成单行,如下所示)并获得每个 config_id 的平均情况和交付

  NETWORK       config_id       APPLICABLE_DAYS      Avg_Cases    Avg_Delivery 
0   Grocery     5399            SUN,MON,TUE,WED         90           10

Run Code Online (Sandbox Code Playgroud)

使用网络上的 groupby,config_id 我可以获得 avg_cases 和 avg_delivery,如下所示。

df.groupby(['network','config_id']).agg({'case':'mean','delivery':'mean'})
Run Code Online (Sandbox Code Playgroud)

但是如何在执行此聚合时加入 APPLICABLE_DAYS ?

Dav*_*son 17

如果您想要爆炸的“相反”,那么这意味着将其放入解决方案 #1 中的列表中。您还可以在解决方案#2 中作为字符串加入:

使用lambda x: x.tolist()'APPLICABLE_DAYS'您的内柱.aggGROUPBY功能:

df = (df.groupby(['NETWORK','config_id'])
      .agg({'APPLICABLE_DAYS': lambda x: x.tolist(),'Case':'mean','Delivery':'mean'})
      .rename({'Case' : 'Avg_Cases','Delivery' : 'Avg_Delivery'},axis=1)
      .reset_index())
df
Out[1]: 
   NETWORK  config_id       APPLICABLE_DAYS  Avg_Cases  Avg_Delivery
0  Grocery       5399  [SUN, MON, TUE, WED]         25           2.5
Run Code Online (Sandbox Code Playgroud)

使用lambda x: ",".join(x)'APPLICABLE_DAYS'您的内柱.aggGROUPBY功能:

 df = (df.groupby(['NETWORK','config_id'])
      .agg({'APPLICABLE_DAYS': lambda x: ",".join(x),'Case':'mean','Delivery':'mean'})
      .rename({'Case' : 'Avg_Cases','Delivery' : 'Avg_Delivery'},axis=1)
      .reset_index())
df
Out[1]: 
   NETWORK  config_id       APPLICABLE_DAYS  Avg_Cases  Avg_Delivery
0  Grocery       5399       SUN,MON,TUE,WED         25           2.5
Run Code Online (Sandbox Code Playgroud)

如果你正在寻找的sum,那么你可以改变mean,以sumCasesDelivery列。


sam*_*mmy 11

你的结果看起来更像是一个总和,而不是平均值;下面的解决方案使用命名聚合

    df.groupby(["NETWORK", "config_id"]).agg(
    APPLICABLE_DAYS=("APPLICABLE_DAYS", ",".join),
    Total_Cases=("Case", "sum"),
    Total_Delivery=("Delivery", "sum"),
)

                        APPLICABLE_DAYS       Total_Cases   Total_Delivery
NETWORK config_id           
Grocery 5399                SUN,MON,TUE,WED           100      10
Run Code Online (Sandbox Code Playgroud)

如果是平均值,那么您可以将 'sum' 更改为 'mean' :

df.groupby(["NETWORK", "config_id"]).agg(
    APPLICABLE_DAYS=("APPLICABLE_DAYS", ",".join),
    Avg_Cases=("Case", "mean"),
    Avg_Delivery=("Delivery", "mean"),
)

                    APPLICABLE_DAYS   Avg_Cases Avg_Delivery
NETWORK config_id           
Grocery 5399         SUN,MON,TUE,WED      25      2.5
Run Code Online (Sandbox Code Playgroud)

  • 如果你想要一个列表而不是字符串,你可以这样做: `... APPLICABLE_DAYS=("APPLICABLE_DAYS", pd.Series.to_list) ...` (2认同)