pd.NamedAgg перезаписывает значения предыдущих столбцов - PullRequest
4 голосов
/ 26 мая 2020

Это фрейм данных, который я использовал.

      token name   ltp    change
0   12345.0  abc   2.0       NaN
1   12345.0  abc   5.0  1.500000
2   12345.0  abc   3.0 -0.400000
3   12345.0  abc   9.0  2.000000
4   12345.0  abc   5.0 -0.444444
5   12345.0  abc  16.0  2.200000
6    6789.0  xyz   1.0       NaN
7    6789.0  xyz   5.0  4.000000
8    6789.0  xyz   3.0 -0.400000
9    6789.0  xyz  13.0  3.333333
10   6789.0  xyz   9.0 -0.307692
11   6789.0  xyz  20.0  1.222222

Пытаясь решить этот вопрос , я обнаружил странное поведение pd.NamedAgg

#Worked as intended
df.groupby('name').agg(pos=pd.NamedAgg(column='change',aggfunc=lambda x: x.gt(0).sum()),\
                       neg = pd.NamedAgg(column='change',aggfunc=lambda x:x.lt(0).sum()))
# Output
      pos  neg
name
abc   3.0  2.0
xyz   3.0  2.0

При выполнении этого над спецификациями c столбца

df.groupby('name')<b>['change']</b>.agg(pos = pd.NamedAgg(column='change',aggfunc=lambda x:x.gt(0).sum()),\
                                 neg = pd.NamedAgg(column='change',aggfunc=lambda x:x.lt(0).sum()))
#Output
      pos  neg
name
abc   2.0  2.0
xyz   2.0  2.0

pos значения столбцов перезаписываются neg значениями столбцов.

Другой пример ниже:

df.groupby('name')<b>['change']</b>.agg(pos = pd.NamedAgg(column='change',aggfunc=lambda x:x.gt(0).sum()),\
                                 neg = pd.NamedAgg(column='change',aggfunc=lambda x:x.sum()))
#Output
           pos       neg
name
abc   4.855556  4.855556
xyz   7.847863  7.847863

Более странные результаты:

df.groupby('name')['change'].agg(pos = pd.NamedAgg(column='change',aggfunc=lambda x:x.gt(0).sum()),\
                                 neg = pd.NamedAgg(column='change',aggfunc=lambda x:x.sum()),\
                                 max = pd.NamedAgg(column='ltp',aggfunc='max'))

# I'm applying on Series `'change'` but I mentioned `column='ltp'` which should
# raise an `KeyError: "Column 'ltp' does not exist!"` but it produces results as follows

           pos       neg  max
name
abc   4.855556  4.855556  2.2
xyz   7.847863  7.847863  4.0

Проблема возникает при использовании с pd.Series

s = pd.Series([1,1,2,2,3,3,4,5])
s.groupby(s.values).agg(one = pd.NamedAgg(column='new',aggfunc='sum'))

   one
1    2
2    4
3    6
4    4
5    5

Разве это не должно вызвать KeyError?

Еще несколько странных результатов. Значения one столбца не перезаписываются, когда мы используем разные имена столбцов.

s.groupby(s.values).agg(one=pd.NamedAgg(column='anything',aggfunc='sum'),\
                        second=pd.NamedAgg(column='something',aggfunc='max'))

   one  second       
1    2       1     
2    4       2
3    6       3
4    4       4
5    5       5

Значения перезаписываются, когда мы используем то же имя столбца в pd.NamedAgg

s.groupby(s.values).agg(one=pd.NamedAgg(column='weird',aggfunc='sum'),\
                        second=pd.NamedAgg(column='weird',aggfunc='max'))

  one  second  # Values of column `one` are over-written
1  1       1
2  2       2
3  3       3
4  4       4
5  5       5

My pandas version

pd.__version__
# '1.0.3'

Из документации pandas:

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

In [82]: animals.groupby("kind").height.agg(
   ....:     min_height='min',
   ....:     max_height='max',
   ....: )
   ....: 
Out[82]: 
      min_height  max_height
kind                        
cat          9.1         9.5
dog          6.0        34.0

Но я не мог понять, почему его использование с column дает странные результаты.

ОБНОВЛЕНИЕ:

Отчет об ошибке подан @ jezrael в github issue #34380 и здесь тоже.

РЕДАКТИРОВАТЬ: Это ошибка, подтвержденная pandas -dev, и она была решена в PR ОШИБКА: агрегаты перезаписывались, если у них было то же имя #30858

1 Ответ

1 голос
/ 26 мая 2020

Если после groupby указаны столбцы, используйте решение, указанное в параграфе :

Именованное агрегирование также допустимо для агрегатов Series groupby. В этом случае нет выбора столбца, поэтому значения - это просто функции.

df = df.groupby('name')['change'].agg(pos = lambda x:x.gt(0).sum(),\
                                      neg = lambda x:x.lt(0).sum())
print (df)
      pos  neg
name          
abc   3.0  2.0
xyz   3.0  2.0

почему использование этого столбца дает странные результаты.

I думаю, что это ошибка, вместо этого неправильный вывод должен вызвать ошибку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...