【问题标题】:How to use pandas .at function for Series with multiindex如何对具有多索引的系列使用 pandas .at 函数
【发布时间】:2019-09-26 02:16:25
【问题描述】:

我正在使用 iterrows 遍历具有多索引的大型数据框。结果是具有多索引的系列。经过一些分析,结果发现大部分时间都花在了获取系列的单元格值上,所以我想使用 Series.at 函数,因为它更快。 不幸的是,我在 pandas 文档中没有找到关于 multiindex 的任何内容。

这是一个简单的代码:

import numpy as np
import pandas as pd

arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'], ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])

s = pd.Series(np.random.randn(8), index=index)
>>>>s
first  second
bar    one      -0.761968
       two       0.670786
baz    one      -0.193843
       two      -0.251533
foo    one       1.732875
       two       0.538561
qux    one      -1.111480
       two       0.478322
dtype: float64

我尝试过 s.at[("bar","one")] , s.at["bar","one"],但这些都不起作用。

>>>>s.at[("bar","one")]
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "C:\Python\lib\site-packages\pandas\core\indexing.py", line 2270, in __getitem__
    return self.obj._get_value(*key, takeable=self._takeable)
TypeError: _get_value() got multiple values for argument 'takeable'
>>>>s.at["bar","one"]
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "C:\Python\lib\site-packages\pandas\core\indexing.py", line 2270, in __getitem__
    return self.obj._get_value(*key, takeable=self._takeable)
TypeError: _get_value() got multiple values for argument 'takeable'

有人知道在这种情况下如何使用 .at 吗?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    使用Series.loc:

    print (s.loc[("bar","one")])
    1.265936258705534
    

    编辑:

    好像是bug。

    如果使用 DataFrame 它工作得很好:

    np.random.seed(1234)
    arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'], ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
    tuples = list(zip(*arrays))
    index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
    

    s = pd.Series(np.random.randn(8), index=index)
    print (s)
    first  second
    bar    one       0.471435
           two      -1.190976
    baz    one       1.432707
           two      -0.312652
    foo    one      -0.720589
           two       0.887163
    qux    one       0.859588
           two      -0.636524
    dtype: float64
    
    df = s.to_frame('col')
    print (df)
                       col
    first second          
    bar   one     0.471435
          two    -1.190976
    baz   one     1.432707
          two    -0.312652
    foo   one    -0.720589
          two     0.887163
    qux   one     0.859588
          two    -0.636524
    
    print (df.at[("bar","one"), 'col'])
    0.47143516373249306
    

    【讨论】:

    • @RLaszlo - 可以使用 DataFrame 吗?如果是,请检查已编辑的答案。
    • 我取得了巨大的进步。我没有使用 iterrows 并试图强制 .at 从系列中获取数据,而是仅遍历整个 Dataframe 的索引,并使用 .at。使用数据框进行多索引非常有效。谢谢@jezrael
    • 除了上面的答案,你还可以在 Series 上使用 IndexSllce 和 loc。 ___ idx = pd.IndexSlice __ s.loc[idx['bar','one']] __ s.loc[idx[['bar','foo'],['one','two]']] ]
    • 2019-05-08 编辑补充说这是一个错误。看起来 github.com/pandas-dev/pandas/issues/26989 有一个修复 github.com/pandas-dev/pandas/pull/32520 已于 2020 年 5 月合并。
    猜你喜欢
    • 2020-08-18
    • 2021-07-13
    • 1970-01-01
    • 1970-01-01
    • 2018-04-19
    • 1970-01-01
    • 2020-07-18
    • 1970-01-01
    • 2013-06-30
    相关资源
    最近更新 更多