Python Pandas:dataframe.loc 返回 "KeyError: label not in [index]" ,但 dataframe.index 显示它是



我正在使用Python中的pandas工具包,但我遇到了一个问题。

我有一个值列表,lst,为了方便起见,假设它只有前 20 个自然数:

>>> lst = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

然后我创建一个DataFrame,通过给它一个带有该列表的Series,如下所示:

>>> df = DataFrame(Series(lst))

我想用它来计算从0.1(10%( 到1(100%( 的分位数,我使用 DataFrame 中的quantile函数来做到这一点:

>>> quantiles = df.quantile(np.linspace(.1,1,num=10,endpoint=True))

如果我打印quantiles,则会出现这种情况:

0
0.1   2.9
0.2   4.8
0.3   6.7
0.4   8.6
0.5  10.5
0.6  12.4
0.7  14.3
0.8  16.2
0.9  18.1
1.0  20.0

现在,我想将分位数0.3 和 0.7的值存储在一个变量中,在搜索了如何做到这一点之后,我想出了一个在DataFrame中使用loc的解决方案,给它分位数标签(例如0.7(和我想考虑的一系列值的列索引。由于只有一个,我这样做:

>>> q_3 = qts.loc[0.7][0]

问题是python给了我这个错误:

**KeyError: 'the label [0.7] is not in the [index]'**

但我知道它存在,因为如果我尝试打印index值,我会得到这个:

>>> qts.index
Float64Index([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0], dtype='float64')

所以,索引显然存在,但我说它不存在。 我做错了什么?

如果我尝试使用这种方法打印任何其他分位数值,而不是0.30.7,它可以工作:

>>> qts.loc[0.1][0]
2.8999999999999999
>>> qts.loc[0.2][0]
4.8000000000000007
>>> qts.loc[0.4][0]
8.6000000000000014
>>> qts.loc[0.5][0]
10.5
>>> qts.loc[0.6][0]
12.4
>>> qts.loc[0.8][0]
16.200000000000003
>>> qts.loc[0.9][0]
18.100000000000001
>>> qts.loc[1][0]
20.0

有什么想法吗?

我使用的是Python 3.5和pandas 0.20.3。

编辑感谢您的反馈! 所以,这是一个浮点精度问题。尽管如此,我想知道:有没有更好的方法来获取分位数列表中的第 N 个元素,而不是像我一样使用loc

这里的索引值并不完全等于 0.7;对于非常小的精度,存在差异。您可以通过运行以下命令来确认这一点:

assert qts.index[6] == 0.7

print(qts.index[6] - 0.7)

如果先使用numpy.round舍入索引,您将能够根据需要通过qts.loc[0.7, 0]访问元素:

import numpy as np
qts.index = np.round(qts.index, decimals=1)

正如其他人提到的,这是精度问题。为了在索引中找到所需的浮点数,您可能需要使用np.isclose

>> quantiles.loc[np.isclose(quantiles.index, 0.3), 0]
0.3    6.7              
Name: 0, dtype: float64
>> quantiles.loc[np.isclose(quantiles.index, 0.7), 0]
0.7    14.3
Name: 0, dtype: float64

您是浮点精度错误的受害者(某些浮点值根本无法以有限的二进制形式表示,请参阅浮点数学是否损坏?(。

虽然qts.index确实输出
Float64Index([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0], dtype='float64')

看看接下来会发生什么:

>>>for i in qts.index: 
print(repr(i))  
0.10000000000000001     
0.20000000000000001     
0.30000000000000004     
0.40000000000000002     
0.5                     
0.59999999999999998     
0.70000000000000007     
0.80000000000000004     
0.90000000000000002     
1.0 

这仍然不能解释为什么qts.loc[0.4][0]有效而qts.loc[0.7][0]不起作用(一种可能的解释可能是.loc确实在浮点索引的情况下实现了某种公差,即如果错误不是太大,它将"允许"访问所需的索引(,但qts.loc[0.70000000000000007][0]有效:

>>> qts.loc[0.70000000000000007][0]
14.299999999999999

最新更新