来自pandas.Series的独特价值

时间:2017-12-18 13:41:54

标签: python pandas numpy

考虑以下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}

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

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

1 个答案:

答案 0 :(得分:3)

JavaJavaScript一样,numpy中的nan不等于自己。

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

这意味着当set构造函数检查"我在此集合中是否有nan的实例?"它alwasy返回 False

那么......为什么?

在这两种情况下,

nan表示"值不能由' float'"表示。这意味着将其转换为float的尝试必然会失败。它也无法排序,因为无法判断nan是否应该大于或小于任何数字。

毕竟,哪个更大" cat"还是7?是"高飞" =="冥王星"?

所以...我该怎么办?

有几种方法可以解决此问题。就个人而言,我通常会在处理之前尝试填充 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)