关于python:如何更改数据帧列的顺序?

How to change the order of DataFrame columns?

我有一个DataFrame(以下df):

1
2
3
4
import numpy as np
import pandas as pd

df = pd.DataFrame(np.random.rand(10, 5))

我添加更多的列(S)进行分配:

1
df['mean'] = df.mean(1)

我怎么mean将柱的前柱的第一集,即离开它的非接触式测量的其他列的顺序?


一种简单的方法是使用列列表重新分配数据帧,并根据需要重新排列。

这就是你现在拥有的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
In [6]: df
Out[6]:
          0         1         2         3         4      mean
0  0.445598  0.173835  0.343415  0.682252  0.582616  0.445543
1  0.881592  0.696942  0.702232  0.696724  0.373551  0.670208
2  0.662527  0.955193  0.131016  0.609548  0.804694  0.632596
3  0.260919  0.783467  0.593433  0.033426  0.512019  0.436653
4  0.131842  0.799367  0.182828  0.683330  0.019485  0.363371
5  0.498784  0.873495  0.383811  0.699289  0.480447  0.587165
6  0.388771  0.395757  0.745237  0.628406  0.784473  0.588529
7  0.147986  0.459451  0.310961  0.706435  0.100914  0.345149
8  0.394947  0.863494  0.585030  0.565944  0.356561  0.553195
9  0.689260  0.865243  0.136481  0.386582  0.730399  0.561593

In [7]: cols = df.columns.tolist()

In [8]: cols
Out[8]: [0L, 1L, 2L, 3L, 4L, 'mean']

以任何方式重新排列cols。这是我将最后一个元素移动到第一个位置的方式:

1
2
3
4
In [12]: cols = cols[-1:] + cols[:-1]

In [13]: cols
Out[13]: ['mean', 0L, 1L, 2L, 3L, 4L]

然后像这样重新排序数据帧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
In [16]: df = df[cols]  #    OR    df = df.ix[:, cols]

In [17]: df
Out[17]:
       mean         0         1         2         3         4
0  0.445543  0.445598  0.173835  0.343415  0.682252  0.582616
1  0.670208  0.881592  0.696942  0.702232  0.696724  0.373551
2  0.632596  0.662527  0.955193  0.131016  0.609548  0.804694
3  0.436653  0.260919  0.783467  0.593433  0.033426  0.512019
4  0.363371  0.131842  0.799367  0.182828  0.683330  0.019485
5  0.587165  0.498784  0.873495  0.383811  0.699289  0.480447
6  0.588529  0.388771  0.395757  0.745237  0.628406  0.784473
7  0.345149  0.147986  0.459451  0.310961  0.706435  0.100914
8  0.553195  0.394947  0.863494  0.585030  0.565944  0.356561
9  0.561593  0.689260  0.865243  0.136481  0.386582  0.730399


你也可以这样做:

1
df = df[['mean', '0', '1', '2', '3']]

您可以通过以下方式获取列列表:

1
cols = list(df.columns.values)

输出将产生:

1
['0', '1', '2', '3', 'mean']

…在将其放入第一个函数之前,很容易手动重新排列


只需按需要的顺序分配列名:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
In [39]: df
Out[39]:
          0         1         2         3         4  mean
0  0.172742  0.915661  0.043387  0.712833  0.190717     1
1  0.128186  0.424771  0.590779  0.771080  0.617472     1
2  0.125709  0.085894  0.989798  0.829491  0.155563     1
3  0.742578  0.104061  0.299708  0.616751  0.951802     1
4  0.721118  0.528156  0.421360  0.105886  0.322311     1
5  0.900878  0.082047  0.224656  0.195162  0.736652     1
6  0.897832  0.558108  0.318016  0.586563  0.507564     1
7  0.027178  0.375183  0.930248  0.921786  0.337060     1
8  0.763028  0.182905  0.931756  0.110675  0.423398     1
9  0.848996  0.310562  0.140873  0.304561  0.417808     1

In [40]: df = df[['mean', 4,3,2,1]]

现在,"mean"列出现在前面:

1
2
3
4
5
6
7
8
9
10
11
12
13
In [41]: df
Out[41]:
   mean         4         3         2         1
