【问题标题】:Selecting values with Pandas multiindex using lists of tuples使用元组列表使用 Pandas 多索引选择值
【发布时间】:2019-11-30 11:40:31
【问题描述】:

我有一个带有 3 个级别的 MultiIndex 的 DataFrame:

id    foo  bar    col1
0     1    a -0.225873
      2    a -0.275865
      2    b -1.324766
3     1    a -0.607122
      2    a -1.465992
      2    b -1.582276
      3    b -0.718533
7     1    a -1.904252
      2    a  0.588496
      2    b -1.057599
      3    a  0.388754
      3    b -0.940285

保留 id 索引级别,我想沿 foo 和 bar 级别求和,但每个 id 具有不同的值。

例如,对于 id = 0 我想对 foo = [1] 和 bar = [["a", "b"]] 求和,对于 id = 3 我想对 foo = [2] 和bar = [["a", "b"]],对于 id = 7,我想对 foo = [[1,2]] 和 bar = [["a"]] 求和。给出结果:

id    col1
0     -0.225873    
3     -3.048268   
7     -1.315756

我一直在尝试这些方面的东西:

df.loc(axis = 0)[[(0, 1, ["a","b"]), (3, 2, ["a","b"]), (7, [1,2], "a")].sum()

不确定这是否可能。任何优雅的解决方案(可能删除 MultiIndex?)将不胜感激!

【问题讨论】:

    标签: pandas pandas-groupby


    【解决方案1】:

    使用slicers 的更简洁的解决方案:

    sections = [(0, 1, slice(None)), (3, 2, slice(None)), (7, slice(1,2), "a")]
    pd.concat(df.loc[s] for s in sections).groupby("id").sum()
    
            col1
    id          
    0  -0.225873
    3  -3.048268
    7  -1.315756
    

    需要注意的两点:

    1. 由于pd.concat 创建了一个新的DataFrame,这可能比公认的答案更节省内存。
    2. slice(None) 是强制性的,否则调用pd.concatdf.loc[s] 的索引列不匹配。

    【讨论】:

      【解决方案2】:

      元组列表不是问题。每个元组不对应于单个索引的事实是问题所在(因为list 不是有效的key)。如果你想像这样索引一个 Dataframe,你需要将每个元组内的列表展开为它们自己的条目。


      定义您的选项,如以下字典列表,然后使用列表理解进行转换,并使用所有单独的条目进行索引。

      d = [
        {
          'id': 0,
          'foo': [1],
          'bar': ['a', 'b']
        },
        {
          'id': 3,
          'foo': [2],
          'bar': ['a', 'b']
        },
        {
          'id': 7,
          'foo': [1, 2],
          'bar': ['a']
        },
      ]
      

      all_idx = [
          (el['id'], i, j)
          for el in d
          for i in el['foo']
          for j in el['bar']
      ]
      
      # [(0, 1, 'a'), (0, 1, 'b'), (3, 2, 'a'), (3, 2, 'b'), (7, 1, 'a'), (7, 2, 'a')]
      
      df.loc[all_idx].groupby(level=0).sum()
      

              col1
      id
      0  -0.225873
      3  -3.048268
      7  -1.315756
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-10
        • 2020-12-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-13
        相关资源
        最近更新 更多