【问题标题】:Python pandas unique value ignoring NaNPython pandas 忽略 NaN 的唯一值
【发布时间】:2022-04-05 09:44:42
【问题描述】:

我想在groupby 聚合中使用unique,但我不想在unique 结果中使用nan

一个示例数据框:

df = pd.DataFrame({'a': [1, 2, 1, 1, np.nan, 3, 3], 'b': [0,0,1,1,1,1,1],
    'c': ['foo', np.nan, 'bar', 'foo', 'baz', 'foo', 'bar']})

       a  b    c
0 1.0000  0  foo
1 2.0000  0  NaN
2 1.0000  1  bar
3 1.0000  1  foo
4    nan  1  baz
5 3.0000  1  foo
6 3.0000  1  bar

还有groupby

df.groupby('b').agg({'a': ['min', 'max', 'unique'], 'c': ['first', 'last', 'unique']})

它的结果是:

       a                             c                      
     min    max           unique first last           unique
b                                                           
0 1.0000 2.0000       [1.0, 2.0]   foo  foo       [foo, nan]
1 1.0000 3.0000  [1.0, nan, 3.0]   bar  bar  [bar, foo, baz]

但我想要没有nan:

       a                        c                      
     min    max      unique first last           unique
b                                                           
0 1.0000 2.0000  [1.0, 2.0]   foo  foo            [foo]
1 1.0000 3.0000  [1.0, 3.0]   bar  bar  [bar, foo, baz]

我该怎么做?当然,我有几列要聚合,每列需要不同的聚合函数,所以我不想将unique 聚合与其他聚合一个接一个地分开。

【问题讨论】:

    标签: python pandas group-by null unique


    【解决方案1】:

    定义一个函数:

    def unique_non_null(s):
        return s.dropna().unique()
    

    然后在聚合中使用:

    df.groupby('b').agg({
        'a': ['min', 'max', unique_non_null], 
        'c': ['first', 'last', unique_non_null]
    })
    

    【讨论】:

      【解决方案2】:

      这将满足您的需求:

      df.fillna(method='ffill').groupby('b').agg({'a': ['min', 'max', 'unique'], 'c': ['first', 'last', 'unique']})
      

      因为您使用minmaxunique 重复值与您无关。

      【讨论】:

      • 还有df.ffill()..
      • @Bharathshetty 公平地说,我看到 zipa 的答案首先出现。有时答案出现的时间有点随机。
      • @Bharathshetty 没看到,但现在我看到了,你给自己加了一个 +1 :)
      【解决方案3】:

      2020 年 11 月 23 日更新

      这个答案很糟糕,不要用这个。请参考@IanS 的回答。

      之前

      试试ffill

      df.ffill().groupby('b').agg({'a': ['min', 'max', 'unique'], 'c': ['first', 'last', 'unique']})
      
      一个 第一 最后 唯一 最小 最大 唯一 b 0 富富 [富] 1.0 2.0 [1.0, 2.0] 1 bar bar [bar, foo, baz] 1.0 3.0 [1.0, 3.0]

      如果 Nan 是该组的第一个元素,则上述解决方案将中断。

      【讨论】:

      • 谢谢大家,我认为Bharath shetty 有最简单和pythonic 的解决方案。再次感谢!!
      • 这是一个糟糕的解决方案。这是完全错误的。它仅适用于本示例,因为 NaN 上方的值恰好在该组中。
      • @Bharath 我认为这实际上是一个很好的解决方案。它可能不是最优雅或最 Python 的,但我怀疑它比其他选项更快。
      • @ragesz 请接受 IanS 的回答,因为它涵盖了所有边缘情况。这个答案在很多情况下并不适用。
      【解决方案4】:

      你可以使用下面的代码,

          df.apply(lambda x: len(x.dropna().unique()))
      

      【讨论】:

      • 此评论实际上并没有回答问题 =/ 它专门在 groupby 上下文中
      猜你喜欢
      • 2014-11-26
      • 1970-01-01
      • 2019-06-03
      • 2016-01-14
      • 2019-07-24
      • 2018-07-05
      • 2016-10-17
      • 2023-04-09
      • 2019-09-24
      相关资源
      最近更新 更多