带有多索引的 df.at 与 df.loc

Posted

技术标签:

【中文标题】带有多索引的 df.at 与 df.loc【英文标题】:df.at with multiindex vs df.loc 【发布时间】:2018-09-22 20:37:46 【问题描述】:

我有一个关于 df.locdf.at 在具有 MultiIndex 的数据帧方面的区别的问题。我一直在查看来自 *** 的一些精彩资源,但它似乎并没有说明我的问题。特别是这个...pandas .at versus .loc(或者至少我不完全理解这里显示的内容)。

根据 pandas 文档,https://pandas-docs.github.io/pandas-docs-travis/generated/pandas.DataFrame.at.htmldf.at 应该返回奇异值,并且它比df.loc 快,所以我倾向于使用df.at。让我展示一下我的困惑,因为它适用于将 df.at 与 MultiIndex 一起使用。

我有以下数据框:

df = pd.DataFrame('field1':['foo']*6, 'field2':['bar']*6, 'field3': 
['a','a','b','b','b','c'],'value1':[0.4,0.5,0.4,0.7,.9,.4],'value2': 
[4000,4000,9000,9000,9000,10000], index=range(6))

df
Out[329]: 
  field1 field2 field3  value1  value2
0    foo    bar      a     0.4    4000
1    foo    bar      a     0.5    4000
2    foo    bar      b     0.4    9000
3    foo    bar      b     0.7    9000
4    foo    bar      b     0.9    9000
5    foo    bar      c     0.4   10000

我想使用 MultiIndex 访问这个数据框,所以我正在执行以下操作:

df = df.set_index(['field1','field2','field3'])

所以现在我想通过('foo','bar','c') 访问我的df 中的value1,这是一个奇异值,它会出错。

df.at[('foo','bar','c'),'value1']
Traceback (most recent call last):

  File "<ipython-input-344-921b8b658a49>", line 1, in <module>
    df.at[('foo','bar','c'),'value1']

  File "C:\Anaconda2\lib\site-packages\pandas\core\indexing.py", line 1610, 
in __getitem__
    return self.obj.get_value(*key, takeable=self._takeable)

  File "C:\Anaconda2\lib\site-packages\pandas\core\frame.py", line 1836, in 
get_value
    return engine.get_value(series.get_values(), index)

  File "pandas\index.pyx", line 103, in pandas.index.IndexEngine.get_value 
(pandas\index.c:3234)

  File "pandas\index.pyx", line 111, in pandas.index.IndexEngine.get_value 
(pandas\index.c:2931)

  File "pandas\index.pyx", line 152, in pandas.index.IndexEngine.get_loc 
(pandas\index.c:3830)

  File "pandas\index.pyx", line 170, in 
pandas.index.IndexEngine._get_loc_duplicates (pandas\index.c:4154)

TypeError: only integer arrays with one element can be converted to an index

我假设这是返回一个系列对象,它不能表示为单个值?鉴于df.loc 的输出,这只是我的假设。

df.loc[('foo','bar','c')]['value1']
 Out[345]: 
field1  field2  field3
foo     bar     c         0.4
Name: value1, dtype: float64

现在,如果我没有使用 MultiIndex,我认为不会出现此问题...

无论如何,这是否存在,或者我显然遗漏了什么?谢谢

【问题讨论】:

赞成,这是一个写得很好的问题。 我无法用 Pandas 0.22 重现这个。有趣的是,df.at[('foo', 'bar', 'a'), 'value1'] 返回array([ 0.4, 0.5]) 嗯。我正在使用 pandas 0.18,也许这已经修复了? 秒数不能在 0.22 内重复。 【参考方案1】:

你可以试试这样的:

# setting multiindex
df = df.set_index(['field1','field2','field3'])

现在当你像这样使用df.atdf.at[('foo','bar','c')]['value1'],你会得到想要的结果:

field1  field2  field3
foo     bar     c         0.4
Name: value1, dtype: float64

根据我的尝试,您可能没有正确使用 at 查询数据框。

【讨论】:

以上是关于带有多索引的 df.at 与 df.loc的主要内容,如果未能解决你的问题,请参考以下文章

在多索引中创建新列

Pandas选取行,列总结

为啥我在多索引的索引中有空项目

pandas一些常用函数以及操作的使用和理解(持续更新)

如何更改熊猫数据框中多索引的外层索引?

如何在不合并索引的情况下连接具有不同多索引的两个数据帧?