Панды: zscore среди групп - PullRequest
1 голос
/ 06 марта 2019

Я пытаюсь найти z баллов значений среди групп, например, в следующих данных

df:

GROUP VALUE
 1     5
 2     2
 1     10
 2     20
 1     7

В группе 1 есть значения 5, 10, 7. Так что теперь я ищу их zscore только в их группе

Sample Desired Output: 

GROUP VALUE Z_SCORE
 1     5     0.5
 2     2     0.01
 1     10    7
 2     20    8.3
 1     7     1.3

zscore выше не являются истинными вычисленными значениями, это просто представление.

Я пытаюсь следующее

def z_score(x):
   z = np.abs(stats.zscore(x))
   return z

df['Z_SCORE'] = df.groupby(['GROUP'])['Value'].apply(z_score)

но не в состоянии сделать это успешно. Как мне этого добиться?

1 Ответ

3 голосов
/ 06 марта 2019

Используйте GroupBy.transform вместо apply для правильного преобразования числовых массивов в новые Series для групп:

from  scipy.stats import zscore

def z_score(x):
   z = np.abs(zscore(x))
   return z

df['Z_SCORE'] = df.groupby('GROUP')['VALUE'].transform(z_score)

print (df)
   GROUP  VALUE   Z_SCORE
0      1      5  1.135550
1      2      2  1.000000
2      1     10  1.297771
3      2     20  1.000000
4      1      7  0.162221

Решение с GroupBy.applyвозможно, но необходимо изменить функцию для возврата Series с индексом по каждой группе:

def z_score(x):
   z = np.abs(zscore(x))
   return pd.Series(z, index=x.index)


df['Z_SCORE'] = df.groupby('GROUP')['VALUE'].apply(z_score)
print (df)
   GROUP  VALUE   Z_SCORE
0      1      5  1.135550
1      2      2  1.000000
2      1     10  1.297771
3      2     20  1.000000
4      1      7  0.162221
...