假设有一个这种类型的数据框(可能有更多列):
d = {'ATTRIBUTE_NAME':
['Raw_Read_Error_Rate',
'Reallocate_NAND_Blk_Cnt',
'Power_On_Hours',
'Power_Cycle_Count',
'Program_Fail_Count',
'Erase_Fail_Count',
'Ave_Block-Erase_Count',
'Unexpect_Power_Loss_Ct',
'Unused_Reserve_NAND_Blk',
'SATA_Interfac_Downshift',
'Error_Correction_Count',
'Reported_Uncorrect',
'Temperature_Celsius',
'Reallocated_Event_Count',
'Current_Pending_Sector',
'Offline_Uncorrectable',
'UDMA_CRC_Error_Count',
'Percent_Lifetime_Remain',
'Write_Error_Rate',
'Success_RAIN_Recov_Cnt',
'Total_Host_Sector_Write',
'Host_Program_Page_Count',
'FTL_Program_Page_Count']}
df = pd.DataFrame(d)
必须通过以下键按“ATTRIBUTE_NAME”列排序:首先以“Count”结尾的行,然后按行长排序,然后按字典顺序。
如果您需要通过类似的键对简单列表进行排序,那么这很简单,只需使用 'key' 参数即可:
sorted(l, key=lambda x: (-x.endswith('Count'), len(x), x))
但在数据框的情况下,并非一切都那么明显。'sort_values()' 方法也有一个 'key' 参数,但它接受一个 'Series' 对象并返回相同的对象。
不会出现简单的排序问题。例如,这些键分别工作:
df.sort_values('ATTRIBUTE_NAME', key=lambda x: -x.str.endswith('Count'))
df.sort_values('ATTRIBUTE_NAME', key=lambda x: x.str.len())
但现在不可能组合这些键。我想出了一种笨拙的方式来接受和返回“系列”对象的键:
def multi_sort(s):
l = sorted(s.items(), key=lambda x: (-x[1].endswith('Count'), len(x[1]), x[1]))
return pd.Series(dict(l))
df.sort_values('ATTRIBUTE_NAME', key=multi_sort)
但是这种排序给了我一个我不清楚的结果:
'''
ATTRIBUTE_NAME
4 Program_Fail_Count
15 Offline_Uncorrectable
0 Raw_Read_Error_Rate
5 Erase_Fail_Count
6 Ave_Block-Erase_Count
7 Unexpect_Power_Loss_Ct
14 Current_Pending_Sector
18 Write_Error_Rate
1 Reallocate_NAND_Blk_Cnt
9 SATA_Interfac_Downshift
2 Power_On_Hours
12 Temperature_Celsius
19 Success_RAIN_Recov_Cnt
8 Unused_Reserve_NAND_Blk
11 Reported_Uncorrect
20 Total_Host_Sector_Write
16 UDMA_CRC_Error_Count
13 Reallocated_Event_Count
21 Host_Program_Page_Count
3 Power_Cycle_Count
17 Percent_Lifetime_Remain
22 FTL_Program_Page_Count
10 Error_Correction_Count
帮我弄清楚并告诉我是否有一种方法可以按几个键排序,因为它是在“sorted()”函数中实现的?
UPD。
感谢@strawdog 的帮助,我设法了解了在按多个键对列进行排序时如何使用key该方法sort_values(),这要感谢他:
df = df.sort_values(by="ATTRIBUTE_NAME",
key=lambda s: s.map(lambda x: (-x.endswith("Count"), len(x), x)))
我建议这样做:
在显示最终结果之前,您可以删除上面一行中的 drop 方法,以查看创建了什么列以及框架是如何排序的。
有一个较短的版本具有相同的结果:
我们得到 df (或 res,取决于选项):