2012-06-16 193 views
134

我有一个dataframe,列数超过200列(不要问为什么)。这个问题是因为他们产生的顺序Python Pandas - 根据列名重新排列数据框中的列

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

我需要重新排序的列如下:

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

是否有某种方式为我蟒蛇内做到这一点?

+16

为什么你有200列吗? ;) –

+0

可能重复的[如何更改DataFrame列的顺序?](https://stackoverflow.com/questions/13148429/how-to-change-the-order-of-dataframe-columns) –

回答

171
df.reindex_axis(sorted(df.columns), axis=1) 

这假设对列名进行排序会给出您想要的订单。如果列名不按字典顺序排序(例如,如果您希望列Q10.3出现在Q9.1之后),则需要进行不同的排序,但与大熊猫无关。

+2

我喜欢这个因为可以使用相同的方法对行进行排序(我需要对行和列进行排序)。虽然它是相同的方法,但您可以省略'axis'参数(或提供其默认值'0'),如'df.reindex_axis(sorted(non_sorted_row_index))',相当于'df.reindex(sorted(non_sorted_row_index) ))' –

+0

请注意,重新索引不是在原地完成的,因此要将这种排序实际应用于df,您必须使用'df = df.reindex_axis(...)'。另外,请注意,使用这种方法很容易实现非词典排序,因为列名称列表可以单独排序为任意顺序,然后传递给'reindex_axis'。这是@Wes McKinney('df = df.sort_index(axis = 1)')建议的替代方法所不可能的,但这对于纯粹的词典编排来说是更清晰的。 – WhoIsJack

0

sort方法和sorted功能允许您提供自定义的函数来提取用于比较的关键:

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

这适用于一般列表,我对它很熟悉。我如何将它应用于熊猫DataFrame? – pythOnometrist

+1

不确定,我承认我的答案不是特定于此库。 – tweet

186

您还可以做更简洁:

df.sort_index(axis=1)

编辑

确保你持有价值

df = df.sort_index(axis=1)

或做到位

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

+2

记住要用'df.sort_index(axis = 1,inplace = True)'''df = df.sort_index(axis = 1)',通过@multigoodverse – GoJian

+5

或修改'df'' – Jakub

+1

这应该是#1 –

16

Tweet's answer可以传递给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 
20

你可以这样做:

 
df[sorted(df.columns)] 
+1

我得到“'DataFrame'对象不可调用”。版本:熊猫0.14。 – multigoodverse

13

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

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

最快捷的方法是:

df.sort_index(axis=1) 

要知道,这将创建一个新的实例。因此,你需要将结果存储在一个新的变量:

sortedDf=df.sort_index(axis=1) 
-1
print df.sort_index(by='Frequency',ascending=False) 

,其中由是列的名字,如果你想如果你需要一个任意基于列的

9

数据集进行排序序列,而不是排序的序列,你可以这样做:

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

我在2.7.10测试了它,它对我有用。

5

几列,你可以把列命令你想要的东西:

#['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  
0

一个用例是,你命名的(一些)你列了一些前缀,并且要与那些前缀排序的所有在一起的列和一些特定的顺序(不按字母顺序)。例如,您可能会使用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) ], []) ]