Python Pandas:dataframe.loc返回" KeyError:标签不在[index]"中,但dataframe.index显示它是

时间:2017-07-12 20:16:16

标签: python pandas statistics

我在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%)的分位数,我使用{{1}来做来自DataFrame的函数:

quantile

如果我打印>>> quantiles = df.quantile(np.linspace(.1,1,num=10,endpoint=True)) ,则显示以下内容:

quantiles

现在,我想在变量中存储分位数 0.3 0.7 的值,在搜索完成后,我想出了一个使用{的解决方案{1}}中的{1}},为其提供分位数标签(例如 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 )以及我要考虑的一系列值的列索引。由于只有一个,我这样做:

loc

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

DataFrame

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

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

所以,该指数显然存在,但我说它并不存在。 我做错了什么?

如果我尝试使用此方法打印任何其他分位数值,而不是**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')

有什么想法吗?

我使用的是Python 3.5,而pandas是0.20.3。

修改 感谢您的反馈! 因此,它是一个浮点精度问题。不过,我想知道:有没有更好的方法来获取分位数列表中的 N' 元素,而不是像我一样使用0.3

3 个答案:

答案 0 :(得分:3)

此处的索引值 <0>以非常小的精度存在差异。您可以通过运行确认:

Gstreamer

assert qts.index[6] == 0.7

如果您首先使用print(qts.index[6] - 0.7) 对索引进行舍入,则可以根据需要通过numpy.round访问该元素:

qts.loc[0.7, 0]

答案 1 :(得分:1)

您是浮点精度误差的受害者(某些浮点值无法以有限二进制形式表示,请参阅Is floating point math broken?)。

虽然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在浮点索引的情况下实现某种容差,即如果错误不太大,它将“允许&#34;访问所需的索引”,但qts.loc[0.70000000000000007][0]有效:

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

答案 2 :(得分: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