0     1  0.190717  0.712833  0.043387  0.915661
1     1  0.617472  0.771080  0.590779  0.424771
2     1  0.155563  0.829491  0.989798  0.085894
3     1  0.951802  0.616751  0.299708  0.104061
4     1  0.322311  0.105886  0.421360  0.528156
5     1  0.736652  0.195162  0.224656  0.082047
6     1  0.507564  0.586563  0.318016  0.558108
7     1  0.337060  0.921786  0.930248  0.375183
8     1  0.423398  0.110675  0.931756  0.182905
9     1  0.417808  0.304561  0.140873  0.310562


怎么样:

1
df.insert(0, 'mean', df.mean(1))

http://pandas.pydata.org/pandas docs/stable/dsintro.html列选择添加删除


在你的情况下,

1
df = df.reindex_axis(['mean',0,1,2,3,4], axis=1)

会做你想做的。

在我的情况下(一般形式):

1
2
df = df.reindex_axis(sorted(df.columns), axis=1)
df = df.reindex_axis(['opened'] + list([a for a in df.columns if a != 'opened']), axis=1)

更新1月2018

如果您想使用reindex

1
2
df = df.reindex(columns=sorted(df.columns))
df = df.reindex(columns=(['opened'] + list([a for a in df.columns if a != 'opened']) ))


自2018年8月起:

如果列名太长而无法键入,则可以通过具有以下位置的整数列表指定新的顺序:

数据:

1
2
3
4
5
6
7
8
9
10
11
          0         1         2         3         4      mean
0  0.397312  0.361846  0.719802  0.575223  0.449205  0.500678
1  0.287256  0.522337  0.992154  0.584221  0.042739  0.485741
2  0.884812  0.464172  0.149296  0.167698  0.793634  0.491923
3  0.656891  0.500179  0.046006  0.862769  0.651065  0.543382
4  0.673702  0.223489  0.438760  0.468954  0.308509  0.422683
5  0.764020  0.093050  0.100932  0.572475  0.416471  0.389390
6  0.259181  0.248186  0.626101  0.556980  0.559413  0.449972
7  0.400591  0.075461  0.096072  0.308755  0.157078  0.207592
8  0.639745  0.368987  0.340573  0.997547  0.011892  0.471749
9  0.050582  0.714160  0.168839  0.899230  0.359690  0.438500

一般示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
new_order = [3,2,1,4,5,0]
print(df[df.columns[new_order]])  

          3         2         1         4      mean         0
0  0.575223  0.719802  0.361846  0.449205  0.500678  0.397312
1  0.584221  0.992154  0.522337  0.042739  0.485741  0.287256
2  0.167698  0.149296  0.464172  0.793634  0.491923  0.884812
3  0.862769  0.046006  0.500179  0.651065  0.543382  0.656891
4  0.468954  0.438760  0.223489  0.308509  0.422683  0.673702
5  0.572475  0.100932  0.093050  0.416471  0.389390  0.764020
6  0.556980  0.626101  0.248186  0.559413  0.449972  0.259181
7  0.308755  0.096072  0.075461  0.157078  0.207592  0.400591
8  0.997547  0.340573  0.368987  0.011892  0.471749  0.639745
9  0.899230  0.168839  0.714160  0.359690  0.438500  0.050582

对于OP问题的具体情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
new_order = [-1,0,1,2,3,4]
df = df[df.columns[new_order]]
print(df)

       mean         0         1         2         3         4
0  0.500678  0.397312  0.361846  0.719802  0.575223  0.449205
1  0.485741  0.287256  0.522337  0.992154  0.584221  0.042739
2  0.491923  0.884812  0.464172  0.149296  0.167698  0.793634
3  0.543382  0.656891  0.500179  0.046006  0.862769  0.651065
4  0.422683  0.673702  0.223489  0.438760  0.468954  0.308509
5  0.389390  0.764020  0.093050  0.100932  0.572475  0.416471
6  0.449972  0.259181  0.248186  0.626101  0.556980  0.559413
7  0.207592  0.400591  0.075461  0.096072  0.308755  0.157078
8  0.471749  0.639745  0.368987  0.340573  0.997547  0.011892
9  0.438500  0.050582  0.714160  0.168839  0.899230  0.359690

