Pandas 组中的值\计数和规格化

Pandas 组中的值\计数和规格化,pandas,pandas-groupby,Pandas,Pandas Groupby,我有这个数据框: Name | Survey_A | Survey_B ---------------------------- A | y | z A | z | z A | y | y B | z | y B | z | y B | y | z >>> df x x2 x3 0 A z a 1 A

我有这个数据框:

Name  |  Survey_A |  Survey_B
----------------------------
A     |  y        |  z
A     |  z        |  z
A     |  y        |  y
B     |  z        |  y
B     |  z        |  y
B     |  y        |  z
>>> 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
我想得到测量A和测量B中每种类型的标准化值计数,按名称分组

我知道如何使用
agg
函数获取值\u计数:

(df
   .groupby('Name')
   .agg({i:'value_counts' for i in
     df[['Survey_A', 'Survey_B']]})
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
其中:

Name  |  type  |  Survey_A |  Survey_B
--------------------------------------
A     |  y     |  2        | 1
      |  z     |  1        | 2
B     |  y     |  1        | 2
      |  z     |  2        | 1
Name  |  type  |  Survey_A
--------------------------
A     |  y     |  0.666     
      |  z     |  0.333  
B     |  y     |  0.333   
      |  z     |  0.666    
但是我不知道如何获得规范化的
值\u计数
就像我使用
pandas.Series.value\u计数(normalize=True)

我知道如何在一个专栏中做到这一点:

(df
  .groupby('Name')['Survey_A']
  .value_counts(normalize=True))
其中:

Name  |  type  |  Survey_A |  Survey_B
--------------------------------------
A     |  y     |  2        | 1
      |  z     |  1        | 2
B     |  y     |  1        | 2
      |  z     |  2        | 1
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)
但我想知道是否有一种更为泛泛的方法……您可以使用:

df.groupby('x').agg({'Survey_A': 'value_counts', 'Survey_B': 'value_counts'})
但是
NaN
值将在输出数据帧中:

Name  |  Survey_A |  Survey_B
----------------------------
A     |  y        |  z
A     |  z        |  z
A     |  y        |  y
B     |  z        |  y
B     |  z        |  y
B     |  y        |  z
>>> 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

我想您可以
groupby
获取
值\u counts
并自己对其进行规范化,但我看不出它比您的函数快多少:

(df
   .groupby('Name')
   .agg({i:'value_counts' for i in
     df[['Survey_A', 'Survey_B']]})
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