python - 从数据帧/系列中提取时缺失值的奇怪行为

标签 python python-2.7 pandas nan

在使用 pandas 时,我遇到了一些非常奇怪的缺失值行为,这让我很害怕。

请遵守以下规定:

import pandas as pd
import numpy as np
from numpy import nan as NA
from pandas import DataFame

In [1]: L1 = [NA, NA]
In [2]: L1
Out[2]: [nan, nan]
In [3]: set(L1)
Out[3]: {nan}

到目前为止一切都很好,正如预期的那样,列表 L1 的集合包含单个 NA 值。但现在我对当你做完全相同的事情但基于从数据框系列中提取的列表时会发生的事情感到非常困惑

In [4]: EG = DataFrame(np.random.rand(10), columns = ['Data'])
In [5]: EG['Data'][5:7] = NA
In [6]: L2 = list(EG['Data'][5:7])
In [7]: L2
Out[8]: [nan, nan]
In [9]: set(L2)
Out[9]: {nan, nan}

这里发生了什么?当它们所基于的列表看起来完全相同时,为什么这些集合会不同?

我做了一些挖掘,认为类型可能不同(这似乎令人惊讶,因为 NA 值的创建方式在我看来完全相同)。请参阅以下内容:

In [10]: type(L1[0])
Out[10]: float
In [11]: type(L1[1])
Out[11]: float
In [12]: type(L2[0])
Out[12]: numpy.float64
In [13]: type(L2[1])
Out[13]: numpy.float64

很明显,类型是不同的,这已经让我大吃一惊,但是如果我将 L2 的每个元素转换为 float ,就像 L1 中的那样,奇怪的集合行为应该消失:

In [14]: L3 = [float(elem) for elem in L2]
In [15]: L3
Out[15]: [nan, nan]
In [16]: type(L3[0])
Out[16]: float
In [17]: type(L3[1])
Out[17]: float 
In [18]: set(L3)
Out[18]: {nan, nan}

即使 L3 中的元素类型与 L1 中的元素类型完全相同,问题仍然存在。

有人可以帮忙吗?

使用 groupby 聚合数据时,我依赖于 set(L) 的常规功能。我注意到这个问题,它让我发疯。我有兴趣了解解决方法,但我更想知道这里到底发生了什么......

请帮忙...

编辑:为了响应用户评论,我发布了我实际上正在尝试聚合数据的代码。我不确定这会改变问题的严重程度,但它可能有助于理解为什么它如此令人沮丧:

def NoActionRequired(x):
""" This function is used to aggregate the data that is believed to be equal within multi line/day groups. It puts the data 
    into a list and then if that list forms a set of length 1 (which it must if the data are in fact equal) then the single
    value contained in the set is returned, otherwise the list is returned. This allows for the fact that we may be wrong about
    the equality of the data, and it is something that can be tested after aggreagation."""

    L = list(x)
    S = set(L)
    if len(S) == 1:
        return S.pop()
    else:
        return L

DFGrouped['Data'].agg(NoActionRequired)

其想法是,如果组中的所有数据都相同,则返回单个值,否则返回数据列表。

最佳答案

我现在看到的唯一解释是第一个列表中的所有 NA 都是相同的对象:

>>> L1 = [NA, NA]
>>> L1
[nan, nan]
>>> L1[0] is L1[1]
True

虽然第二个列表中的对象是不同的对象:

>>> L2 = list(pd.Series([NA, NA]))
>>> L2
[nan, nan]
>>> L2[0] is L2[1]
False

关于你的功能,我建议使用 pandas.Series.unique()而不是设置,类似:

def NoActionRequired(x):
    # ...    
    S = x.unique()
    if len(S) == 1:
        return S[0]
    else:
        return list(x)

看起来 unique()NaN 配合得很好:

>>> pd.Series([NA, NA]).unique()
array([ nan])

编辑检查 NA 是否在列表中,可以使用 np.isnan() 函数:

>>> L = [NA, 1, 2]
>>> np.isnan(L)
array([ True, False, False], dtype=bool)

关于python - 从数据帧/系列中提取时缺失值的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19783446/

相关文章:

python - 将 Pandas DataFrame 转换为多维 ndarray

python pandas 如何从数据框中删除异常值并替换为前面记录的平均值

python - 岭回归中的参数Alpha是什么?

python - 沿 NumPy 数组的轴计算唯一元素

python - 如何在命令终端中使用 python 处理远程文件

python - 在 tkinter 中使用选项菜单小部件时出错

python - Django 表单 ChoiceField 依赖于另一个 ChoiceField

python 和 kafka KeyError : -1

python-2.7 - 当我尝试安装Canopy时,为什么opencv会降级numpy,scipy和其他软件包?

python - 访问列表中第一个元素以外的元素不起作用