[英]Add index of value_counts() to new column for each group in groupby
[英]Pandas groupby each column and add new column for each group
我有這樣的數據框
lvl1=['l1A','l1A','l1B','l1C','l1D']
lvl2=['l2A','l2A','l2A','l26','l27']
wgt=[.2,.3,.15,.05,.3]
lvls=[lvl1,lvl2]
df=pd.DataFrame(wgt, lvls).reset_index()
df.columns = ['lvl' + str(i) for i in range(1,3)] + ['wgt']
df
lvl1 lvl2 wgt
0 l1A l2A 0.20
1 l1A l2A 0.30
2 l1B l2A 0.15
3 l1C l26 0.05
4 l1D l27 0.30
我想獲得每個級別的平均權重,並將它們作為單獨的列添加到此數據框中。
pd.concat([df, df.groupby('lvl1').transform('mean').add_suffix('_l1avg'), df.groupby('lvl2').transform('mean').add_suffix('_l2avg')], axis=1)
lvl1 lvl2 wgt wgt_l1avg wgt_l2avg
0 l1A l2A 0.20 0.25 0.216667
1 l1A l2A 0.30 0.25 0.216667
2 l1B l2A 0.15 0.15 0.216667
3 l1C l26 0.05 0.05 0.050000
4 l1D l27 0.30 0.30 0.300000
水平可以超過兩個,所以我想用變量來做這個。 當數據集變得非常大時,最好和最有效的方法是什么。 我不一定需要將它們放在同一個數據框中。 在這種情況下,它可以只是一個單獨的nxm矩陣(2 x 5)中的平均權重矩陣。
使用list comprehension
:
cols = ['lvl1','lvl2']
k = ['{}_avg'.format(x) for x in cols]
df = df.join(pd.concat([df.groupby(c)['wgt'].transform('mean') for c in cols], 1, keys=k))
print (df)
lvl1 lvl2 wgt lvl1_avg lvl2_avg
0 l1A l2A 0.20 0.25 0.216667
1 l1A l2A 0.30 0.25 0.216667
2 l1B l2A 0.15 0.15 0.216667
3 l1C l26 0.05 0.05 0.050000
4 l1D l27 0.30 0.30 0.300000
l=[]
l.append(df)
for x ,y in enumerate(df.columns[:-1]):
l.append(df.groupby(y).transform('mean').add_suffix('_{}1avg'.format(x+1)))
pd.concat(l,1)
Out[1328]:
lvl1 lvl2 wgt wgt_11avg wgt_21avg
0 l1A l2A 0.20 0.25 0.216667
1 l1A l2A 0.30 0.25 0.216667
2 l1B l2A 0.15 0.15 0.216667
3 l1C l26 0.05 0.05 0.050000
4 l1D l27 0.30 0.30 0.300000
這是一個非熊貓的解決方案。 從生成的字典中,可以有效地映射到列。
from collections import defaultdict
import pandas as pd
df = pd.DataFrame([['l1A', 'l2A', 0.20],
['l1A', 'l2A', 0.30],
['l1B', 'l2A', 0.15],
['l1C', 'l26', 0.05],
['l1D', 'l27', 0.30]],
columns=['lvl1', 'lvl2', 'wgt'])
results = defaultdict(lambda: defaultdict(float))
arr = df.values
for i in range(1, 3):
for x in sorted(np.unique(arr[:, i-1])):
results[i][x] = np.mean(arr[np.where(arr[:, i-1]==x)][:, 2])
df['avg_lvl'+str(i)] = df['lvl'+str(i)].map(results[i])
# lvl1 lvl2 wgt avg_lvl1 avg_lvl2
# 0 l1A l2A 0.20 0.25 0.216667
# 1 l1A l2A 0.30 0.25 0.216667
# 2 l1B l2A 0.15 0.15 0.216667
# 3 l1C l26 0.05 0.05 0.050000
# 4 l1D l27 0.30 0.30 0.300000
對於這個微型數據集,我看到3個響應的以下性能:
%timeit pandas1(df) # wen
# 10 loops, best of 3: 35 ms per loop
%timeit pandas2(df) # jezrael
# 100 loops, best of 3: 4.54 ms per loop
%timeit numpy1(df) # jp_data_analysis
# 1000 loops, best of 3: 1.88 ms per loop
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.