通过添加其他横截面将 pandas MultiIndex 的横截面设置为 DataFrame

Posted

技术标签:

【中文标题】通过添加其他横截面将 pandas MultiIndex 的横截面设置为 DataFrame【英文标题】:Set cross section of pandas MultiIndex to DataFrame from addition of other cross sections 【发布时间】: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)

【问题讨论】:

【参考方案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 这很奇怪。您使用的是哪个熊猫版本?

以上是关于通过添加其他横截面将 pandas MultiIndex 的横截面设置为 DataFrame的主要内容,如果未能解决你的问题,请参考以下文章

panda的多索引的好处?

将Square UIView划分为横截面iOS Objective C

使用 pandas read_csv 方法的 Python 多级索引

如何高效处理面板数据

pandas 中的新列 - 通过应用列表 groupby 将系列添加到数据框

横截面模型拟合优度过高的原因