【问题标题】:Unique values from pandas.Series [duplicate]pandas.Series 中的唯一值 [重复]
【发布时间】:2018-05-31 20:57:56
【问题描述】:

考虑以下pandas.Series

import pandas as pd
import numpy as np
s = pd.Series([np.nan, 1, 1, np.nan])

s
0    NaN
1    1.0
2    1.0
3    NaN
dtype: float64

我想使用内置的set 函数仅查找此特定系列中的唯一值:

unqs = set(s)

unqs
{nan, 1.0, nan}

为什么结果集中有重复的NaNs?使用类似的函数 (pandas.unique) 不会产生这个结果,那么这里有什么区别呢?

pd.unique(s)
array([ nan,   1.])

【问题讨论】:

  • 因为在 Python 中 math.nan != math.nan。这是对等式关系应该具有的 reflexivity 契约的违反之一,但这里有充分的理由这样做。
  • 这有什么特别的设计原因吗?这种比较的结果是不直观的。
  • 不仅不直观,甚至违反了自反性约束。原因是比如math.nan + 2也是math.nan,但是你能说x + 2 == x吗?
  • 请在使用 pandas 时使用s.unique()s.value_counts()
  • 我认为这个问题之前已经以各种形式得到了解答(例如herehere)。基本上,Python 在迭代系列时会创建新的 NaN 对象(就像您指出的那样),并且 Python 首先通过 id 测试相等的对象,然后再回退到==

标签: python pandas numpy


【解决方案1】:

就像在JavaJavaScript 中一样,numpy 中的nan 不等于自身。

>>> np.nan == np.nan
False

这意味着当set 构造函数检查“我在这个集合中有nan 的实例吗?”它总是返回 False

那么……为什么?

nan 在这两种情况下都表示“不能用'float'表示的值”。这意味着将其转换为浮点数的尝试必然会失败。它也无法排序,因为无法判断nan 是否应该大于或小于任何数字。

毕竟,“猫”和 7 哪个更大?并且是“goofy”==“pluto”吗?

那么……我该怎么办?

有几种方法可以解决此问题。就我个人而言,我通常会尝试在处理之前填充 nan:DataFrame.fillna 会对此有所帮助,并且我总是会使用 df.unique() 来获取一组唯一值。

no_nas = s.dropna().unique()
with_nas = s.unique()
with_replaced_nas = s.fillna(-1).unique() # using a placeholder

(注意:以上都可以传入set构造函数。

如果我不想使用 Pandas 方式怎么办?

有理由不使用 Pandas,或者依赖原生对象而不是 Pandas。这些应该就足够了。

您的另一个选择是过滤并删除nan

unqs = set(item for item in s if not np.isnan(item))

你也可以替换内联的东西:

placeholder = '{placeholder}' # There are a variety of placeholder options.
unqs = set(item if not np.isnan(item) else placeholder for item in s)

【讨论】:

  • "SO... what do I do?" 不,您确实应该使用专门用于此类事情的 pandas 函数。例如,s.dropna().unique(),或s.value_counts().index,等等。
  • 完全同意。添加了普遍首选的 Pandas 方法,但由于我不知道 OP 的原始需求,所以我添加了一个额外的部分。
  • 现在看起来好多了:-)
猜你喜欢
  • 1970-01-01
  • 2017-01-13
  • 1970-01-01
  • 2012-11-06
  • 2018-09-23
  • 2022-01-17
  • 1970-01-01
  • 1970-01-01
  • 2013-10-12
相关资源
最近更新 更多