Вы можете использовать concat
, а затем сортировать по , отсортированному по нескольким атрибутам и изменять порядок по новым значениям с подмножеством - []
:
df = pd.concat([df1, df2], axis=1)
cols = sorted(df.columns, key = lambda x: (x[-1], x[:-1]))
print (cols)
['A1', 'AB1', 'B1', 'C1', 'A2', 'AB2', 'B2', 'C2', 'A3', 'AB3', 'B3', 'C3']
df = df[cols]
print (df)
A1 AB1 B1 C1 A2 AB2 B2 C2 A3 AB3 B3 C3
0 0 0 1 2 3 1 4 5 6 2 7 8
1 9 3 10 11 12 4 13 14 15 5 16 17
2 18 6 19 20 21 7 22 23 24 8 25 26
3 27 9 28 29 30 10 31 32 33 11 34 35
4 36 12 37 38 39 13 40 41 42 14 43 44
Другая идея заключается в создании MultiIndex in columns
и сортировке по второму уровню, последним сглаживанием MultiIndex
назад по map
:
df1.columns = [df1.columns.str[:1], df1.columns.str[1]]
df2.columns = [df2.columns.str[:2], df2.columns.str[2]]
df = pd.concat([df1, df2],axis=1).sort_index(axis=1, level=1)
df.columns = df.columns.map(''.join)
print (df)
A1 AB1 B1 C1 A2 AB2 B2 C2 A3 AB3 B3 C3
0 0 0 1 2 3 1 4 5 6 2 7 8
1 9 3 10 11 12 4 13 14 15 5 16 17
2 18 6 19 20 21 7 22 23 24 8 25 26
3 27 9 28 29 30 10 31 32 33 11 34 35
4 36 12 37 38 39 13 40 41 42 14 43 44
РЕДАКТИРОВАТЬ:
Для более общего решения можно использовать DataFrame.reindex
с MultiIndex.from_product
:
df1 = pd.DataFrame(data = np.arange(45).reshape(-1,9),
columns = ['A1','B1', 'C1', 'A2', 'B2', 'C2','A3','B3','C3'])
df2 = pd.DataFrame(data = np.arange(15).reshape(-1,3), columns = ['Sum1','Sum2','Sum3'])
#change order of values in MultiIndex
df1.columns = [df1.columns.str[1], df1.columns.str[:1]]
df2.columns = [df2.columns.str[3], df2.columns.str[:3]]
mux = pd.MultiIndex.from_product([['1','2','3'], ['A','Sum','B','C']])
print (mux)
MultiIndex([('1', 'A'),
('1', 'Sum'),
('1', 'B'),
('1', 'C'),
('2', 'A'),
('2', 'Sum'),
('2', 'B'),
('2', 'C'),
('3', 'A'),
('3', 'Sum'),
('3', 'B'),
('3', 'C')],
)
df = pd.concat([df1, df2], axis=1).reindex(columns=mux)
df.columns = [f'{b}{a}' for a, b in df.columns]
print (df)
A1 Sum1 B1 C1 A2 Sum2 B2 C2 A3 Sum3 B3 C3
0 0 0 1 2 3 1 4 5 6 2 7 8
1 9 3 10 11 12 4 13 14 15 5 16 17
2 18 6 19 20 21 7 22 23 24 8 25 26
3 27 9 28 29 30 10 31 32 33 11 34 35
4 36 12 37 38 39 13 40 41 42 14 43 44