首先,我们在两个轴上创建一个带有MultiIndex的小pd.DataFrame
:
columns = pd.MultiIndex.from_tuples([('a', 2), ('a', 3), ('b', 1), ('b', 3)], names=['col_1', 'col_2'])
index = pd.MultiIndex.from_tuples([(pd.Timestamp('2023-03-01'), 'A'), (pd.Timestamp('2023-03-01'), 'B'), (pd.Timestamp('2023-03-01'), 'C'), (pd.Timestamp('2023-03-02'), 'A'), (pd.Timestamp('2023-03-02'), 'B'), (pd.Timestamp('2023-03-03'), 'B'), (pd.Timestamp('2023-03-03'), 'C')], names=['idx_1', 'idx_2'])
data = np.arange(len(index) * len(columns)).reshape(len(index), len(columns))
df = pd.DataFrame(index=index, columns=columns, data=data)
我们得到
col_1 a b
col_2 2 3 1 3
idx_1 idx_2
2023-03-01 A 0 1 2 3
B 4 5 6 7
C 8 9 10 11
2023-03-02 A 12 13 14 15
B 16 17 18 19
2023-03-03 B 20 21 22 23
C 24 25 26 27
现在我想让'A'行和'B'行相等:
col_1 a b
col_2 2 3 1 3
idx_1 idx_2
2023-03-01 A 4 5 6 7
B 4 5 6 7
C 8 9 10 11
2023-03-02 A 16 17 18 19
B 16 17 18 19
2023-03-03 B 20 21 22 23
C 24 25 26 27
我可以这样做:
df = df.unstack()
df.loc[:, pd.IndexSlice[:, :, 'A']] = df.loc[:, pd.IndexSlice[:, :, 'B']].values
df = df.stack().reindex(index)
我想知道是否有另一种不需要复制两次数据的方法。
您可以直接分配您的值,使用rename
强制对齐:
idx = pd.IndexSlice
df.loc[idx[:, 'A'], :] = df.loc[idx[:, 'B'], :].rename({'B': 'A'}, level='idx_2')
输出:
col_1 a b
col_2 2 3 1 3
idx_1 idx_2
2023-03-01 A 4 5 6 7
B 4 5 6 7
C 8 9 10 11
2023-03-02 A 16 17 18 19
B 16 17 18 19
2023-03-03 B 20 21 22 23
C 24 25 26 27
可以通过MultiIndex的DataFrame.rename
二级来分配切片:
df.loc[pd.IndexSlice[:, 'A'],:] = df.loc[pd.IndexSlice[:, 'B'],:].rename({'B':'A'}, level=1)
print (df)
col_1 a b
col_2 2 3 1 3
idx_1 idx_2
2023-03-01 A 4 5 6 7
B 4 5 6 7
C 8 9 10 11
2023-03-02 A 16 17 18 19
B 16 17 18 19
2023-03-03 B 20 21 22 23
C 24 25 26 27
def function1(dd:pd.DataFrame):
dd1=dd.reset_index()
dd1.loc[dd1.idx_2=='A',[ ('a', 2), ('a', 3), ('b', 1), ('b', 3)]]=dd1.loc[dd1.idx_2=='B',[ ('a', 2), ('a', 3), ('b', 1), ('b', 3)]].values
return dd1.set_index(['idx_1', 'idx_2'])
df.groupby(level=0).apply(function1)
:
col_1 a b
col_2 2 3 1 3
idx_1 idx_2
2023-03-01 A 4 5 6 7
B 4 5 6 7
C 8 9 10 11
2023-03-02 A 16 17 18 19
B 16 17 18 19
2023-03-03 B 20 21 22 23
C 24 25 26 27