value_counts и нормализовать в группах - PullRequest
0 голосов
/ 14 декабря 2018

У меня есть этот фрейм данных:

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, сгруппированные по имени.

Я знаю, как получитьvalue_counts с использованием функции agg:

(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)

НоИнтересно, есть ли более пандашский способ сделать это ...

Ответы [ 2 ]

0 голосов
/ 15 декабря 2018

Полагаю, вы можете 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
0 голосов
/ 15 декабря 2018

Вы можете использовать:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...