在 python 中连接具有不同列数的数据帧后,如何不让列按字母顺序排序

how to not let columns sorted by alphabetical order after concatenate dataframes with different number of columns in python

我在将 python 用于 double-level header 时遇到了这个问题。并从其他论坛发现了同样的问题,如下所述:

当连接 DataFrames 并且 header 是 douple-level 时,如果列名之间存在任何差异,则列名将按字母数字顺序排序。如果它们在 DataFrames 中相同,则不会对它们进行排序。

此类未记录且不需要。当然,默认行为应该是 no-sort。例如:

我有两个数据框

# df1:              C   A   B         # df2:         C   A   B   D
                    1   2   3                        1   2   3   4
                0   4   5   6                    0   5   6   7   8
                1   7   8   9                    1   9  10  11  12

如果我打印 "Cols sorted", concat([df1,df2], sort = False)

# Cols sorted           A   B   C    D
                        2   3   1    4
                    0   5   6   4  NaN
                    1   8   9   7  NaN

但我想保留原始顺序,例如:

# Cols wanted:          C   A   B    D
                        1   2   3    4
                    0   4   5   6  NaN
                    1   7   8   9  NaN

因为当我连接它们时 df1 被放在第一位。当我使用 df1.append(df2) 时,我遇到了同样的问题。

我还组织了一个包含 60 多列的 DataFrame。所以我可以按正确的顺序创建一个新的列名列表,然后简单地做 df = df[list of column name in original order]

使用sort=False (reference)

pd.concat([df4a,df5], sort=False)

    C          B           D           A            E
0   -2.089701   -0.485516   1.610569    -1.048672   NaN
1   -0.675452   -0.367919   -1.610718   -1.624306   NaN

有趣的问题...但是,我想我找到了解决多索引列数据帧连接失败的 sort=False 的方法。

让我们首先通过将数据帧转换为数据帧并使用 pd.concat 将数据帧列索引连接在一起。然后我们使用该结果的索引重新索引 pd.concat 数据帧的列轴以恢复原始列顺序。

设置:

df = pd.DataFrame({'A':np.random.choice(list('ABC'),10) , 'B':np.random.randint(0,5,10),'C':np.random.random(10)})   
df1 = df.set_index(['A','B'], append=True)['C'].unstack([1,2])

df = pd.DataFrame({'A':np.random.choice(list('DEF'),10) , 'B':np.random.randint(0,5,10),'C':np.random.random(10)})
df2 = df.set_index(['A','B'], append=True)['C'].unstack([1,2])

print(df1)
A         B                   C         B         A                  C         B
B         1         4         2         0         0         4        4         2
0  0.657680       NaN       NaN       NaN       NaN       NaN      NaN       NaN
1  0.518157       NaN       NaN       NaN       NaN       NaN      NaN       NaN
2       NaN  0.776922       NaN       NaN       NaN       NaN      NaN       NaN
3       NaN       NaN  0.063375       NaN       NaN       NaN      NaN       NaN
4  0.328447       NaN       NaN       NaN       NaN       NaN      NaN       NaN
5       NaN       NaN       NaN  0.598312       NaN       NaN      NaN       NaN
6       NaN       NaN       NaN       NaN  0.918801       NaN      NaN       NaN
7       NaN       NaN       NaN       NaN       NaN  0.045484      NaN       NaN
8       NaN       NaN       NaN       NaN       NaN       NaN  0.71723       NaN
9       NaN       NaN       NaN       NaN       NaN       NaN      NaN  0.246769

print(df2)
A         D                   E         D                   F                  E
B         1         0         0         3         2         3        2         4
0  0.396883       NaN       NaN       NaN       NaN       NaN      NaN       NaN
1       NaN  0.789478       NaN       NaN       NaN       NaN      NaN       NaN
2       NaN       NaN  0.076724       NaN       NaN       NaN      NaN       NaN
3       NaN       NaN       NaN  0.424836       NaN       NaN      NaN       NaN
4       NaN       NaN       NaN       NaN  0.970031       NaN      NaN       NaN
5       NaN       NaN       NaN       NaN       NaN  0.119261      NaN       NaN
6  0.781708       NaN       NaN       NaN       NaN       NaN      NaN       NaN
7       NaN       NaN       NaN       NaN       NaN       NaN  0.57147       NaN
8       NaN       NaN       NaN       NaN       NaN       NaN      NaN  0.407157
9       NaN       NaN       NaN       NaN  0.932431       NaN      NaN       NaN

首先,让我们尝试pd.concat([df1,df2], sort=False),打印头(2):

A   A       B                     C       D               E       F    
B   0   4   0         1   2   4   2   4   0   1   2   3   0   4   2   3
0 NaN NaN NaN  0.657680 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1 NaN NaN NaN  0.518157 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

不,那没用。

所以,让我们先从两个数据框中连接列索引。

orig_cols = pd.concat([df1.columns.to_frame(), df2.columns.to_frame()]).index
pd.concat([df1,df2]).reindex(orig_cols, axis=1)

现在让我们看看 head(2) 的输出:

A         B       C   B   A       C   B   D       E   D       F       E
B         1   4   2   0   0   4   4   2   1   0   0   3   2   3   2   4
0  0.657680 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1  0.518157 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

成功了。