这种方法的主要问题是,多次调用相同的代码每次都会产生不同的结果,因此需要小心:)


您需要按照所需的顺序创建一个新的列列表,然后使用df = df[cols]重新排列这些列。

1
2
cols = ['mean']  + [col for col in df if col != 'mean']
df = df[cols]

您也可以使用更一般的方法。在本例中,最后一列(由-1指示)作为第一列插入。

1
2
cols = [df.columns[-1]] + [col for col in df if col != df.columns[-1]]
df = df[cols]

如果数据帧中存在列,也可以使用此方法按所需顺序重新排序。

1
2
3
4
inserted_cols = ['a', 'b', 'c']
cols = ([col for col in inserted_cols if col in df]
        + [col for col in df if col not in inserted cols])
df = df[cols]

我自己也遇到了一个类似的问题,只是想补充一下我解决的问题。我喜欢用reindex_axis() method来改变列顺序。这起作用了:

1
df = df.reindex_axis(['mean'] + list(df.columns[:-1]), axis=1)

基于@jorge的注释的替代方法:

1
df = df.reindex(columns=['mean'] + list(df.columns[:-1]))

虽然在微观基准上,reindex_axis似乎比reindex稍快,但我认为我更喜欢后者,因为它的直接性。


简单地说,

1
df = df[['mean'] + df.columns[:-1].tolist()]


这个函数避免了您只需要列出数据集中的每个变量就可以对其中的一些进行排序。

1
2
3
4
5
6
def order(frame,var):
    if type(var) is str:
        var = [var] #let the command take a string or list
    varlist =[w for w in frame.columns if w not in var]
    frame = frame[var+varlist]
    return frame

它需要两个参数,第一个参数是数据集,第二个参数是要放在前面的数据集中的列。

所以在我的例子中,我有一个名为frame的数据集,变量a1、a2、b1、b2、total和date。如果我想把道达尔带到前面,那么我要做的就是:

1
frame = order(frame,['Total'])

如果我想把总数和日期放在最前面,那么我会:

1
frame = order(frame,['Total','Date'])

编辑:

另一种有用的方法是,如果您有一个不熟悉的表,并且您正在查找其中包含特定术语的变量,如var1、var2,…您可以执行如下操作:

1
frame = order(frame,[v for v in frame.columns if"VAR" in v])

您可以执行以下操作(从Aman的答案中借用部分内容):

1
2
3
4
5
6
7
cols = df.columns.tolist()
cols.insert(0, cols.pop(-1))

cols
>>>['mean', 0L, 1L, 2L, 3L, 4L]

df = df[cols]

只需键入要更改的列名称,并为新位置设置索引。

1
2
3
4
5
def change_column_order(df, col_name, index):
    cols = df.columns.tolist()
    cols.remove(col_name)
    cols.insert(index, col_name)
    return df[cols]

对于您的案例,如下所示:

1
df = change_column_order(df, 'mean', 0)


将任何列移动到任何位置:

1
2
3
4
5
6
7
8
9
10
11
import pandas as pd
df = pd.DataFrame({"A": [1,2,3],
                  "B": [2,4,8],
                  "C": [5,5,5]})

cols = df.columns.tolist()
column_to_move ="C"
new_position = 1

cols.insert(new_position, cols.pop(cols.index(column_to_move)))
df = df[cols]

最简单的方法是这样更改列名的顺序

df = df[['mean', Col1,Col2,Col3]]


set()

一个简单的方法是使用set(),特别是当您有一个长的列列表并且不想手动处理它们时:

1
2
3
cols = list(set(df.columns.tolist()) - set(['mean']))
cols.insert(0, 'mean')
df = df[cols]


下面是一种移动现有列的方法,该列将在适当的位置修改现有数据帧。

1
2
my_column = df.pop('column name')
df.insert(3, my_column.name, my_column)

这个问题以前已经回答过,但现在不推荐使用reindex轴,因此我建议使用:

1
df.reindex(sorted(df.columns), axis=1)


我按照韦斯·麦金尼的建议尝试了insert()功能。

df.insert(0, 'mean', df.mean(1))

这得到了Timmie想要的结果,在一行中,不需要移动最后一列。


