Pandas - агрегат DataFrame ведет себя странно - PullRequest
0 голосов
/ 26 февраля 2019

Относится к Проблема списка передачи агрегатного метода данных в кадре и Пандам не удается агрегировать со списком функций агрегирования

Рассмотреть этот фрейм данных

import pandas as pd
import numpy as np
df = pd.DataFrame(index=range(10))
df['a'] = [ 3 * x for x in range(10) ]
df['b'] = [ 1 -2 * x for x in range(10) ]

В соответствии с документацией для aggregate вы должны иметь возможность указать, какие столбцы агрегировать, используя dict, например:

df.agg({'a' : 'mean'})

, который возвращает

a    13.5

Но если вы попытаетесь aggregate с пользовательской функцией, подобной этой

def nok_mean(x):
    return np.mean(x)

df.agg({'a' : nok_mean})

Возвращает среднее значение для каждой строки, а не для столбца

      a
0   0.0
1   3.0
2   6.0
3   9.0
4  12.0
5  15.0
6  18.0
7  21.0
8  24.0
9  27.0

Почему пользовательская функция не возвращает то же самое, что и агрегирование с np.mean или 'mean'?

При этом используется pandas версия 0.23.4, numpy версия 1.15.4, pythonверсия 3.7.1

Ответы [ 3 ]

0 голосов
/ 26 февраля 2019

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

Когда вы передаете набор функций, ввод обрабатывается как DataFrame вместо уплощенного массива.После этого все вычисления по оси индекса выполняются по умолчанию.Вот почему вы получаете средства по строкам.

Если перейти на страницу документов , вы увидите:

Операции агрегирования всегда выполняютсяпо оси либо индекс (по умолчанию), либо ось столбца.Это поведение отличается от numpy функций агрегирования (mean, median, prod, sum, std, var), где по умолчанию вычисляется агрегация уплощенного массива, например, numpy.mean(arr_2d) в отличие от numpy.mean(arr_2d, axis=0).

__

Я думаю, что единственный способ подражать поведению numpy и передавать в одно и то же время команду функций agg - это df.agg(nok_mean)['a'].

0 голосов
/ 26 февраля 2019

Проблема связана с применением np.mean к серии.Давайте рассмотрим несколько примеров:

def nok_mean(x):
    return x.mean()

df.agg({'a': nok_mean})

a    13.5
dtype: float64

это работает, как и ожидалось, потому что вы используете версию среднего значения для панд, которая может быть применена к серии или фрейму данных:

df['a'].agg(nok_mean)
df.apply(nok_mean)

Давайтепосмотрим, что произойдет, когда np.mean применяется к серии:

def nok_mean1(x):
    return np.mean(x)

df['a'].agg(nok_mean1)
df.agg({'a':nok_mean1})
df['a'].apply(nok_mean1)
df['a'].apply(np.mean)

all возвращает

0     0.0
1     3.0
2     6.0
3     9.0
4    12.0
5    15.0
6    18.0
7    21.0
8    24.0
9    27.0
Name: a, dtype: float64

, когда вы применяете np.mean к кадру данных, который работает должным образом:

df.agg(nok_mean1)
df.apply(nok_mean1)

a    13.5
b    -8.0
dtype: float64

, чтобы заставить np.mean работать должным образом с функцией, передайте ndarray для x:

def nok_mean2(x):
    return np.mean(x.values)

df.agg({'a':nok_mean2})

a    13.5
dtype: float64

Я предполагаю, что все это связано с apply, которыйВот почему df['a'].apply(nok_mean2) возвращает ошибку атрибута.

Я предполагаю здесь в исходном коде

0 голосов
/ 26 февраля 2019

Когда вы определяете свою nok_mean функцию, определение вашей функции в основном говорит, что вы хотите np.mean для каждой строки

Он находит среднее для каждой строки и возвращает вамрезультат.Например, если ваш фрейм данных выглядит так:

    a           b
0   [0, 0]      1
1   [3, 4]      -1
2   [6, 8]      -3
3   [9, 12]     -5
4   [12, 16]    -7
5   [15, 20]    -9
6   [18, 24]    -11
7   [21, 28]    -13
8   [24, 32]    -15
9   [27, 36]    -17

, то df.agg({'a', nok_mean}) вернет это:

    a
0   0.0
1   3.5
2   7.0
3   10.5
4   14.0
5   17.5
6   21.0
7   24.5
8   28.0
9   31.5
...