Pandas DataFrame,其字符串元组为索引

时间:2016-10-21 22:37:25

标签: python pandas indexing

我在这里感觉到一些奇怪的pandas行为。我的数据框看起来像

df = pd.DataFrame(columns=['Col 1', 'Col 2', 'Col 3'],
                  index=[('1', 'a'), ('2', 'a'), ('1', 'b'), ('2', 'b')])

In [14]: df
Out[14]:
       Col 1 Col 2 Col 3
(1, a)   NaN   NaN   NaN
(2, a)   NaN   NaN   NaN
(1, b)   NaN   NaN   NaN
(2, b)   NaN   NaN   NaN

我可以设置任意元素的值

In [15]: df['Col 2'].loc[('1', 'b')] = 6

In [16]: df
Out[16]:
       Col 1 Col 2 Col 3
(1, a)   NaN   NaN   NaN
(2, a)   NaN   NaN   NaN
(1, b)   NaN     6   NaN
(2, b)   NaN   NaN   NaN

但是当我使用相同的语法引用我刚设置的元素时,我得到了

In [17]: df['Col 2'].loc[('1', 'b')]
KeyError: 'the label [1] is not in the [index]'

有人可以告诉我我做错了什么或为什么会出现这种情况?我根本不允许将索引设置为多元素元组吗?

修改

显然,将元组索引包装在列表中会起作用。

In [38]: df['Col 2'].loc[[('1', 'b')]]
Out[38]:
(1, b)    6
Name: Col 2, dtype: object

虽然我在实际使用案例中仍然有一些奇怪的行为,所以很高兴知道这不是推荐用法。

1 个答案:

答案 0 :(得分:6)

选择括号中的元组被视为包含要检索的元素的序列。这就像你将['1', 'b']作为参数传递一样。因此KeyError消息:pandas试图找到键'1',但显然找不到它。

这就是为什么它在你添加额外的括号时起作用,因为现在参数变成了一个元素的序列 - 你的元组。

你应该避免在选择中处理列表和元组参数的歧义。行为也可能不同,具体取决于索引是简单索引还是多索引。

在任何情况下,如果你在这里询问建议,我看到的是你应该尝试不构建由元组构成的简单索引:如果你实际构建一个多索引,pandas会更好用,并且会更强大:

df = pd.DataFrame(columns=['Col 1', 'Col 2', 'Col 3'],
                  index=pd.MultiIndex.from_tuples([('1', 'a'), ('2', 'a'), ('1', 'b'), ('2', 'b')]))

df['Col 2'].loc[('1', 'b')] = 6

df['Col 2'].loc[('1', 'b')]
Out[13]: 6

df
Out[14]: 
    Col 1 Col 2 Col 3
1 a   NaN   NaN   NaN
2 a   NaN   NaN   NaN
1 b   NaN     6   NaN
2 b   NaN   NaN   NaN