根据列名对 pandas DataFrame 中的列进行排序 [duplicate]

Sorting columns in pandas dataframe based on column name [duplicate]

提问人:pythOnometrist 提问时间:6/17/2012 最后编辑:fantabolouspythOnometrist 更新时间:5/31/2023 访问量:564443

问:

这个问题在这里已经有答案了:
4年前关闭。

这篇文章在 6 个月前被编辑并提交审核,但未能重新打开帖子:

原始关闭原因未解决

我有一个超过 200 列。问题是,当它们生成时,订单是dataframe

['Q1.3','Q6.1','Q1.2','Q1.1',......]

我需要按如下方式对列进行排序

['Q1.1','Q1.2','Q1.3',.....'Q6.1',......]

有没有办法让我在 Python 中做到这一点?

Python Pandas 数据帧

评论

17赞 Joey 8/20/2020
该问题的顶部有一个横幅“这个问题在这里已经有答案:如何更改 DataFrame 列的顺序?(34 个答案)去年关门了。它所说的问题是一个完全不同的问题,因此应该删除这个横幅和链接。
9赞 William Miller 2/1/2022
我投票重新打开这个问题,我相信它被错误地标记为重复:提供的副本询问如何对列重新排序,而这个问题询问如何按列名排序。严格来说,后者的答案是前者的子集,但寻求后者答案的用户不太可能在重复的答案中找到它(提到排序的最高票数答案目前在总票数中排名第 5)。
2赞 fantabolous 6/4/2023
我完全同意,链接的问题完全不同。为什么没有人会同意重新开放它,这超出了我的范围。

答:

632赞 BrenBarn 6/17/2012 #1
df = df.reindex(sorted(df.columns), axis=1)

这假定对列名称进行排序将给出所需的顺序。如果你的列名不能按字典顺序排序(例如,如果你希望列 Q10.3 出现在 Q9.1 之后),你需要以不同的方式排序,但这与 pandas 无关。

评论

8赞 Nate Anderson 11/18/2015
我喜欢这个,因为可以使用相同的方法对行进行排序(我需要对行和列进行排序)。虽然它是相同的方法,但您可以省略参数(或提供其默认值,),例如,它等效于axis0df.reindex_axis(sorted(non_sorted_row_index))df.reindex(sorted(non_sorted_row_index))
3赞 WhoIsJack 1/29/2018
请注意,重新索引不是就地完成的,因此要实际将排序应用于 df,您必须使用 .另请注意,使用这种方法可以很容易地进行非字典排序,因为列名列表可以单独排序为任意顺序,然后传递给 .这不可能用@Wes McKinney()建议的替代方法,然而,对于纯粹的词典排序来说,这种方法更干净。df = df.reindex_axis(...)reindex_axisdf = df.sort_index(axis=1)
1赞 CodingMatters 5/8/2018
不确定“.reindex_axis”何时被弃用,请参阅下面的消息。FutureWarning:“.reindex_axis”已弃用,将在将来的版本中删除。请改用“.reindex”。这与 ipykernel 包是分开的,因此我们可以避免在以下情况下进行导入
7赞 Logan 9/18/2018
reindex_axis已弃用,并导致 .但是,工作正常。对于上面的示例,请使用FutureWarning.reindexdf.reindex(columns=sorted(df.columns))
2赞 Hedge92 9/1/2021
这是一个很好的解决方案,但如果有重复的列名,则不起作用。在这种情况下,麦金尼@Wes的答案是有效的。因此,我认为这是最合适的解决方案。df.sort_index(axis=1)
1赞 tweet 6/17/2012 #2

该方法和函数允许您提供自定义函数来提取用于比较的键:sortsorted

>>> ls = ['Q1.3', 'Q6.1', 'Q1.2']
>>> sorted(ls, key=lambda x: float(x[1:]))
['Q1.2', 'Q1.3', 'Q6.1']

评论

0赞 pythOnometrist 6/17/2012
这适用于一般的列表,我熟悉它。如何将其应用于 pandas DataFrame?
1赞 tweet 6/17/2012
不确定,我承认我的答案不是特定于这个库的。
477赞 Wes McKinney 7/9/2012 #3

您还可以更简洁地执行以下操作:

df.sort_index(axis=1)

确保将结果分配回去:

df = df.sort_index(axis=1)

或者,就地执行:

df.sort_index(axis=1, inplace=True)

评论

