pandas IndexError/TypeError 与 NaN 值不一致
pandas IndexError/TypeError inconsistency with NaN values
我有几个系列的可变长度列表,其中有一些空值。一个例子是:
In [108]: s0 = pd.Series([['a', 'b'],['c'],np.nan])
In [109]: s0
Out[109]:
0 [a, b]
1 [c]
2 NaN
dtype: object
但另一个包含所有 NaNs
:
In [110]: s1 = pd.Series([np.nan,np.nan])
In [111]: s1
Out[111]:
0 NaN
1 NaN
dtype: float64
我需要每个列表中的最后一项,这很简单:
In [112]: s0.map(lambda x: x[-1] if isinstance(x,list) else x)
Out[112]:
0 b
1 c
2 NaN
dtype: object
但是在谈到这一点时我发现,如果没有 isinstance
,当 NaNs
上的索引阻塞时,它在 s0
和 s1
:
In [113]: s0.map(lambda x: x[-1])
...
TypeError: 'float' object is not subscriptable
In [114]: s1.map(lamda x: x[-1])
...
IndexError: invalid index to scalar variable.
谁能解释一下为什么?这是一个错误吗?我正在使用 Pandas 0.16.2 和 Python 3.4.3.
从本质上讲,这实际上是一个 NumPy 问题,而不是 pandas 问题。
map
遍历列中的值,一次将它们传递给 lambda
函数。在下面,pandas 中的 columns/Series 只是 NumPy 数组的(切片),因此 pandas 定义了以下 helper function 以从函数的基础数组中获取值。这是由 map
在每次迭代中调用的:
PANDAS_INLINE PyObject*
get_value_1d(PyArrayObject* ap, Py_ssize_t i) {
char *item = (char *) PyArray_DATA(ap) + i * PyArray_STRIDE(ap, 0);
return PyArray_Scalar(item, PyArray_DESCR(ap), (PyObject*) ap);
}
关键位是 PyArray_Scalar
,这是一个 NumPy API 函数,它将 NumPy 数组的一部分复制到 return 标量值。
构成函数的代码太长post这里,但是here's在代码库中哪里可以找到它。我们需要知道的是它 returns 的标量将匹配它所使用的数组的数据类型。
返回您的系列:s0
具有 object
dtype,而 s1
具有 float64
dtype。这意味着 PyArray_Scalar
将为每个系列 return 不同类型的标量;一个实际的 Python float
对象和一个 NumPy 标量浮点对象分别为:
>>> type(s0[2])
float
>>> type(s1[0])
numpy.float64
NaN
值被 return 编辑为两种不同的类型,因此当您尝试使用 lambda
函数对它们进行索引时会出现不同的错误。
我有几个系列的可变长度列表,其中有一些空值。一个例子是:
In [108]: s0 = pd.Series([['a', 'b'],['c'],np.nan])
In [109]: s0
Out[109]:
0 [a, b]
1 [c]
2 NaN
dtype: object
但另一个包含所有 NaNs
:
In [110]: s1 = pd.Series([np.nan,np.nan])
In [111]: s1
Out[111]:
0 NaN
1 NaN
dtype: float64
我需要每个列表中的最后一项,这很简单:
In [112]: s0.map(lambda x: x[-1] if isinstance(x,list) else x)
Out[112]:
0 b
1 c
2 NaN
dtype: object
但是在谈到这一点时我发现,如果没有 isinstance
,当 NaNs
上的索引阻塞时,它在 s0
和 s1
:
In [113]: s0.map(lambda x: x[-1])
...
TypeError: 'float' object is not subscriptable
In [114]: s1.map(lamda x: x[-1])
...
IndexError: invalid index to scalar variable.
谁能解释一下为什么?这是一个错误吗?我正在使用 Pandas 0.16.2 和 Python 3.4.3.
从本质上讲,这实际上是一个 NumPy 问题,而不是 pandas 问题。
map
遍历列中的值,一次将它们传递给 lambda
函数。在下面,pandas 中的 columns/Series 只是 NumPy 数组的(切片),因此 pandas 定义了以下 helper function 以从函数的基础数组中获取值。这是由 map
在每次迭代中调用的:
PANDAS_INLINE PyObject*
get_value_1d(PyArrayObject* ap, Py_ssize_t i) {
char *item = (char *) PyArray_DATA(ap) + i * PyArray_STRIDE(ap, 0);
return PyArray_Scalar(item, PyArray_DESCR(ap), (PyObject*) ap);
}
关键位是 PyArray_Scalar
,这是一个 NumPy API 函数,它将 NumPy 数组的一部分复制到 return 标量值。
构成函数的代码太长post这里,但是here's在代码库中哪里可以找到它。我们需要知道的是它 returns 的标量将匹配它所使用的数组的数据类型。
返回您的系列:s0
具有 object
dtype,而 s1
具有 float64
dtype。这意味着 PyArray_Scalar
将为每个系列 return 不同类型的标量;一个实际的 Python float
对象和一个 NumPy 标量浮点对象分别为:
>>> type(s0[2])
float
>>> type(s1[0])
numpy.float64
NaN
值被 return 编辑为两种不同的类型,因此当您尝试使用 lambda
函数对它们进行索引时会出现不同的错误。