这个问题是试图概括为这个问题提供的解决方案:
Pandas: add a column to a multiindex column dataframe
我需要为每个列索引生成一个列。
spencerlyon2
提供的解决方案在我们要添加单个列时起作用:
df['bar', 'three'] = [0, 1, 2]
但是我想对每个第一级列索引进行概括。
源DF:
In [1]: df
Out[2]:
first bar baz
second one two one two
A -1.089798 2.053026 0.470218 1.440740
B 0.488875 0.428836 1.413451 -0.683677
C -0.243064 -0.069446 -0.911166 0.478370
下面的目标DF要求three
列是其各自索引的one
和two
列的加法。
In [1]: df
Out[2]:
first bar baz
second one two three one two three
A -1.089798 2.053026 0.963228 1.440740 -2.317647 -0.876907
B 0.488875 0.428836 0.917711 -0.683677 0.345873 -0.337804
C -0.243064 -0.069446 -0.312510 0.478370 0.266761 0.745131
答案 0 :(得分:1)
我从您的示例输入开始:
first bar baz
second one two one two
A -1.089798 2.053026 0.470218 1.440740
B 0.488875 0.428836 1.413451 -0.683677
C -0.243064 -0.069446 -0.911166 0.478370
要将新列添加到MultiIndex列的每个级别0, 您可以运行以下命令:
for c1 in df.columns.get_level_values('first').unique():
# New column int index
cInd = int(df.columns.get_loc(c1).stop)
col = (c1, 'three') # New column name
newVal = df[(c1, 'one')] + df[(c1, 'two')]
df.insert(loc=cInd, column=col, value=newVal) # Insert the new column
在上面的示例中,新列中的值是连续数字,但是 根据您的需要设置它们。
我的代码(在列排序之后)的结果是:
first bar baz
second one two three one two three
A -1.089798 2.053026 0.963228 0.470218 1.440740 1.910958
B 0.488875 0.428836 0.917711 1.413451 -0.683677 0.729774
C -0.243064 -0.069446 -0.312510 -0.911166 0.478370 -0.432796
答案 1 :(得分:1)
您可以将join
与具有相同索引的两个数据帧一起使用,以一次创建一堆列。
首先,使用groupby
对axis=1
来计算总和
ndf = df.groupby(df.columns.get_level_values(0), axis=1).sum()
bar baz
A 0.963228 1.910958
B 0.917711 0.729774
C -0.312510 -0.432796
(PS:如果您有两列以上,可以这样做
df.loc[:, (slice(None), ['one', 'two'])].groupby(df.columns.get_level_values(0), axis=1).sum()
首先仅对列“一”和“两”进行切片,然后仅对然后 groupby
)进行切片
然后,使其与您的列索引匹配,即使其与原始数据框一样成为MultiIndexed数据框
ndf.columns = pd.MultiIndex.from_product([ndf.columns, ['three']])
bar baz
three three
A 0.963228 1.910958
B 0.917711 0.729774
C -0.312510 -0.432796
最后,df.join
finaldf = df.join(ndf).sort_index(axis=1)
如果您真的很在乎订购,请使用reindex
finaldf.reindex(['one', 'two', 'three'], axis=1, level=1)
first bar baz
second one two three one two three
A -1.089798 2.053026 0.963228 0.470218 1.440740 1.910958
B 0.488875 0.428836 0.917711 1.413451 -0.683677 0.729774
C -0.243064 -0.069446 -0.312510 -0.911166 0.478370 -0.432796