我知道有一些方法可以交换 python pandas 中的列顺序。 假设我有这个示例数据集:
import pandas as pd
employee = {'EmployeeID' : [0,1,2],
'FirstName' : ['a','b','c'],
'LastName' : ['a','b','c'],
'MiddleName' : ['a','b', None],
'Contact' : ['(M) 133-245-3123', '(F)[email protected]', '(F)312-533-2442 [email protected]']}
df = pd.DataFrame(employee)
一个基本的方法是:
neworder = ['EmployeeID','FirstName','MiddleName','LastName','Contact']
df=df.reindex(columns=neworder)
但是,如您所见,我只想交换两列。这是可行的,因为只有 4 列,但如果我有 100 列呢?交换或重新排序列的有效方法是什么?
可能有2种情况:
假设您当前的列顺序是 [b,c,d,a] 并且您想将其排序为 [a,b,c,d],您可以这样做:
new_df = old_df[['a', 'b', 'c', 'd']]
两列交换
cols = list(df.columns)
a, b = cols.index('LastName'), cols.index('MiddleName')
cols[b], cols[a] = cols[a], cols[b]
df = df[cols]
重新排序列交换(2次交换)
cols = list(df.columns)
a, b, c, d = cols.index('LastName'), cols.index('MiddleName'), cols.index('Contact'), cols.index('EmployeeID')
cols[a], cols[b], cols[c], cols[d] = cols[b], cols[a], cols[d], cols[c]
df = df[cols]
交换多个
现在归结为如何使用列表切片 -
cols = list(df.columns)
cols = cols[1::2] + cols[::2]
df = df[cols]
当面对更大规模的相同问题时,我在这个链接上遇到了一个非常优雅的解决方案:http://www.datasciencemadesimple.com/re-arrange-or-re-order-the-column-of-dataframe- in-pandas-python-2/ 标题下 “在 pandas python 中按列位置重新排列数据框的列”。
基本上,如果您将列顺序作为列表,则可以将其作为新的列顺序读取。
##### Rearrange the column of dataframe by column position in pandas python
df2=df1[df1.columns[[3,2,1,0]]]
print(df2)
就我而言,我有一个预先计算好的列链接,它确定了我想要的新顺序。如果这个顺序被定义为 L 中的一个数组,那么:
a_L_order = a[a.columns[L]]
如果你想在开头有一个固定的列列表,你可以这样做
cols = ['EmployeeID','FirstName','MiddleName','LastName']
df = df[cols + [c for c in df.columns if c not in cols]]
这会将这 4 列放在第一位,其余的保持不变(没有任何重复的列)。
当您没有太多列并且不想列出列名时,一种对列重新排序的简洁方法是使用 .iloc[].
df_reorderd = df.iloc[:, [0, 1, 3, 2, 4]]
当数据帧被写入文件(例如 CSV)时,列也可以重新排序:
df.to_csv('employees.csv',
columns=['EmployeeID','FirstName','MiddleName','LastName','Contact'])
我认为这样的功能对于控制列的位置非常有用:
def df_changeorder(frame: pd.DataFrame, var: list, remove=False, count_order='left', offset=0) -> pd.DataFrame:
"""
:param frame: dataframe
:param var: list of columns to move to the front
:param count_order: where to start counting from left or right to insert
:param offset: cols to skip in the count_order specified
:return: dataframe with order changed
"""
varlist = [w for w in frame.columns if w not in var]
if remove:
frame = frame[var]
else:
if offset == 0:
if count_order == 'left':
frame = frame[var + varlist]
if count_order == 'right':
frame = frame[varlist + var]
else:
if count_order == 'left':
frame = frame[varlist[:offset] + var + varlist[offset:]]
if count_order == 'right':
frame = frame[varlist[:-offset] + var + varlist[-offset:]]
return frame
一个简单的用例就像定义我们想要重新排序的列,例如,使用提供的 DataFrame,如果我们想进行这样的排序:
['EmployeeID', 'Contact', 'LastName', 'FirstName', 'MiddleName']
注意我们只需要移动
Contact
和LastName
,因此我们可以很容易地得到这个结果:
# columns to swap
swap_columns = ["Contact","LastName"]
# change the order
df = df_changeorder(df, swap_columns, count_order='left', offset=1)
使用这种方法,我们可以根据需要重新排序任意数量的列,我们只需要指定列列表,然后像示例中那样应用函数。
根据需要定位pandas系列
#using pandas.iloc
df.iloc[:,[1,3,2,0]]
pandas.iloc 函数的第一个参数用于行,第二个参数用于列,因此我们给出了列必须显示的顺序列表。