Операция GroupBy с использованием целого кадра данных для группировки значений - PullRequest
10 голосов
/ 06 июня 2019

У меня есть 2 таких кадра данных ...

np.random.seed(0)
a = pd.DataFrame(np.random.randn(20,3))
b = pd.DataFrame(np.random.randint(1,5,size=(20,3)))

Я бы хотел найти среднее значение в a для 4 групп в b.

Это ...

a[b==1].sum().sum() / a[b==1].count().sum()

... работает для одной группы за раз, но мне было интересно, может ли кто-нибудь придумать более чистый метод.

Мой ожидаемый результат -

1   -0.088715
2   -0.340043
3   -0.045596
4    0.582136
dtype: float64

Спасибо.

Ответы [ 2 ]

11 голосов
/ 06 июня 2019

Вы можете stack, затем groupby два Series

a.stack().groupby(b.stack()).mean()
6 голосов
/ 06 июня 2019

Если вы хотите быстрое решение для numpy, используйте np.unique и np.bincount:

c, d = (a_.to_numpy().ravel() for a_ in [a, b]) 
u, i, cnt = np.unique(d, return_inverse=True, return_counts=True)

np.bincount(i, c) / cnt
# array([-0.0887145 , -0.34004319, -0.04559595,  0.58213553])

Чтобы построить серию, используйте

pd.Series(np.bincount(i, c) / cnt, index=u)

1   -0.088715
2   -0.340043
3   -0.045596
4    0.582136
dtype: float64

Для сравнения stackвозвращает,

a.stack().groupby(b.stack()).mean()

1   -0.088715
2   -0.340043
3   -0.045596
4    0.582136
dtype: float64

%timeit a.stack().groupby(b.stack()).mean()
%%timeit
c, d = (a_.to_numpy().ravel() for a_ in [a, b]) 
u, i, cnt = np.unique(d, return_inverse=True, return_counts=True)
np.bincount(i, c) / cnt

5.16 ms ± 305 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
113 µs ± 1.92 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...