![](/img/trans.png)
[英]How to reorder columns of pandas dataframe based on multiple conditions?
[英]How to reorder columns in a Pandas dataframe based on other dataframe columns
假設這些數據幀:
import pandas as pd
df_one = pd.DataFrame({'col_1':[1, 2, 3, 4], 'col_2':[5,6,7,8], 'col_3':[9,10,11,12]})
df_two = pd.DataFrame({'col_1':[1, 2, 3, 4], 'col_3': [9,10,11,12], '2_col':[5, 6, 7, 8]})
實際上,這些數據幀來自不同的 txt 文件,因此每列的概念是相同的,但列的順序不同,並且某些列的名稱略有不同。 兩個數據集都有 33 列代表相同的概念,但順序不同。
如何使用與第一個 df 相同的結構重新排序第二個 df? 表示與 df_one 相同的列順序和相同的列名...
最終目標是將兩個df合並為一個合並的df。
我試過這個:
cols = df_one.columns.to_list() # get columns names from df_one
df_two = df_two.reindex(columns=cols)
但這會在“col_2”中獲得 NaN 值:
col_1 col_2 col_3
0 1 NaN 9
1 2 NaN 10
2 3 NaN 11
3 4 NaN 12
我還嘗試先更改 df_two 中的 col 名稱,然后重新排序:
df_two.columns = cols
df_two = df_two.reindex(columns=cols)
但這也是錯誤的(col_2 現在具有 col_3 的值):
col_1 col_2 col_3
0 1 9 5
1 2 10 6
2 3 11 7
3 4 12 8
感謝您的建議。
根據評論進行編輯:
實際的列名更像是:'Date' & 'iDate'、'Contract' & 'nContract'、'Premium' & 'iPremium'。 我以問題中的數字為例(可能是個壞主意),但相關數字不是名稱的一部分。
我怎樣才能 map df_two 中的列順序? (比如說,df_1 的 col 1 與 df_2 中的 col 1 相同,df_1 的 col 2 是 df_2 的 col_3,df_1 的 col_3 是 df_2 的 col_2) - 然后我將 df_2 中的列重命名為 df_1 中的列。
我認為所有列名都至少有一個數字,因此,您可以根據數字訂購 df_two,然后重命名這些列。 你可以嘗試這樣的事情:
import pandas as pd
import re
df_one = pd.DataFrame({'col_1':[1, 2, 3, 4], 'col_2':[5,6,7,8], 'col_3':[9,10,11,12]})
df_two = pd.DataFrame({'col_1':[1, 2, 3, 4], 'col_3': [9,10,11,12], '2_col':[5, 6, 7, 8]})
print('df_two old:\n\n',df_two,'\n')
def findnum(col):
return int(re.findall('\d+',col)[0])
df_two =df_two[sorted(df_two.columns, key=findnum)]
df_two.columns=df_one.columns
print('df_two new: \n')
print(df_two)
Output:
df_two old:
col_1 col_3 2_col
0 1 9 5
1 2 10 6
2 3 11 7
3 4 12 8
df_two new:
col_1 col_2 col_3
0 1 5 9
1 2 6 10
2 3 7 11
3 4 8 12
如果您的常用參數如您所說'Contract' & 'ContractNum'
編號”,您可以嘗試這樣的事情:
import pandas as pd
df_one = pd.DataFrame({'Contract':[1, 2, 3, 4], 'Date':[5,6,7,8], 'Provider':[9,10,11,12]})
df_two = pd.DataFrame({'iDate':[1, 2, 3, 4], 'ContractNum': [9,10,11,12], 'nProvider':[5, 6, 7, 8]})
print('df_one:\n', df_one,'\n')
print('df_two:\n', df_two,'\n')
def func(pal):
for i,val in enumerate(df_one.columns):
if val.lower() in pal.lower():
return int(i)
df_two=df_two[sorted(df_two.columns, key=func)]
print('df_two sorted: ')
print(df_two,'\n')
df_two.columns=df_one.columns
print('df_two new colnames: ')
print(df_two,'\n')
Output:
df_one:
Contract Date Provider
0 1 5 9
1 2 6 10
2 3 7 11
3 4 8 12
df_two:
iDate ContractNum nProvider
0 1 9 5
1 2 10 6
2 3 11 7
3 4 12 8
df_two sorted:
ContractNum iDate nProvider
0 9 1 5
1 10 2 6
2 11 3 7
3 12 4 8
df_two new colnames:
Contract Date Provider
0 9 1 5
1 10 2 6
2 11 3 7
3 12 4 8
我們可以做的
df[['col_2','col_3']]=-np.sort(-df[['col_2','col_3']].values,axis=1)
df
col_1 col_2 col_3
0 1 9 5
1 2 10 6
2 3 11 7
3 4 12 8
如果數字是列之間的公共參數,我們可以提取它們並將它們傳遞到.map
function 然后使用自定義字典重新分配它們。
df_two.columns = df_two.columns.str.extract("(\d+)")[0].map(
{col.split("_")[1]: col for col in df_one.columns}
).tolist()
#{'1': 'col_1', '2': 'col_2', '3': 'col_3'} <- dict
#['col_1', 'col_3', 'col_2'] <- map output that we re-assign.
print(df_two)
col_1 col_3 col_2
0 1 9 5
1 2 10 6
2 3 11 7
3 4 12 8
然后你可以merge
/ concat
pd.concat([df_one,df_two])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.