我有一个超过10000列的pandas Dataframe。这些列需要按顺序排序。通常这很简单:
import numpy as np
import pandas as pd
df = pd.read_csv("...*.csv")
df.reindex_axis(sorted(df.columns), axis=1) # sort the columns of the dataframe
对于我的Dataframe df
,这些列中的每一列都是以下格式的字符串:
sampleFIRSTNUMBER_SECONDNUMBER
e.g。 sample42_5864183439
,sample3_8976711222
编辑:作为示例数据框,
df = pd.DataFrame([[1,2,3,4, 5], [5, 6, 7, 8, 9], [9, 10, 11, 12, 13]],columns=['sample1_5','sample10_5','sample100_5','sample1_50', 'sample111_500'])
print(df)
sample1_5 sample10_5 sample100_5 sample1_50 sample111_500
0 1 2 3 4 5
1 5 6 7 8 9
2 9 10 11 12 13
我遇到的问题是排序值的经典问题:目前,sample10_####
位于sample1_####
之前。
对于" SECONDNUMBER"也是如此,即10000在1之前,在10之前等等。
也就是说,chr10_10001
目前排在chr10_11
之前。
我如何正确地格式化这些列,以便" FIRSTNUMER"和" SECONDNUMBER"都按顺序排序?我认为此列不是sample1_5
,而是sample01_000005
格式。手动为这个大小的数据集重新注释这些列名称是不可行的; for循环解析每个数字可能在算法上很困难。
是否有正确的大熊猫友好方式重新格式化这些列? (或者我可能不正确地使用排序?)
答案 0 :(得分:3)
v = df.columns.str.extract('^\D+(\d+)_(\d+)$', expand=True).values.astype(int)
df.iloc[:, np.lexsort(v.T[::-1])]
答案 1 :(得分:2)
您可以extract
与zfill
一起使用,axis=1
对sort_index
进行排序更好:
df = pd.DataFrame([[1,2,3,4]],columns=['sample1_5','sample10_5','sample100_5','sample1_50'])
df = df.sort_index(axis=1)
print (df)
sample100_5 sample10_5 sample1_5 sample1_50
0 3 2 1 4
df1 = df.columns.to_series().str.extract('([a-z]+)(\d+)_(\d+)', expand=True)
df1[1] = df1[1].str.zfill(3)
df1[2] = df1[2].str.zfill(2)
df1['new'] = df1.apply(lambda x: '{}{}_{}'.format(x[0],x[1],x[2]), axis=1)
print (df1)
0 1 2 new
sample100_5 sample 100 05 sample100_05
sample10_5 sample 010 05 sample010_05
sample1_5 sample 001 05 sample001_05
sample1_50 sample 001 50 sample001_50
df.columns = df1['new']
df.columns.name = None
print (df)
sample100_05 sample010_05 sample001_05 sample001_50
0 3 2 1 4
print (df.sort_index(axis=1))
sample001_05 sample001_50 sample010_05 sample100_05
0 1 4 2 3