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]})

image

对于上边这个dataframe,先按字段mid顺序排序,如果mid值相同,再用gene字段按ascii值不区分字母大小写顺序排序


解决方案

方案一(会区分大小写,不适用):

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

image

方案二 (大量数据时,并不会根据gene字段排序)

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

image

用真实数据做如下测试,发现不满足需求

image

方案三 (满足需求)

对于方案一,唯一的问题是会区分字母小大写,所以多方案一进行优化,做如下改动

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

image

直接这样执行会出错,分析原因:

  • 是因为gene是字符串类型,调用.str.lower()是没问题,但是mid是数值类型,调用.str.lower()会有问题
    image

解决异常:

  • 我们只对字符串类型的做大小写准换,对数值类型不处理。
def str2lower(sr):
    try:
        return sr.str.lower()
    except:
        return sr

修改上边的代码

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

image

在真实数据测试

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

image
先按MIDcount的值顺序排序,再根据gene的值不区分字母大小写顺序数据,满足需求。(在这里看到的gene值全都是数字开头是因为数据太大,只输出了前5个元素)

posted @ 2022-12-05 18:18  一枚码农  阅读(212)  评论(0编辑  收藏  举报