我有这个数据框:
Name | Survey_A | Survey_B
----------------------------
A | y | z
A | z | z
A | y | y
B | z | y
B | z | y
B | y | z
我想在Survey_A和Survey_B中获得按名称分组的每种类型的标准化值计数。
我知道如何使用agg
函数获取value_counts:
(df
.groupby('Name')
.agg({i:'value_counts' for i in
df[['Survey_A', 'Survey_B']]})
给出:
Name | type | Survey_A | Survey_B
--------------------------------------
A | y | 2 | 1
| z | 1 | 2
B | y | 1 | 2
| z | 2 | 1
但是我不知道如何像使用value_counts
一样获得标准化的pandas.Series.value_counts(normalize=True)
我知道如何在一列上做到这一点:
(df
.groupby('Name')['Survey_A']
.value_counts(normalize=True))
哪个给:
Name | type | Survey_A
--------------------------
A | y | 0.666
| z | 0.333
B | y | 0.333
| z | 0.666
但不是几个。我尝试过:
(df
.groupby('Name')
.agg({i: lambda x:
x.value_counts(normalize=true) for i
in df[['Survey_A', 'Survey_B']]}))
但没有成功。
使用这样的自定义功能是可能的:
def get_pct(g):
output = pd.DataFrame()
for c in g[['Survey_A', 'Survey_B']]:
output[c] = g[c].value_counts(normalize=True)
return output
df.groupby('Name').apply(get_pct)
但是我想知道是否还有其他的熊猫方法...
答案 0 :(得分:0)
您可以使用:
df.groupby('x').agg({'Survey_A': 'value_counts', 'Survey_B': 'value_counts'})
但是NaN
值将在输出数据框中:
>>> df
x x2 x3
0 A z a
1 A z a
2 A y d
3 B y a
4 B z d
>>> df.groupby('x').agg({'x2': 'value_counts', 'x3': 'value_counts'})
x2 x3
A a NaN 2.0
d NaN 1.0
y 1.0 NaN
z 2.0 NaN
B a NaN 1.0
d NaN 1.0
y 1.0 NaN
z 1.0 NaN
答案 1 :(得分:0)
我想您可以groupby
并获得value_counts
并对其进行规范化,但是我看不出它的运行速度快于您的功能:
df.groupby('Name').agg({i:'value_counts' for i in df.columns[1:]}).groupby(level=0).transform(lambda x: x.div(x.sum()))
Survey_A Survey_B
A y 0.666667 0.333333
z 0.333333 0.666667
B y 0.333333 0.666667
z 0.666667 0.333333