我有一个名为df
的DataFrame,我想计算不同app_0
上app_1
,app_2
和sex
列中的最高频率元素。
import pandas as pd
import numpy as np
df=pd.DataFrame({'id':[1,2,3,4],'app_0':['a','b','c','d'],
'app_1':['b','c','d',np.nan],'app_2':['c','b','a','a'],'sex':[0,0,1,1]})
Input:
df
id app_0 app_1 app_2 sex
0 1 a b c 0
1 2 b c b 0
2 3 c d a 1
3 4 d NaN a 1
如您所见,sex
和id 1
的{{1}}均为id 2
。对于0
,sex 0
在b
,app_0
和app_1
列中出现最多,app_2
在倒数第二位。因此,对于c
和id 1
,频率最高的元素是id 2
,第二频率最高的是b
。
c
Expected:
答案 0 :(得分:2)
对stack
和value_counts
使用自定义功能:
def f(x):
s = x.stack().value_counts()
return pd.Series([s.index[0], s.index[1]], index=['top_1','top_2'])
或将Counter
与Counter.most_common
的取整值一起使用:
from collections import Counter
def f(x):
c = Counter([y for x in x.values.tolist() for y in x])
a = c.most_common(2)
return pd.Series([a[0][0], a[1][0]], index=['top_1','top_2'])
df1 = df.groupby('sex')['app_0','app_1','app_2'].apply(f)
df = df.join(df1, on='sex')
print (df)
id app_0 app_1 app_2 sex top_1 top_2
0 1 a b c 0 b c
1 2 b c b 0 b c
2 3 c d a 1 a d
3 4 d NaN a 1 a d
编辑:
如果next
不存在第二个最高值,则可以使用更通用的解决方案:
df=pd.DataFrame({'id':[1,2,3,4],'app_0':['a','a','a','a'],
'app_1':['a','a','a',np.nan],'app_2':['a','a','a','a'],'sex':[0,0,1,1]})
print (df)
id app_0 app_1 app_2 sex
0 1 a a a 0
1 2 a a a 0
2 3 a a a 1
3 4 a NaN a 1
def f(x):
c = Counter([y for x in x.values.tolist() for y in x])
a = iter(c.most_common(2))
return pd.Series([next(a, ['no top1'])[0],
next(a, ['no top2'])[0]], index=['top_1','top_2'])
df1 = df.groupby('sex')['app_0','app_1','app_2'].apply(f)
df = df.join(df1, on='sex')
print (df)
id app_0 app_1 app_2 sex top_1 top_2
0 1 a a a 0 a no top2
1 2 a a a 0 a no top2
2 3 a a a 1 a NaN
3 4 a NaN a 1 a NaN