Изменение порядка общих столбцов, но не других в фрейме данных pandas

#python #pandas #dataframe

Вопрос:

У меня есть два кадра данных с сотнями столбцов. У некоторых одно и то же имя, у некоторых-нет. Я хочу, чтобы в двух кадрах данных столбцы с одинаковыми именами были перечислены в одном и том же порядке. Как правило, если бы это были единственные столбцы, я бы сделал:

 df2 = df2.filter(df1.columns)
 

Однако, поскольку существуют столбцы с разными именами, это исключит все столбцы в df2, которых нет в df1.

Как упорядочить все общие столбцы в одном порядке, не теряя при этом столбцы, которые не являются общими? Те, что не являются общими, должны храниться в первоначальном порядке. Поскольку у меня сотни столбцов, я не могу сделать это вручную, но мне нужно быстрое решение, такое как «фильтр». Пожалуйста, обратите внимание, что, хотя есть похожие вопросы, они не касаются случая «некоторые столбцы являются общими, а некоторые-разными».

Пример:

 df1.columns = A,B,C,...,Z,1,2,...,1000
df2.columns = Z,K,P,T,...,01,02,...,01000
 

Я хочу изменить порядок столбцов, чтобы df2 был:

 df2.columns = A,B,C,...,Z,01,02,...,01000
 

Ответ №1:

Попробуйте sets выполнить операции с именами столбцов, такими как intersection и difference :

Настройка MRE

 >>> df1
   A  B  C  D
0  2  7  7  5
1  6  8  4  2

>>> df2
   C  B  E  F
0  8  7  3  2
1  8  6  5  8
 
 c0 = df1.columns.intersection(df2.columns)
c1 = df1.columns.difference(df2.columns)
c2 = df2.columns.difference(df1.columns)

df1 = df1[c0.tolist()   c1.tolist()]
df2 = df2[c0.tolist()   c2.tolist()]
 

Выход:

 >>> df1
   B  C  A  D
0  7  7  2  5
1  8  4  6  2

>>> df2
   B  C  E  F
0  7  8  3  2
1  6  8  5  8
 

Ответ №2:

Предположим, вы также хотите сохранить столбцы, которые не являются общими, в одном и том же месте:

 # make a copy of df2 column names
new_cols = df2.columns.values.copy()

# reorder common column names in df2 to be same order as df1
new_cols[df2.columns.isin(df1.columns)] = df1.columns[df1.columns.isin(df2.columns)]

# reorder columns using new_cols
df2[new_cols]
 

Пример:

 df1 = pd.DataFrame([[1,2,3,4,5]], columns=list('badfe'))
df2 = pd.DataFrame([[1,2,3,4,5]], columns=list('fsxad'))

df1
   b  a  d  f  e
0  1  2  3  4  5

df2
   f  s  x  a  d
0  1  2  3  4  5

new_cols = df2.columns.values.copy()
new_cols[df2.columns.isin(df1.columns)] = df1.columns[df1.columns.isin(df2.columns)]

df2[new_cols]
   a  s  x  d  f
0  4  2  3  5  1
 

Ответ №3:

Вы можете сделать, используя pd.Index.difference и pd.index.union

 i = df1.columns.intersection(df2.columns,sort=False).union(
    df2.columns.difference(df1.columns),sort=False
     )
out = df2.loc[:,i]
 

 df1 = pd.DataFrame(columns=list("ABCEFG"))
df2 = pd.DataFrame(columns=list("ECDAFGHI"))
print(df1)
print(df2)
i = df2.columns.intersection(df1.columns,sort=False).union(
    df2.columns.difference(df1.columns),sort=False
     )
print(df2.loc[:,i])

Empty DataFrame
Columns: [A, B, C, E, F, G]
Index: []
Empty DataFrame
Columns: [E, C, D, A, F, G, H, I]
Index: []
Empty DataFrame
Columns: [A, C, E, F, G, D, H, I]
Index: []