我的数据框在“ A”和“ B”之间具有相似的列名,如下所示:
df = pd.DataFrame({'A_Text1':1, 'A_Text2':2, 'A_Text3':3, 'A_Text4':7, 'B_Text1':4, 'B_Text2':5, 'B_Text3':6, 'B_Text4':8})
当我从此处使用解决方案时,Re-ordering columns in pandas dataframe based on column name之所以会这样,是因为它按字母顺序排列:
df = pd.DataFrame({'A_Text3':3, 'A_Text4':7, 'A_Text1':1, 'A_Text2':2, 'B_Text3':6, 'B_Text4':8, 'B_Text1':4, 'B_Text2':5})
我真正需要的是能够按照我想要的方式排列列名:
Array = ['orangutan', 'sun', 'tan']
“ _ Text”列名称的排列方式始终像我上面指定的那样(_Text3,_Text4,_Text1,_Text2),因为我有数百个具有类似“ _Text”名称的列。
答案 0 :(得分:2)
一个想法是使用助手dictionary
映射自定义顺序,使用另一个字典替换rename
中的字典,最后使用Index.argsort
和DataFrame.iloc
更改新列的顺序名称:
order = {'Text3':'1', 'Text4':'2', 'Text1':'3', 'Text2':'4'}
d = df.columns.to_series().replace(order, regex=True).to_dict()
print (df.rename(columns=d).columns)
Index(['A_3', 'A_4', 'A_1', 'B_3', 'B_4', 'B_1', 'A_2', 'B_2'], dtype='object')
df = df.iloc[:, df.rename(columns=d).columns.argsort()]
print (df)
A_Text3 A_Text4 A_Text1 A_Text2 B_Text3 B_Text4 B_Text1 B_Text2
0 3 7 1 2 6 8 4 5
您还可以创建动态字典,如果列表中有10列以上,还可以添加零以进行正确排序:
order = ['Text3', 'Text4', 'Text1', 'Text2']
order_d = {v: f'{k:03}' for k, v in enumerate(order, 1)}
print (order_d)
{'Text3': '001', 'Text4': '002', 'Text1': '003', 'Text2': '004'}
d = df.columns.to_series().replace(order_d, regex=True)
print (df.rename(columns=d).columns)
Index(['A_003', 'A_004', 'A_001',
'B_003', 'B_004', 'B_001', 'A_002', 'B_002'], dtype='object')
df = df.iloc[:, df.rename(columns=d).columns.argsort()]
print (df)
A_Text3 A_Text4 A_Text1 A_Text2 B_Text3 B_Text4 B_Text1 B_Text2
0 3 7 1 2 6 8 4 5
答案 1 :(得分:0)
让我们尝试pd.Categorical
的第一个想法是创建列的数据框并提取字母和数字表示形式
然后我们进行分类排序。
s = df.columns.to_frame('')
s = s.join(s[0].str.extract("(\w)_\D+(\d)").rename(columns={0: "alpha", 1: "numeric"}))
print(s)
0 alpha numeric
0 A_Text1 A 1
1 A_Text2 A 2
2 A_Text3 A 3
3 B_Text1 B 1
4 B_Text2 B 2
5 B_Text3 B 3
6 A_Text4 A 4
7 B_Text4 B 4
#define your custom order.
order = [3,4,1,2]
s['numeric'] = pd.Categorical(s['numeric'].astype(int),order,ordered=True)
s_ordered = s.sort_values(['alpha','numeric'])
0 alpha numeric
2 A_Text3 A 3
6 A_Text4 A 4
0 A_Text1 A 1
1 A_Text2 A 2
5 B_Text3 B 3
7 B_Text4 B 4
3 B_Text1 B 1
4 B_Text2 B 2
然后分配回您的列。
df.columns = s_ordered[0].tolist()
A_Text3 A_Text4 A_Text1 A_Text2 B_Text3 B_Text4 B_Text1 B_Text2
0 1 2 3 4 5 6 7 8