用"T"怎么样?

1
df.T.reindex(['mean',0,1,2,3,4]).T


@发条器:你的解决方案对我很有帮助,因为我想从一个数据帧中把两列放在前面,因为我不知道所有列的确切名称,因为它们是由以前的PIVOT语句生成的。所以,如果你是在同一个情况下:把列放在你知道名字的前面,然后让它们跟在"所有其他列"后面,我就提出了下面的一般解决方案;

1
df = df.reindex_axis(['Col1','Col2'] + list(df.columns.drop(['Col1','Col2'])), axis=1)

您可以使用可用于两个轴的reindex

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
df
#           0         1         2         3         4      mean
# 0  0.943825  0.202490  0.071908  0.452985  0.678397  0.469921
# 1  0.745569  0.103029  0.268984  0.663710  0.037813  0.363821
# 2  0.693016  0.621525  0.031589  0.956703  0.118434  0.484254
# 3  0.284922  0.527293  0.791596  0.243768  0.629102  0.495336
# 4  0.354870  0.113014  0.326395  0.656415  0.172445  0.324628
# 5  0.815584  0.532382  0.195437  0.829670  0.019001  0.478415
# 6  0.944587  0.068690  0.811771  0.006846  0.698785  0.506136
# 7  0.595077  0.437571  0.023520  0.772187  0.862554  0.538182
# 8  0.700771  0.413958  0.097996  0.355228  0.656919  0.444974
# 9  0.263138  0.906283  0.121386  0.624336  0.859904  0.555009

df.reindex(['mean', *range(5)], axis=1)

#        mean         0         1         2         3         4
# 0  0.469921  0.943825  0.202490  0.071908  0.452985  0.678397
# 1  0.363821  0.745569  0.103029  0.268984  0.663710  0.037813
# 2  0.484254  0.693016  0.621525  0.031589  0.956703  0.118434
# 3  0.495336  0.284922  0.527293  0.791596  0.243768  0.629102
# 4  0.324628  0.354870  0.113014  0.326395  0.656415  0.172445
# 5  0.478415  0.815584  0.532382  0.195437  0.829670  0.019001
# 6  0.506136  0.944587  0.068690  0.811771  0.006846  0.698785
# 7  0.538182  0.595077  0.437571  0.023520  0.772187  0.862554
# 8  0.444974  0.700771  0.413958  0.097996  0.355228  0.656919
# 9  0.555009  0.263138  0.906283  0.121386  0.624336  0.859904

这里有一个函数可以为任意数量的列执行此操作。

1
2
3
4
5
def mean_first(df):
    ncols = df.shape[1]        # Get the number of columns
    index = list(range(ncols)) # Create an index to reorder the columns
    index.insert(0,ncols)      # This puts the last column at the front
    return(df.assign(mean=df.mean(1)).iloc[:,index]) # new df with last column (mean) first

书中最简单的方法

1
2
df.insert(0,"test",df["mean"])
df=df.drop(columns=["mean"]).rename(columns={"test":"mean"})

DataFrame.sort_index(axis=1)很干净,请看这里的医生。然后是concat


我喜欢Shoresh的答案,即当您不知道位置时,使用set功能删除列,但这并不适用于我的目的,因为我需要保持原始列顺序(具有任意列标签)。

不过,我是通过使用boltons包中的indexedset来实现这一点的。

我还需要重新添加多个列标签,因此对于更一般的情况,我使用以下代码:

1
2
3
4
from boltons.setutils import IndexedSet
cols = list(IndexedSet(df.columns.tolist()) - set(['mean', 'std']))
cols[0:0] =['mean', 'std']
df = df[cols]

希望这对任何在这个线程中搜索通用解决方案的人都有用。


我相信@aman的答案是最好的,如果你知道另一列的位置。

如果你不知道mean的位置,只知道它的名字,就不能直接求助于cols = cols[-1:] + cols[:-1]。下面是我能想到的下一个最好的办法:

1
2
3
4
meanDf = pd.DataFrame(df.pop('mean'))
# now df doesn't contain"mean" anymore. Order of join will move it to left or right:
meanDf.join(df) # has mean as first column
df.join(meanDf) # has mean as last column