簡體   English   中英

帶有條件aggfunc的Pandas數據透視表

[英]Pandas pivot table with conditional aggfunc

我的熊貓數據框如下:

df = pd.DataFrame({"PAR NAME":['abc','def','def','def','abc'], "value":[1,2,3,4,5],"DESTCD":['E','N','E','E','S']})

我需要為PAR NAME設置df,並找出其值的%age來自DESTCD為'E'的地方。 像這樣的東西(顯然沒有用!)

df.pivot_table(index="PAR NAME",values=["value"],aggfunc={'value':lambda x: (x.sum() if x["DESTCD"]=="E")*100.0/x.sum()})

我目前正在通過添加條件列,然后將其與數據透視表中的“值”相加然后進行除法來做到這一點,但是我的數據庫很大(1gb +),必須有一種更簡單的方法。

編輯:預期輸出abc 16.67(由於abc和E是總abc的1等於6)def 77.78(因為def和E是9的總def);

可以使用多個基於PAR NAME groupby方法代替透視表,然后應用所需的操作。

new = df[df['DESTCD']=='E'].groupby('PAR NAME')['value'].sum()*100/df.groupby('PAR NAME')['value'].sum()

輸出:

PAR NAME
abc    16.666667
def    77.777778
Name: value, dtype: float64

如果你想要時間

%%timeit

df[df['DESTCD']=='E'].groupby('PAR NAME')['value'].sum()*100/df.groupby('PAR NAME')['value'].sum()
100 loops, best of 3: 4.03 ms per loop

%%timeit
df = pd.concat([df]*10000)
df[df['DESTCD']=='E'].groupby('PAR NAME')['value'].sum()*100/df.groupby('PAR NAME')['value'].sum()

100 loops, best of 3: 15.6 ms per loop

我試圖解決該問題而未特別提及“ E”,因此可以將其推廣到任何字母。 輸出是一個數據框,您可以在E上建立索引以獲取答案。 我只是簡單地單獨進行聚合,然后使用有效的聯接方法。

df = pd.DataFrame({"PAR NAME":['abc','def','def','def','abc'], "value":[1,2,3,4,5],"DESTCD":['E','N','E','E','S']})

# First groupby 'DESTCD' and 'PAR NAME'
gb = df.groupby(['DESTCD', 'PAR NAME'], as_index=False).sum()
print(gb)
  DESTCD PAR NAME  value
0      E      abc      1
1      E      def      7
2      N      def      2
3      S      abc      5

gb_parname = gb.groupby(['PAR NAME']).sum()
out = gb.join(gb_parname, on='PAR NAME', rsuffix='Total')
print(out)
  DESTCD PAR NAME  value  valueTotal
0      E      abc      1           6
1      E      def      7           9
2      N      def      2           9
3      S      abc      5           6

out.loc[:, 'derived']= out.apply(lambda df: df.value/df.valueTotal, axis=1)

print(out)
  DESTCD PAR NAME  value  valueTotal   derived
0      E      abc      1           6  0.166667
1      E      def      7           9  0.777778
2      N      def      2           9  0.222222
3      S      abc      5           6  0.833333

這也是一個相對有效的操作

%%timeit
gb = df.groupby(['DESTCD', 'PAR NAME'], as_index=False).sum()
gb_parname = gb.groupby(['PAR NAME']).sum()
out = gb.join(gb_parname, on='PAR NAME', rsuffix='Total')
out.loc[:, 'derived']= out.apply(lambda df: df.value/df.valueTotal, axis=1)
100 loops, best of 3: 6.31 ms per loop

我還找到了一種通過數據透視來回答問題的方法,該方法與所選答案同樣有效! 為了方便其他人,在此處添加:

df.pivot_table(index="PAR NAME",values=["value"],aggfunc={'value':lambda x: x[df.iloc[x.index]['DESTCD']=='E'].sum()*100.0/x.sum()})

邏輯是aggfunc僅適用於有問題的系列,在引用索引到主df之前無法引用任何其他系列。

暫無
暫無

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

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