如何更改 DataFrame 列的顺序?
Posted
技术标签:
【中文标题】如何更改 DataFrame 列的顺序?【英文标题】:How to change the order of DataFrame columns? 【发布时间】:2019-10-27 10:25:18 【问题描述】:我有以下DataFrame
(df
):
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.rand(10, 5))
我通过分配添加更多列:
df['mean'] = df.mean(1)
如何将mean
列移到前面,即将其设置为第一列,而其他列的顺序保持不变?
【问题讨论】:
Python Pandas - Re-ordering columns in a dataframe based on column name的可能重复 对于基于 NumPy 的通用解决方案,请参阅 How to move a column in a pandas dataframe,仅假定一个列级别,即没有MultiIndex
。
经过充分搜索,我得到了这个最佳链接,用于以非常简单的术语重新排列多个逻辑的列 [columns re-arrange logic for pandas] [datasciencemadesimple.com/…
【参考方案1】:
怎么样:
df.insert(0, 'mean', df['mean'])
https://pandas.pydata.org/pandas-docs/stable/user_guide/dsintro.html#column-selection-addition-deletion
【讨论】:
这会是未来添加到pandas
的功能吗?类似df.move(0,df.mean)
?
美丽。它也发生在原地。
这是一个可扩展的解决方案,因为其他解决方案是手动输入列名。
这适用于 OP 的问题,在创建新列时,但不适用于移动列;尝试将结果移动到*** ValueError: cannot insert mean, already exists
这是一个干净的解决方案。现代API方法是:df.insert(0, 'mean', df['mean'])
【参考方案2】:
排序并不能确保保留正确的顺序。通过将 ['mean'] 与列列表连接起来。
cols_list = ['mean'] + df.columns.tolist()
df['mean'] = df.mean(1)
df = df[cols_list]
【讨论】:
【参考方案3】:这是一个超级简单的方法示例。如果您要从 excel 中复制标题,请使用 .split('\t')
df = df['FILE_NAME DISPLAY_PATH SHAREPOINT_PATH RETAILER LAST_UPDATE'.split()]
【讨论】:
【参考方案4】:这是一种移动现有列的方法,该列将修改现有数据框。
my_column = df.pop('column name')
df.insert(3, my_column.name, my_column) # Is in-place
【讨论】:
这几乎是唯一的好方法,因为它是就地的。大多数其他方法都不是就地的,因此不可扩展。【参考方案5】:另一种选择是使用set_index()
方法,后跟reset_index()
。注意我们先pop()
我们打算移动到数据框前面的列,这样在重置索引的时候避免名字冲突:
df.set_index(df.pop('column_name'), inplace=True)
df.reset_index(inplace=True)
更多详情请见How to change the order of dataframe columns in pandas。
【讨论】:
【参考方案6】:我尝试制作一个订单功能,您可以参考 Stata 的订单命令重新排序/移动列。最好是制作一个py文件(名字可能是order.py)并保存在一个目录中并调用它的函数
def order(dataframe,cols,f_or_l=None,before=None, after=None):
#만든이: 김완석, Stata로 뚝딱뚝딱 저자, blog.naver.com/sanzo213 운영
# 갖다 쓰시거나 수정을 하셔도 되지만 출처는 꼭 밝혀주세요
# cols옵션 및 befor/after옵션에 튜플이 가능하게끔 수정했으며, 오류문구 수정함(2021.07.12,1)
# 칼럼이 멀티인덱스인 상태에서 reset_index()메소드 사용했을 시 적용안되는 걸 수정함(2021.07.12,2)
import pandas as pd
if (type(cols)==str) or (type(cols)==int) or (type(cols)==float) or (type(cols)==bool) or type(cols)==tuple:
cols=[cols]
dd=list(dataframe.columns)
for i in cols:
i
dd.remove(i) #cols요소를 제거함
if (f_or_l==None) & ((before==None) & (after==None)):
print('f_or_l옵션을 쓰시거나 아니면 before옵션/after옵션 쓰셔야되요')
if ((f_or_l=='first') or (f_or_l=='last')) & ~((before==None) & (after==None)):
print('f_or_l옵션 사용시 before after 옵션 사용불가입니다.')
if (f_or_l=='first') & (before==None) & (after==None):
new_order=cols+dd
dataframe=dataframe[new_order]
return dataframe
if (f_or_l=='last') & (before==None) & (after==None):
new_order=dd+cols
dataframe=dataframe[new_order]
return dataframe
if (before!=None) & (after!=None):
print('before옵션 after옵션 둘다 쓸 수 없습니다.')
if (before!=None) & (after==None) & (f_or_l==None):
if not((type(before)==str) or (type(before)==int) or (type(before)==float) or
(type(before)==bool) or ((type(before)!=list)) or
((type(before)==tuple))):
print('before옵션은 칼럼 하나만 입력가능하며 리스트 형태로도 입력하지 마세요.')
else:
b=dd[:dd.index(before)]
a=dd[dd.index(before):]
new_order=b+cols+a
dataframe=dataframe[new_order]
return dataframe
if (after!=None) & (before==None) & (f_or_l==None):
if not((type(after)==str) or (type(after)==int) or (type(after)==float) or
(type(after)==bool) or ((type(after)!=list)) or
((type(after)==tuple))):
print('after옵션은 칼럼 하나만 입력가능하며 리스트 형태로도 입력하지 마세요.')
else:
b=dd[:dd.index(after)+1]
a=dd[dd.index(after)+1:]
new_order=b+cols+a
dataframe=dataframe[new_order]
return dataframe
下面的python代码是我做的一个order函数的例子。我希望您可以使用我的排序功能轻松地重新排序列:)
# module
import pandas as pd
import numpy as np
from order import order # call order function from order.py file
# make a dataset
columns='a b c d e f g h i j k'.split()
dic=
n=-1
for i in columns:
n+=1
dic[i]=list(range(1+n,10+1+n))
data=pd.DataFrame(dic)
print(data)
# use order function (1) : order column e in the first
data2=order(data,'e',f_or_l='first')
print(data2)
# use order function (2): order column e in the last , "data" dataframe
print(order(data,'e',f_or_l='last'))
# use order function (3) : order column i before column c in "data" dataframe
print(order(data,'i',before='c'))
# use order function (4) : order column g after column b in "data" dataframe
print(order(data,'g',after='b'))
# use order function (4) : order columns ['c', 'd', 'e'] after column i in "data" dataframe
print(order(data,['c', 'd', 'e'],after='i'))
【讨论】:
【参考方案7】:我想到的和 Dmitriy Work 一样,显然是最简单的答案:
df["mean"] = df.mean(1)
l = list(np.arange(0,len(df.columns) -1 ))
l.insert(0,-1)
df.iloc[:,l]
【讨论】:
【参考方案8】:您可以使用名称列表重新排序数据框列:
df = df.filter(list_of_col_names)
【讨论】:
【参考方案9】:与上面的答案类似,还有一种使用 deque() 及其 rotate() 方法的替代方法。 rotate 方法获取列表中的最后一个元素并将其插入到开头:
from collections import deque
columns = deque(df.columns.tolist())
columns.rotate()
df = df[columns]
【讨论】:
【参考方案10】:如果您的列名太长而无法键入,那么您可以通过带有位置的整数列表来指定新顺序:
数据:
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
这种方法的主要问题是多次调用相同的代码每次都会产生不同的结果,所以需要小心:)
【讨论】:
【参考方案11】:我想从我不确切知道所有列的名称的数据框中将两列放在前面,因为它们是从之前的数据透视语句生成的。 因此,如果您处于相同的情况:要将知道名称的列放在前面,然后让它们跟在“所有其他列”之后,我想出了以下通用解决方案:
df = df.reindex_axis(['Col1','Col2'] + list(df.columns.drop(['Col1','Col2'])), axis=1)
【讨论】:
【参考方案12】:用T
怎么样?
df = df.T.reindex(['mean', 0, 1, 2, 3, 4]).T
【讨论】:
【参考方案13】:对我有用的一个非常简单的解决方案是在df.columns
上使用.reindex
:
df = df[df.columns.reindex(['mean', 0, 1, 2, 3, 4])[0]]
【讨论】:
【参考方案14】:这个问题已经回答了before,但reindex_axis
现在已被弃用,所以我建议使用:
df = df.reindex(sorted(df.columns), axis=1)
对于那些想要指定他们想要的顺序而不是仅仅对它们进行排序的人,这里给出了解决方案:
df = df.reindex(['the','order','you','want'], axis=1)
现在,您希望如何对列名列表进行排序实际上不是pandas
问题,而是 Python 列表操作问题。有很多方法可以做到这一点,我认为this answer 有一种非常简洁的方法。
【讨论】:
不,那是不同的。在那里,用户想要按名称对所有列进行排序。在这里,他们希望将一列移动到第一列,同时保持其他列的顺序不变。 如果您不希望它们排序怎么办? 答案没有解决问题中的问题。 @mins 我希望上面的编辑足够清楚。 :) 您的编辑现在显示了该问题的有效解决方案。谢谢。【参考方案15】:我认为这是一个稍微整洁的解决方案:
df.insert(0, 'mean', df.pop("mean"))
此解决方案与@JoeHeffer 的解决方案有些相似,但这是一个班轮。
这里我们从数据框中删除列"mean"
,并将其附加到具有相同列名的索引0
。
【讨论】:
这很好,但如果你想让它在最后呢? 您创建的任何新列都会添加到末尾,所以我猜应该是df["mean"] = df.pop("mean")
【参考方案16】:
假设您有 df
与列 A
B
C
。
最简单的方法是:
df = df.reindex(['B','C','A'], axis=1)
【讨论】:
此选项的一大优点是您可以在 pandas 管道操作中使用它! 请注意,这只会返回一个重新索引的数据框 - 不会更改正在使用的df
实例。如果要使用重新索引的 df,只需使用返回值:df2 = df.reindex(['B', 'C', 'A'], axis=1)
。感谢您的回答!
@cheevahagadog 好点!
@AndreasForslöw 感谢您强调这一点。【参考方案17】:
书中最简单的方法
df.insert(0, "test", df["mean"])
df = df.drop(columns=["mean"]).rename(columns="test": "mean")
【讨论】:
【参考方案18】:一种简单的方法是使用 set()
,特别是当您有很长的列列表并且不想手动处理它们时:
cols = list(set(df.columns.tolist()) - set(['mean']))
cols.insert(0, 'mean')
df = df[cols]
【讨论】:
一个警告:如果你把它放入集合中,列的顺序就会消失 有趣! @user1930402 我曾多次尝试上述方法,从未遇到任何问题。我会再次检查。【参考方案19】:根据名称设置另一个现有列的右侧/左侧:
def df_move_column(df, col_to_move, col_left_of_destiny="", right_of_col_bool=True):
cols = list(df.columns.values)
index_max = len(cols) - 1
if not right_of_col_bool:
# set left of a column "c", is like putting right of column previous to "c"
# ... except if left of 1st column, then recursive call to set rest right to it
aux = cols.index(col_left_of_destiny)
if not aux:
for g in [x for x in cols[::-1] if x != col_to_move]:
df = df_move_column(
df,
col_to_move=g,
col_left_of_destiny=col_to_move
)
return df
col_left_of_destiny = cols[aux - 1]
index_old = cols.index(col_to_move)
index_new = 0
if len(col_left_of_destiny):
index_new = cols.index(col_left_of_destiny) + 1
if index_old == index_new:
return df
if index_new < index_old:
index_new = np.min([index_new, index_max])
cols = (
cols[:index_new]
+ [cols[index_old]]
+ cols[index_new:index_old]
+ cols[index_old + 1 :]
)
else:
cols = (
cols[:index_old]
+ cols[index_old + 1 : index_new]
+ [cols[index_old]]
+ cols[index_new:]
)
df = df[cols]
return df
例如
cols = list("ABCD")
df2 = pd.DataFrame(np.arange(4)[np.newaxis, :], columns=cols)
for k in cols:
print(30 * "-")
for g in [x for x in cols if x != k]:
df_new = df_move_column(df2, k, g)
print(f"k after g: df_new.columns.values")
for k in cols:
print(30 * "-")
for g in [x for x in cols if x != k]:
df_new = df_move_column(df2, k, g, right_of_col_bool=False)
print(f"k before g: df_new.columns.values")
输出:
【讨论】:
【参考方案20】:您可以使用一个 独特元素的无序集合来保持“其他列的顺序不变”:
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
【讨论】:
【参考方案21】:这是一个非常简单的答案(只有一行)。
您可以在将“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
【讨论】:
【参考方案22】:经常翻转会有所帮助。
df[df.columns[::-1]]
或者只是随便看看。
import random
cols = list(df.columns)
random.shuffle(cols)
df[cols]
【讨论】:
【参考方案23】:我认为这个功能更直接。您只需要在开头或结尾或两者都指定列的子集:
def reorder_df_columns(df, start=None, end=None):
"""
This function reorder columns of a DataFrame.
It takes columns given in the list `start` and move them to the left.
Its also takes columns in `end` and move them to the right.
"""
if start is None:
start = []
if end is None:
end = []
assert isinstance(start, list) and isinstance(end, list)
cols = list(df.columns)
for c in start:
if c not in cols:
start.remove(c)
for c in end:
if c not in cols or c in start:
end.remove(c)
for c in start + end:
cols.remove(c)
cols = start + cols + end
return df[cols]
【讨论】:
【参考方案24】:我有一个非常具体的用例,用于对 pandas 中的列名重新排序。有时我会在基于现有列的数据框中创建一个新列。默认情况下,pandas 将在末尾插入我的新列,但我希望将新列插入到它派生的现有列旁边。
def rearrange_list(input_list, input_item_to_move, input_item_insert_here):
'''
Helper function to re-arrange the order of items in a list.
Useful for moving column in pandas dataframe.
Inputs:
input_list - list
input_item_to_move - item in list to move
input_item_insert_here - item in list, insert before
returns:
output_list
'''
# make copy for output, make sure it's a list
output_list = list(input_list)
# index of item to move
idx_move = output_list.index(input_item_to_move)
# pop off the item to move
itm_move = output_list.pop(idx_move)
# index of item to insert here
idx_insert = output_list.index(input_item_insert_here)
# insert item to move into here
output_list.insert(idx_insert, itm_move)
return output_list
import pandas as pd
# step 1: create sample dataframe
df = pd.DataFrame(
'motorcycle': ['motorcycle1', 'motorcycle2', 'motorcycle3'],
'initial_odometer': [101, 500, 322],
'final_odometer': [201, 515, 463],
'other_col_1': ['blah', 'blah', 'blah'],
'other_col_2': ['blah', 'blah', 'blah']
)
print('Step 1: create sample dataframe')
display(df)
print()
# step 2: add new column that is difference between final and initial
df['change_odometer'] = df['final_odometer']-df['initial_odometer']
print('Step 2: add new column')
display(df)
print()
# step 3: rearrange columns
ls_cols = df.columns
ls_cols = rearrange_list(ls_cols, 'change_odometer', 'final_odometer')
df=df[ls_cols]
print('Step 3: rearrange columns')
display(df)
【讨论】:
【参考方案25】:您需要按所需顺序创建一个新的列列表,然后使用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]
【讨论】:
【参考方案26】: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,系统:1.35 毫秒,总计:1.35 毫秒 挂墙时间:1.08 毫秒
解决方案 4:
CPU 时间:用户 1.23 毫秒,系统:45 微秒,总计:1.27 毫秒 挂壁时间:986 µs
解决方案 5:
CPU 时间:用户 1.09 毫秒,系统:19 微秒,总计:1.11 毫秒 挂壁时间:949 µs
解决方案 6:
CPU 时间:用户 955 µs,系统:34 µs,总计:989 µs 挂壁时间:859 µs
【讨论】:
解决方案 1 是我需要的,因为我有太多列 (53),谢谢 @Pygirl 的值显示实际消耗时间? (用户、系统、总时间或挂壁时间) 这对我来说是解决问题的最佳答案。这么多解决方案(包括我需要的一个)和简单的方法。谢谢! 解决方案 6(没有列表理解):df = df.iloc[:, [1, 2, 3, 0]]
@sergzemsk:***.com/a/55702033/6660373。我按墙上时间比较。【参考方案27】:
大多数答案都不够概括,pandas reindex_axis 方法有点乏味,因此我提供了一个简单的函数来使用字典将任意数量的列移动到任何位置,其中键 = 列名和值 = 要移动的位置到。如果您的数据框很大,则将 True 传递给“big_data”,则该函数将返回有序列列表。您可以使用此列表对数据进行切片。
def order_column(df, columns, big_data = False):
"""Re-Orders dataFrame column(s)
Parameters :
df -- dataframe
columns -- a dictionary:
key = current column position/index or column name
value = position to move it to
big_data -- boolean
True = returns only the ordered columns as a list
the user user can then slice the data using this
ordered column
False = default - return a copy of the dataframe
"""
ordered_col = df.columns.tolist()
for key, value in columns.items():
ordered_col.remove(key)
ordered_col.insert(value, key)
if big_data:
return ordered_col
return df[ordered_col]
# e.g.
df = pd.DataFrame('chicken wings': np.random.rand(10, 1).flatten(), 'taco': np.random.rand(10,1).flatten(),
'coffee': np.random.rand(10, 1).flatten())
df['mean'] = df.mean(1)
df = order_column(df, 'mean': 0, 'coffee':1 )
>>>
col = order_column(df, 'mean': 0, 'coffee':1 , True)
col
>>>
['mean', 'coffee', 'chicken wings', 'taco']
# you could grab it by doing this
df = df[col]
【讨论】:
【参考方案28】:在你的情况下,
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
仍在创建副本。
@Konstantin 你能就这个问题提出另一个问题吗?最好有更多的上下文
@Konstantin 只是好奇,您是否调试过看到copy=False
创建了一个副本?文档声称,当copy=True
、reindex
返回一个新对象时,表明否则它将是同一个旧对象;如果是同一个对象,怎么可能是副本?【参考方案29】:
我自己也遇到过类似的问题,只是想补充一下我确定的内容。我喜欢 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
稍快一些,但我认为我更喜欢后者,因为它的直接性。
【讨论】:
这是一个不错的解决方案,但 reindex_axis 将被弃用。我使用了 reindex,效果很好。 我可能会错过一些东西,但 1/ 您可能忘记在第二个解决方案中包含axis=1
以使用列,而不是行。 2/ 2020年,reindex
解决方案改变了行/列的顺序,但也清除了数据(NaN
无处不在)。【参考方案30】:
此功能避免了您必须列出数据集中的每个变量来订购其中的几个。
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])
【讨论】:
以上是关于如何更改 DataFrame 列的顺序?的主要内容,如果未能解决你的问题,请参考以下文章