簡體   English   中英

Pandas groupby 獲得過濾總和超過總和

[英]Pandas groupby get filtered sum over total sum

我有以下 dataframe:

df = pd.DataFrame([[1, 2, True], [1, 4, False], [2, 6, False], [2, 8, True]], columns=["Group", "Value", "C"])

   Group  Value      C
0      1      2   True
1      1      4  False
2      2      6  False
3      2      8   True

我希望每個組都知道 C 等於真的值總和的值總和。 因此,例如對於第 1 組,我們有 2 / (2+4)

我已經通過一些廣泛的搜索來達到以下階段:

df.groupby('Group').agg(lambda x: x.loc[x.C == True, 'Value'].sum() / x.Value.sum())

          Value         C
Group                    
1      0.333333  0.333333
2      0.571429  0.571429

但是(正如預期的那樣)我得到兩列,我只想得到一個。 我理想的結果是:

       Ratio        
Group                    
1      0.333333  
2      0.571429  

我當然可以在 groupby 之后進行一些修改並得到我想要的,但是由於我是 Python 的新手,我想知道我是否在這里遺漏了一些基本的東西。

我相信您可以在groupby.transform()上使用 sum 並在過濾后使用.assign()進行分配,以便在 ythe 索引上對齊:

df[df['C']].assign(Ratio=df['Value']/df.groupby('Group')['Value'].transform('sum'))

如果每組超過 1 個 True,請使用:

m=(df.groupby(['Group','C'],as_index=False,sort=False)['Value'].sum()
  .query('C==True').assign(Sum=df.groupby(['Group'])['Value'].transform('sum')))
m[['Group']].assign(Ratio=m['Value']/m['Sum'])

   Group     Ratio
0      1  0.333333
3      2  0.571429

您可以除以所有行的聚合過濾行,然后將 Series 轉換為一列DataFrame

filt = df.loc[df['C']].groupby('Group')['Value'].sum()
tot = df.groupby('Group')['Value'].sum()
df1 = filt.div(tot, fill_value=0).to_frame('ratio')
print (df1)
          ratio
Group          
1      0.333333
2      0.571429

您的解決方案可以通過更改.aggGroupBy.apply的所有列一起使用以返回Series ,但如果大數據/許多唯一組應該很慢:

df = (df.groupby('Group')
        .apply(lambda x: x.loc[x.C, 'Value'].sum() / x.Value.sum())
        .to_frame('ratio'))
print (df)
          ratio
Group          
1      0.333333
2      0.571429

解決方案也適用於只有False組:

df = pd.DataFrame([[0, 2, False], [1, 2, True], [1, 4, False], 
                   [2, 6, False], [2, 8, True]], columns=["Group", "Value", "C"])


df1 = (df.groupby('Group')
        .apply(lambda x: x.loc[x.C, 'Value'].sum() / x.Value.sum())
        .to_frame('ratio'))
print (df1)
          ratio
Group          
0      0.000000
1      0.333333
2      0.571429

filt = df.loc[df['C']].groupby('Group')['Value'].sum()
tot = df.groupby('Group')['Value'].sum()

print (df1)
          ratio
Group          
0      0.000000
1      0.333333
2      0.571429

您可以使用apply

result = df.groupby('Group').apply(lambda x: pd.Series({'ratio' : (x.Value * x.C).sum() / x.Value.sum()}))
print(result)

Output

          ratio
Group          
1      0.333333
2      0.571429

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM