我有以下 DataFrame
(df
):
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.rand(10, 5))
我通过分配添加更多列:
df['mean'] = df.mean(1)
如何将列 mean
移到前面,即将其设置为第一列,而其他列的顺序保持不变?
MultiIndex
。
df = df[ list with newly arranged column names ]
;D
一种简单的方法是使用列列表重新分配数据框,并根据需要重新排列。
这就是你现在所拥有的:
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
。这就是我将最后一个元素移动到第一个位置的方式:
In [12]: cols = cols[-1:] + cols[:-1]
In [13]: cols
Out[13]: ['mean', 0L, 1L, 2L, 3L, 4L]
然后像这样重新排序数据框:
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
你也可以这样做:
df = df[['mean', '0', '1', '2', '3']]
您可以通过以下方式获取列列表:
cols = list(df.columns.values)
输出将产生:
['0', '1', '2', '3', 'mean']
...然后很容易在将其放入第一个函数之前手动重新排列
df.columns.tolist()
pd.read_csv()
导入。您的答案如何用于更改列顺序?
只需按照您想要的顺序分配列名:
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]]
现在,“平均”列出现在前面:
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
<df>.columns
对于 pandas >= 1.3(2022 年编辑):
df.insert(0, 'mean', df.pop('mean'))
怎么样(对于 Pandas < 1.3,原始答案)
df.insert(0, 'mean', df['mean'])
pandas
的功能吗? df.move(0,df.mean)
之类的东西?
*** ValueError: cannot insert mean, already exists
df.insert(0, 'mean', df['mean'])
在你的情况下,
df = df.reindex(columns=['mean',0,1,2,3,4])
会做你想做的事。
就我而言(一般形式):
df = df.reindex(columns=sorted(df.columns))
df = df.reindex(columns=(['opened'] + list([a for a in df.columns if a != 'opened']) ))
copy=False
,但看起来 reindex_axis
仍会创建一个副本。
copy=False
创建了一个副本?该文档声称,当 copy=True
、reindex
返回一个新对象时,表明否则它将是同一个旧对象;如果它是同一个对象,它怎么可能是一个副本?
import numpy as np
import pandas as pd
df = pd.DataFrame()
column_names = ['x','y','z','mean']
for col in column_names:
df[col] = np.random.randint(0,100, size=10000)
您可以尝试以下解决方案:
解决方案1:
df = df[ ['mean'] + [ col for col in df.columns if col != 'mean' ] ]
解决方案2:
df = df[['mean', 'x', 'y', 'z']]
解决方案3:
col = df.pop("mean")
df = df.insert(0, col.name, col)
解决方案4:
df.set_index(df.columns[-1], inplace=True)
df.reset_index(inplace=True)
解决方案 5:
cols = list(df)
cols = [cols[-1]] + cols[:-1]
df = df[cols]
解决方案6:
order = [1,2,3,0] # setting column's order
df = df[[df.columns[i] for i in order]]
时间比较:
解决方案1:
CPU 时间:用户 1.05 毫秒,系统:35 微秒,总计:1.08 毫秒 挂壁时间:995 微秒
解决方案2:
CPU 时间:用户 933 µs,系统:0 ns,总计:933 µs 挂壁时间:800 µs
解决方案3:
CPU 时间:用户 0 ns,sys:1.35 ms,总计:1.35 ms Wall time:1.08 ms
解决方案4:
CPU 时间:用户 1.23 毫秒,系统:45 微秒,总计:1.27 毫秒 挂壁时间:986 微秒
解决方案 5:
CPU 时间:用户 1.09 毫秒,系统:19 微秒,总计:1.11 毫秒挂壁时间:949 微秒
解决方案 6:
CPU 时间:用户 955 µs,系统:34 µs,总计:989 µs 挂壁时间:859 µs
df = df.iloc[:, [1, 2, 3, 0]]
您需要按所需顺序创建新的列列表,然后使用 df = df[cols]
以新顺序重新排列列。
cols = ['mean'] + [col for col in df if col != 'mean']
df = df[cols]
您还可以使用更通用的方法。在此示例中,最后一列(由 -1 表示)作为第一列插入。
cols = [df.columns[-1]] + [col for col in df if col != df.columns[-1]]
df = df[cols]
如果 DataFrame 中存在列,您还可以使用此方法按所需顺序对列进行重新排序。
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]
假设您有 df
列 A
B
C
。
最简单的方法是:
df = df.reindex(['B','C','A'], axis=1)
df
实例。如果要使用重新索引的 df,只需使用返回值:df2 = df.reindex(['B', 'C', 'A'], axis=1)
。感谢您的回答!
如果您的列名太长而无法键入,那么您可以通过具有位置的整数列表指定新顺序:
数据:
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
通用示例:
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
虽然看起来我只是以不同的顺序显式键入列名,但有一个“平均值”列这一事实应该清楚地表明 new_order
与实际位置相关,而不是列名。
对于OP问题的具体情况:
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
这种方法的主要问题是多次调用相同的代码每次都会产生不同的结果,所以需要小心:)
此问题已回答 before,但 reindex_axis
现在已弃用,因此我建议使用:
df = df.reindex(sorted(df.columns), axis=1)
对于那些想要指定他们想要的顺序而不是仅仅对它们进行排序的人,这里给出了解决方案:
df = df.reindex(['the','order','you','want'], axis=1)
现在,您希望如何对列名列表进行排序实际上不是 pandas
问题,而是 Python 列表操作问题。有很多方法可以做到这一点,我认为 this answer 有一种非常简洁的方法。
我认为这是一个稍微整洁的解决方案:
df.insert(0, 'mean', df.pop("mean"))
这个解决方案有点类似于@JoeHeffer 的解决方案,但这是一个衬里。
在这里,我们从数据框中删除列 "mean"
并将其附加到具有相同列名的索引 0
。
df["mean"] = df.pop("mean")
您可以使用名称列表重新排序数据框列:
df = df.filter(list_of_col_names)
我自己也遇到了类似的问题,只是想补充一下我确定的内容。我喜欢用于更改列顺序的 reindex_axis() method
。这有效:
df = df.reindex_axis(['mean'] + list(df.columns[:-1]), axis=1)
基于@Jorge 评论的替代方法:
df = df.reindex(columns=['mean'] + list(df.columns[:-1]))
尽管 reindex_axis
在微基准测试中似乎比 reindex
稍快一些,但我认为我更喜欢后者,因为它的直接性。
axis=1
以使用列,而不是行。 2/ 在 2020 年,reindex
解决方案会更改行/列顺序,但也会清除数据(到处都是 NaN
)。
简单地做,
df = df[['mean'] + df.columns[:-1].tolist()]
order = df.columns.tolist()
df['mean'] = df.mean(1)
df.columns = ['mean'] + order
headers
,它用于创建一个字典,然后用于创建 DataFrame,我称之为 df.reindex(columns=headers)
。我遇到的唯一问题是我已经调用了 df.set_index('some header name', inplace=True)
,所以当重新索引完成时,它添加了另一个名为 some header name
的列,因为原始列现在是索引。至于上面指定的语法,python 解释器中的 ['mean'] + df.columns
给了我 Index(u'meanAddress', u'meanCity', u'meanFirst Name'...
此功能避免了您必须列出数据集中的每个变量来订购其中的几个。
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。如果我想把 Total 带到前面,那么我所要做的就是:
frame = order(frame,['Total'])
如果我想把 Total 和 Date 放在前面,那么我会这样做:
frame = order(frame,['Total','Date'])
编辑:
另一个有用的使用方法是,如果您有一个不熟悉的表,并且您正在查看其中包含特定术语的变量,例如 VAR1、VAR2...,您可以执行以下操作:
frame = order(frame,[v for v in frame.columns if "VAR" in v])
这是一种移动现有列的方法,该列将修改现有数据框。
my_column = df.pop('column name')
df.insert(3, my_column.name, my_column) # Is in-place
您可以执行以下操作(从 Aman 的答案中借用部分内容):
cols = df.columns.tolist()
cols.insert(0, cols.pop(-1))
cols
>>>['mean', 0L, 1L, 2L, 3L, 4L]
df = df[cols]
只需键入要更改的列名,然后为新位置设置索引。
def change_column_order(df, col_name, index):
cols = df.columns.tolist()
cols.remove(col_name)
cols.insert(index, col_name)
return df[cols]
对于您的情况,这将是:
df = change_column_order(df, 'mean', 0)
将任意列移动到任意位置:
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.reindex_axis(['Col1','Col2'] + list(df.columns.drop(['Col1','Col2'])), axis=1)
这是一个非常简单的答案(只有一行)。
您可以在将“n”列添加到 df 后执行此操作,如下所示。
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.rand(10, 5))
df['mean'] = df.mean(1)
df
0 1 2 3 4 mean
0 0.929616 0.316376 0.183919 0.204560 0.567725 0.440439
1 0.595545 0.964515 0.653177 0.748907 0.653570 0.723143
2 0.747715 0.961307 0.008388 0.106444 0.298704 0.424512
3 0.656411 0.809813 0.872176 0.964648 0.723685 0.805347
4 0.642475 0.717454 0.467599 0.325585 0.439645 0.518551
5 0.729689 0.994015 0.676874 0.790823 0.170914 0.672463
6 0.026849 0.800370 0.903723 0.024676 0.491747 0.449473
7 0.526255 0.596366 0.051958 0.895090 0.728266 0.559587
8 0.818350 0.500223 0.810189 0.095969 0.218950 0.488736
9 0.258719 0.468106 0.459373 0.709510 0.178053 0.414752
### here you can add below line and it should work
# Don't forget the two (()) 'brackets' around columns names.Otherwise, it'll give you an error.
df = df[list(('mean',0, 1, 2,3,4))]
df
mean 0 1 2 3 4
0 0.440439 0.929616 0.316376 0.183919 0.204560 0.567725
1 0.723143 0.595545 0.964515 0.653177 0.748907 0.653570
2 0.424512 0.747715 0.961307 0.008388 0.106444 0.298704
3 0.805347 0.656411 0.809813 0.872176 0.964648 0.723685
4 0.518551 0.642475 0.717454 0.467599 0.325585 0.439645
5 0.672463 0.729689 0.994015 0.676874 0.790823 0.170914
6 0.449473 0.026849 0.800370 0.903723 0.024676 0.491747
7 0.559587 0.526255 0.596366 0.051958 0.895090 0.728266
8 0.488736 0.818350 0.500223 0.810189 0.095969 0.218950
9 0.414752 0.258719 0.468106 0.459373 0.709510 0.178053
您可以使用一组独特元素的无序集合来保持“其他列的顺序不变”:
other_columns = list(set(df.columns).difference(["mean"])) #[0, 1, 2, 3, 4]
然后,您可以使用 lambda 通过以下方式将特定列移到前面:
In [1]: import numpy as np
In [2]: import pandas as pd
In [3]: df = pd.DataFrame(np.random.rand(10, 5))
In [4]: df["mean"] = df.mean(1)
In [5]: move_col_to_front = lambda df, col: df[[col]+list(set(df.columns).difference([col]))]
In [6]: move_col_to_front(df, "mean")
Out[6]:
mean 0 1 2 3 4
0 0.697253 0.600377 0.464852 0.938360 0.945293 0.537384
1 0.609213 0.703387 0.096176 0.971407 0.955666 0.319429
2 0.561261 0.791842 0.302573 0.662365 0.728368 0.321158
3 0.518720 0.710443 0.504060 0.663423 0.208756 0.506916
4 0.616316 0.665932 0.794385 0.163000 0.664265 0.793995
5 0.519757 0.585462 0.653995 0.338893 0.714782 0.305654
6 0.532584 0.434472 0.283501 0.633156 0.317520 0.994271
7 0.640571 0.732680 0.187151 0.937983 0.921097 0.423945
8 0.562447 0.790987 0.200080 0.317812 0.641340 0.862018
9 0.563092 0.811533 0.662709 0.396048 0.596528 0.348642
In [7]: move_col_to_front(df, 2)
Out[7]:
2 0 1 3 4 mean
0 0.938360 0.600377 0.464852 0.945293 0.537384 0.697253
1 0.971407 0.703387 0.096176 0.955666 0.319429 0.609213
2 0.662365 0.791842 0.302573 0.728368 0.321158 0.561261
3 0.663423 0.710443 0.504060 0.208756 0.506916 0.518720
4 0.163000 0.665932 0.794385 0.664265 0.793995 0.616316
5 0.338893 0.585462 0.653995 0.714782 0.305654 0.519757
6 0.633156 0.434472 0.283501 0.317520 0.994271 0.532584
7 0.937983 0.732680 0.187151 0.921097 0.423945 0.640571
8 0.317812 0.790987 0.200080 0.641340 0.862018 0.562447
9 0.396048 0.811533 0.662709 0.596528 0.348642 0.563092
只是翻转经常有帮助。
df[df.columns[::-1]]
或者只是洗牌看看。
import random
cols = list(df.columns)
random.shuffle(cols)
df[cols]
您可以使用可用于两个轴的 reindex
:
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
书中最黑客的方法
df.insert(0, "test", df["mean"])
df = df.drop(columns=["mean"]).rename(columns={"test": "mean"})
对我有用的一个非常简单的解决方案是在 df.columns
上使用 .reindex
:
df = df[df.columns.reindex(['mean', 0, 1, 2, 3, 4])[0]]
这是一个对任意数量的列执行此操作的函数。
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
一种简单的方法是使用 set()
,特别是当您有很长的列列表并且不想手动处理它们时:
cols = list(set(df.columns.tolist()) - set(['mean']))
cols.insert(0, 'mean')
df = df[cols]
使用 T
怎么样?
df = df.T.reindex(['mean', 0, 1, 2, 3, 4]).T
如果您知道另一列的位置,我相信 @Aman's answer 是最好的。
如果您不知道 mean
的位置,而只知道它的名称,则不能直接求助于 cols = cols[-1:] + cols[:-1]
。以下是我能想到的下一个最好的事情:
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
cols
的类型是list
;它甚至允许重复(在数据帧上使用时将被丢弃)。您正在考虑Index
个对象。