从常规索引切换到多重索引后,我的一个函数出现问题,我不知道如何解决这个问题。让我从 pandas 文档中获取 pandas.DataFrame.at 的 DataFrame 来说明问题:
>>> df = pd.DataFrame([[0, 2, 3], [0, 4, 1], [10, 20, 30]],
... index=[4, 5, 6], columns=['A', 'B', 'C'])
>>> df
A B C
4 0 2 3
5 0 4 1
6 10 20 30
>>> df.at[4, 'B']
2
如果您现在将其转换为 MultiIndex,相同的调用将失败并引发 KeyError:
>>> df = df.set_index("A", append=True)
>>> df
B C
A
4 0 2 3
5 0 4 1
6 10 20 30
>>> df.at[4, 'B']
Traceback (most recent call last):
File "<input>", line 1, in <module>
df.at[4, "B"]
~~~~~^^^^^^^^
File "/.../pandas/core/indexing.py", line 2419, in __getitem__
return super().__getitem__(key)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../pandas/core/indexing.py", line 2371, in __getitem__
return self.obj._get_value(*key, takeable=self._takeable)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../pandas/core/frame.py", line 3882, in _get_value
loc = engine.get_loc(index)
^^^^^^^^^^^^^^^^^^^^^
File "pandas/_libs/index.pyx", line 822, in pandas._libs.index.BaseMultiIndexCodesEn
gine.get_loc
KeyError: 4
如果 loc 的行为方式相同,那么这种行为就很好 - 但事实并非如此:
>>> df.loc[4, 'B']
A
0 2
Name: B, dtype: int64
当然,您可以通过指定索引的所有级别来解决这个问题......
df.at[(4,0), 'B']
2
但考虑到我有相当多的多索引级别,这似乎不是一个可行的解决方案。使用 loc 然后附加 .iloc[0] 也感觉不太Pythonic...... 有谁知道如何在不指定超过第一级的情况下使 .at 工作?