Pandas 熊猫:如何对数据框中的一系列列进行排序?
我有一个数据框,我需要按数据列的最大值排序。我在执行排序时遇到问题,因为我发现的所有排序示例在执行排序时都对数据帧中的所有列进行操作。在这种情况下,我只需要对列的子集进行排序。第一列包含日期,其余90列包含数据。90个数据列当前按其列名的字母顺序排序。我想按最大值的降序对它们进行排序,最大值恰好在最后一行 在更大的方案中,这个问题是关于如何对数据帧中的一系列列执行排序,而不是对数据帧中的所有列进行排序。例如,在某些情况下,我只需要对数据帧的第2列到第12列进行排序,而将其余的列保留在它们现有的顺序中 以下是未排序数据帧的示例:Pandas 熊猫:如何对数据框中的一系列列进行排序?,pandas,dataframe,sorting,range,columnsorting,Pandas,Dataframe,Sorting,Range,Columnsorting,我有一个数据框,我需要按数据列的最大值排序。我在执行排序时遇到问题,因为我发现的所有排序示例在执行排序时都对数据帧中的所有列进行操作。在这种情况下,我只需要对列的子集进行排序。第一列包含日期,其余90列包含数据。90个数据列当前按其列名的字母顺序排序。我想按最大值的降序对它们进行排序,最大值恰好在最后一行 在更大的方案中,这个问题是关于如何对数据帧中的一系列列执行排序,而不是对数据帧中的所有列进行排序。例如,在某些情况下,我只需要对数据帧的第2列到第12列进行排序,而将其余的列保留在它们现有的顺
df.tail()
Date ADAMS ALLEN BARTHOLOMEW BENTON BLACKFORD BOONE BROWN ... WABASH WARREN WARRICK WASHINGTON WAYNE WELLS WHITE WHITLEY
65 2020-05-10 8 828 356 13 14 227 28 ... 64 12 123 48 53 11 149 22
66 2020-05-11 8 860 367 16 14 235 28 ... 67 12 126 48 56 12 161 23
67 2020-05-12 8 872 371 17 14 235 28 ... 67 12 131 49 56 12 162 23
68 2020-05-13 9 897 382 17 14 249 29 ... 68 12 140 50 58 13 164 27
69 2020-05-14 9 955 394 21 14 252 29 ... 69 12 145 50 60 15 164 28
我希望执行排序,以便将第69行中具有最大值的列放在df['Date']之后,并对列进行排序,以便第69行中的值从左到右递减。完成后,我想创建一个包含列标题的系列,以生成排名列表。以可见列为例,所需列表为:
排名表=[“艾伦”、“巴塞洛缪”、“布恩”、“怀特”、“沃里克”、“布莱克福德”、“沃伦”、“亚当斯”]
目前我最大的障碍是,当我执行排序时,我无法排除日期列,并且收到一个类型错误:
TypeError: Cannot compare type 'Timestamp' with type 'int'
我是新来的熊猫,所以我道歉,如果有一个解决这个问题的办法,应该是显而易见的。谢谢。选择正确的行和列的范围后,您可以使用
排序\u值来执行此操作
#data sample
np.random.seed(86)
df = pd.DataFrame({'date':pd.date_range('2020-05-15', periods=5),
'a': np.random.randint(0,50, 5),
'b': np.random.randint(0,50, 5),
'c': np.random.randint(0,50, 5),
'd': np.random.randint(0,50, 5)})
# parameters
start_idx = 1 #note: the indexing start at 0, so 1 is the second column
end_idx = df.shape[1] #for the last column
row_position = df.shape[0]-1 #for the last one
# create the new order
new_col_roder = df.columns.tolist()
new_col_roder[start_idx:end_idx] = df.iloc[row_position, start_idx:end_idx]\
.sort_values(ascending=False).index
#reirder
df = df[new_col_roder]
print(df)
date c a d b
0 2020-05-15 30 20 44 40
1 2020-05-16 45 32 29 9
2 2020-05-17 17 44 14 27
3 2020-05-18 13 28 4 41
4 2020-05-19 41 35 14 12 #as you can see, the columns are now c, a, d, b
我建议如下:
# initialize the provided sample data frame
df = pd.DataFrame([['65 2020-05-10', 8, 828, 356, 13, 14, 227, 28, 64, 12, 123, 48, 53, 11, 149, 22],
['66 2020-05-11', 8, 860, 367, 16, 14, 235, 28, 67, 12, 126, 48, 56, 12, 161, 23],
['67 2020-05-12', 8, 872, 371, 17, 14, 235, 28, 67, 12, 131, 49, 56, 12, 162, 23],
['68 2020-05-13', 9, 897, 382, 17, 14, 249, 29, 68, 12, 140, 50, 58, 13, 164, 27],
['69 2020-05-14', 9, 955, 394, 21, 14, 252, 29, 69, 12, 145, 50, 60, 15, 164, 28]],
columns = ['Date', 'ADAMS', 'ALLEN', 'BARTHOLOMEW', 'BENTON', 'BLACKFORD', 'BOONE', 'BROWN', 'WABASH', 'WARREN', 'WARRICK', 'WASHINGTON', 'WAYNE', 'WELLS', 'WHITE', 'WHITLEY']
)
# a list of tuples in the form (column_name, max_value)
column_max_list = [(column, df[column].max()) for column in df.columns.values[1:]]
# sort the list descending by the max value
column_max_list_sorted = sorted(column_max_list, key = lambda tup: tup[1], reverse = True)
# extract only the column names
rank_list = [tup[0] for tup in column_max_list_sorted]
for i in range(len(rank_list)):
# get the column to insert next
col = df[rank_list[i]]
# drop the column to be inserted back
df.drop(columns = [rank_list[i]], inplace = True)
# insert the column at the correct index
df.insert(loc = i + 1, column = rank_list[i], value = col)
这将生成所需的排名列表
['ALLEN', 'BARTHOLOMEW', 'BOONE', 'WHITE', 'WARRICK', 'WABASH', 'WAYNE', 'WASHINGTON', 'BROWN', 'WHITLEY', 'BENTON', 'WELLS', 'BLACKFORD', 'WARREN', 'ADAMS']
以及所需的df:
Date ALLEN BARTHOLOMEW BOONE WHITE ...
0 65 2020-05-10 828 356 227 149 ...
1 66 2020-05-11 860 367 235 161 ...
2 67 2020-05-12 872 371 235 162 ...
3 68 2020-05-13 897 382 249 164 ...
4 69 2020-05-14 955 394 252 164 ...
谢谢这种方法简单明了,易于实现,并产生了预期的结果。