【问题标题】:Set cross section of pandas MultiIndex to DataFrame from addition of other cross sections通过添加其他横截面将 pandas MultiIndex 的横截面设置为 DataFrame
【发布时间】:2021-06-25 21:37:23
【问题描述】:

我目前正在尝试根据组内的其他索引分配具有某些索引的行。

考虑以下 pandas 数据框:

import pandas as pd
import numpy as np

index = pd.MultiIndex.from_product([list('abc'), ['aa', 'bb', 'cc']])
df = pd.DataFrame({'col1': np.arange(9), 
                   'col2': np.arange(9, 18), 
                   'col3': np.arange(18,27)}, 
                   index=index)

df的输出:

      col1  col2  col3
a aa     0     9    18
  bb     1    10    19
  cc     2    11    20
b aa     3    12    21
  bb     4    13    22
  cc     5    14    23
c aa     6    15    24
  bb     7    16    25
  cc     8    17    26

我想根据第一级索引分配索引“cc”等于“aa”加上“bb”。

以下工作正常,但我想知道是否有一种方法可以设置值而无需引用底层 NumPy 数组。

df.loc[pd.IndexSlice[:, 'cc'], :] = (df.xs('aa', level=1) 
                                     + df.xs('bb', level=1)).values

有没有办法将“cc”行直接设置为下面的输出?我认为尝试直接设置以下内容的问题是由于索引不匹配。我能以某种方式解决这个问题吗?

df.xs('aa', level=1) + df.xs('bb', level=1)

【问题讨论】:

    标签: python pandas dataframe numpy multi-index


    【解决方案1】:

    更新

    您可以使用pandas.DataFrame.iloc

    df.iloc[df.index.get_level_values(1)=='cc'] = df.xs('aa', level=1) + df.xs('bb', level=1)
    

    旧答案

    你可以这样做:

    df[df.index.get_level_values(1)=='cc'] = df.xs('aa', level=1) + df.xs('bb', level=1)
    

    免责声明:它适用于 pandas 1.2.1 版,不适用于 pandas 1.2.3。我没有测试任何其他版本

    【讨论】:

    • 嗨@Pablo C,那不是我的反对意见。这会遇到设置副本的任何问题吗?
    • @JackMoody 嗨 :) 你是什么意思?我不完全理解你的问题
    • 没关系。如果我遇到SettingWithCopyWarning,我应该只能在这种情况下使用loc
    • 不是我的反对意见。但是看到您的代码在所有cc 行上产生nan 值。
    • @SeaBean 这很奇怪。您使用的是哪个熊猫版本?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    • 2019-06-28
    • 1970-01-01
    • 2018-08-03
    • 2011-05-31
    • 1970-01-01
    相关资源
    最近更新 更多