4赞 GoJian 1/6/2017
记得做,每@multigoodversedf = df.sort_index(axis=1)
9赞 jkr 3/2/2017
或就地修改dfdf.sort_index(axis=1, inplace=True)
5赞 ExtractTable.com 11/15/2019
此外,比 更快,以防开发人员担心它sort_indexreindex
3赞 rsmith54 6/10/2021
这应该是公认的答案。
2赞 Hedge92 9/1/2021
同意@rsmith54,因为此解决方案也适用于重复的列名。
27赞 Jeremy Low 10/8/2013 #4

Tweet 的答案可以传递给上面 BrenBarn 的答案

data.reindex_axis(sorted(data.columns, key=lambda x: float(x[1:])), axis=1)

因此,对于您的示例,请说:

vals = randint(low=16, high=80, size=25).reshape(5,5)
cols = ['Q1.3', 'Q6.1', 'Q1.2', 'Q9.1', 'Q10.2']
data = DataFrame(vals, columns = cols)

您将获得:

data

    Q1.3    Q6.1    Q1.2    Q9.1    Q10.2
0   73      29      63      51      72
1   61      29      32      68      57
2   36      49      76      18      37
3   63      61      51      30      31
4   36      66      71      24      77

然后做:

data.reindex_axis(sorted(data.columns, key=lambda x: float(x[1:])), axis=1)

导致:

data


     Q1.2    Q1.3    Q6.1    Q9.1    Q10.2
0    2       0       1       3       4
1    7       5       6       8       9
2    2       0       1       3       4
3    2       0       1       3       4
4    2       0       1       3       4
73赞 Ivelin 6/25/2014 #5

你可以做:

df[sorted(df.columns)]

编辑:较短的是

df[sorted(df)]

评论

1赞 multigoodverse 1/29/2015
为此,我得到了“'DataFrame'对象不可调用”。版本: pandas 0.14.
0赞 zyxue 4/2/2020
@lvelin,你知道为什么有效吗,它有记录在某处吗?sorted(df)
0赞 Ivelin 4/3/2020
@zyxue,将寻找迭代类来弄清楚要排序的内容。看看这个问题 stackoverflow.com/questions/48868228/...sortedmagic methods
16赞 burkesquires 12/8/2014 #6

不要忘记在 Wes 的答案中添加“inplace=True”或将结果设置为新的 DataFrame。

df.sort_index(axis=1, inplace=True)
4赞 multigoodverse 1/29/2015 #7

最快的方法是:

df.sort_index(axis=1)

请注意,这将创建一个新实例。因此,您需要将结果存储在一个新变量中:

sortedDf=df.sort_index(axis=1)
-3赞 Aravind Krishnakumar 6/21/2015 #8
print df.sort_index(by='Frequency',ascending=False)

其中 by 是列的名称,如果要根据列对数据集进行排序

21赞 M.Z 11/6/2015 #9

如果你需要一个任意序列而不是排序序列,你可以做:

sequence = ['Q1.1','Q1.2','Q1.3',.....'Q6.1',......]
your_dataframe = your_dataframe.reindex(columns=sequence)

我在 2.7.10 中对此进行了测试,它对我有用。

36赞 Myeongsik Joo 3/11/2016 #10

对于多个列,您可以根据需要按顺序排列列:

#['A', 'B', 'C'] <-this is your columns order
df = df[['C', 'B', 'A']]

此示例显示对列进行排序和切片:

d = {'col1':[1, 2, 3], 'col2':[4, 5, 6], 'col3':[7, 8, 9], 'col4':[17, 18, 19]}
df = pandas.DataFrame(d)

您将获得:

col1  col2  col3  col4
 1     4     7    17
 2     5     8    18
 3     6     9    19

然后做:

df = df[['col3', 'col2', 'col1']]

导致:

col3  col2  col1
7     4     1
8     5     2
9     6     3     
1赞 Roko Mijic 7/24/2017 #11

一个用例是,您已经用一些前缀命名了(某些)列,并且您希望使用这些前缀并按某种特定顺序(而不是按字母顺序)对列进行排序。

例如,您可能以 、 标签等开头所有要素,并且希望首先使用所有无前缀的列,然后是所有要素,然后是标签。您可以使用以下函数执行此操作(我将注意到用于减少列表的可能效率问题,但除非您有很多列,否则这不是问题,而我没有):Ft_Lbl_sum

def sortedcols(df, groups = ['Ft_', 'Lbl_'] ):
    return df[ sum([list(filter(re.compile(r).search, list(df.columns).copy())) for r in (lambda l: ['^(?!(%s))' % '|'.join(l)] + ['^%s' % i  for i in l ] )(groups)   ], [])  ]