1. 程式人生 > 其它 >dataframe 多欄位排序

dataframe 多欄位排序

需求:

import pandas as pd

    df = pd.DataFrame(
        {'gene': ['BC061237', 'Gm19965', 'Afdvwef', 'Vafsx', '4930599A14Rik', 'am45766'],
         'mid': [2, 2, 5, 7, 2, 2],
         'count': [3, 6, 2, 7, 3, 3]})

對於上邊這個dataframe,先按欄位mid順序排序,如果mid值相同,再用gene欄位按ascii值不區分字母大小寫順序排序


解決方案

方案一(會區分大小寫,不適用):

df.sort_values(by=['mid', 'gene'])

方案二 (大量資料時,並不會根據gene欄位排序)

df.sort_values('gene', key=lambda x: x.str.lower()).sort_values('mid')

用真實資料做如下測試,發現不滿足需求

方案三 (滿足需求)

對於方案一,唯一的問題是會區分字母小大寫,所以多方案一進行優化,做如下改動

df.sort_values(by=['mid', 'gene'], key=lambda x: x.str.lower())

直接這樣執行會出錯,分析原因:

  • 是因為gene是字串型別,呼叫.str.lower()是沒問題,但是mid是數值型別,呼叫.str.lower()會有問題

解決異常:

  • 我們只對字串型別的做大小寫準換,對數值型別不處理。
def str2lower(sr):
    try:
        return sr.str.lower()
    except:
        return sr

修改上邊的程式碼

df.sort_values(by=['mid', 'gene'], key=str2lower)

在真實資料測試

r = gene_table.sort_values(by=['MIDcount', 'gene'], key=str2lower)
r[:5]


先按MIDcount的值順序排序,再根據gene的值不區分字母大小寫順序資料,滿足需求。(在這裡看到的gene值全都是數字開頭是因為資料太大,只輸出了前5個元素)