Применение пользовательской агрегатной функции groupby для нахождения среднего значения Numpy Array - PullRequest
0 голосов
/ 25 апреля 2020

У меня есть pandas DataFrame, где B содержит NumPy список фиксированного размера.

|------|---------------|-------|
|  A   |       B       |   C   |
|------|---------------|-------|
|  0   |   [2,3,5,6]   |   X   |
|------|---------------|-------|
|  1   |   [1,2,3,4]   |   X   |
|------|---------------|-------|
|  2   |   [2,3,6,5]   |   Y   |
|------|---------------|-------|
|  3   |   [2,3,2,3]   |   Y   |
|------|---------------|-------|
|  4   |   [2,3,4,4]   |   Y   |
|------|---------------|-------|
|  5   |   [2,3,5,6]   |   Z   |
|------|---------------|-------|

Я хочу сгруппировать их по столбцам 'C' и вычислить среднее значение значений «Б» как список. Как таблица приведена ниже. Я хочу сделать это эффективно.

|----------------|-------|
|        B       |   C   |
|----------------|-------|
|  [1.5,2.5,4,5] |   X   |
|----------------|-------|
|    [2,3,4,4]   |   Y   |
|----------------|-------|
|    [2,3,5,6]   |   Z   |
|----------------|-------|

Я рассмотрел возможность разбить список NumPy на отдельные столбцы. Но это был бы мой последний вариант.

Как написать собственную функцию агрегирования, как сейчас: в столбце B отображается не цифра c и отображается

DataError: No numeric types to aggregate 

1 Ответ

3 голосов
/ 25 апреля 2020

То, что вам нужно, возможно с преобразованием значений в 2d массив и последующим использованием np.mean:

f = lambda x: np.mean(np.array(x.tolist()), axis=0)
df2 = df.groupby('C')['B'].apply(f).reset_index()
print (df2)
   C                     B
0  X  [1.5, 2.5, 4.0, 5.0]
1  Y  [2.0, 3.0, 4.0, 4.0]
2  Z  [2.0, 3.0, 5.0, 6.0]

Возможно последнее решение, но менее эффективное (спасибо @Abhik Sarkar за тест):

df1 = pd.DataFrame(df.B.tolist()).groupby(df['C']).mean()
df2 = pd.DataFrame({'B': df1.values.tolist(), 'C': df1.index})
print (df2)
                      B  C
0  [1.5, 2.5, 4.0, 5.0]  X
1  [2.0, 3.0, 4.0, 4.0]  Y
2  [2.0, 3.0, 5.0, 6.0]  Z
...