【问题标题】:pd.NamedAgg overwrites previous columns valuespd.NamedAgg 覆盖以前的列值
【发布时间】:2020-09-12 20:36:39
【问题描述】:

这是我使用的数据框。

      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

在尝试解决this question 时,我遇到了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

在特定列上执行此操作时

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.lt(0).sum()))
#Output
      pos  neg
name
abc   2.0  2.0
xyz   2.0  2.0

pos 列值被neg 列值覆盖。

下面的另一个例子:

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()))
#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

我的熊猫版

pd.__version__
# '1.0.3'

来自熊猫文档:

命名聚合也适用于 Series groupby 聚合。在这种情况下,没有列选择,因此值只是函数。

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 一起使用会产生奇怪的结果。

更新:

错误报告由@jezraelgithub issue #34380here too. 中提交

编辑:这是 pandas-dev 确认的错误,已在 PR BUG: aggregations were getting overwritten if they had the same name #30858

中解决

【问题讨论】:

    标签: python pandas dataframe aggregation


    【解决方案1】:

    如果groupby后有指定列,使用paragraph中指定的解决方案:

    命名聚合也适用于 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
    

    为什么将它与列一起使用会产生奇怪的结果。

    我认为这是错误,而不是错误的输出应该引发错误。

    【讨论】:

    • 感谢您的回答。但我不明白为什么使用 with pd.NamedAgg 会导致这种奇怪的行为。
    • @Ch3steR - 我认为这是错误的使用,正确的是应该引发错误。
    • 是的,如果它不打算以这种方式工作,它应该会引发错误。可能在 GitHub 上报告它可能会有所帮助。
    • @Ch3steR - 是的,给我一些时间。
    • 是的,我会等你和其他人给出答案。否则我们可以一起在 GitHub 中打开一个问题。
    猜你喜欢
    • 1970-01-01
    • 2016-11-14
    • 1970-01-01
    • 2019-05-09
    • 2016-04-30
    • 2012-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多