读取csv而不使用行枚举列,并使用自定义键进行排序

2024-05-13 05:18:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个TSV文件,我想读取它,按特定列排序并将其写回。
我遇到的两个问题是:

  • 提供自定义键会导致错误(我将在文章末尾显示回溯)
  • 在不提供自定义密钥的情况下,将完成排序。但是,当我将数据帧写回TSV文件时,有另一列表示我要删除的行编号

我尝试以以下方式使用pandas模块:

import re
import pandas as pd

def natural_sort_key(s, _nsre=re.compile('([0-9]+)')):
    return [int(text) if text.isdigit() else text.lower() for text in _nsre.split(s)]

def main(path):
    with open(path, 'r') as f:
        df = pd.read_csv(path, delimiter='\t')

        a = df.sort_values('#mm10.kgXref.geneSymbol', key=natural_sort_key, na_position='first')
        a.to_csv('mouse_conversion_by_gene_symbol', sep='\t')

if __name__ == '__main__':
    main('mouse_conversion')

我在提供自定义密钥后得到的回溯是:

Traceback (most recent call last):
  File "sortTables.py", line 22, in <module>
    main('mouse_conversion')
  File "sortTables.py", line 12, in main
    a = df.sort_values('#mm10.kgXref.geneSymbol', key=natural_sort_key, na_position='first')
  File "/home/eliran/miniconda/envs/newenv/lib/python3.7/site-packages/pandas/core/frame.py", line 5297, in sort_values
    k, kind=kind, ascending=ascending, na_position=na_position, key=key
  File "/home/eliran/miniconda/envs/newenv/lib/python3.7/site-packages/pandas/core/sorting.py", line 287, in nargsort
    items = ensure_key_mapped(items, key)
  File "/home/eliran/miniconda/envs/newenv/lib/python3.7/site-packages/pandas/core/sorting.py", line 420, in ensure_key_mapped
    result = key(values.copy())
  File "sortTables.py", line 6, in natural_sort_key
    return [int(text) if text.isdigit() else text.lower() for text in _nsre.split(s)]
TypeError: expected string or bytes-like object

至于第二个问题,这里有一个例子:
对于此输入:

#mm10.kgXref.geneSymbol mm10.kgXref.refseq  mm10.knownToEnsembl.name
Rp1 NM_011283   ENSMUST00000027032.5
Gm37483     ENSMUST00000194382.1
Sox17   NM_011441   ENSMUST00000027035.9

我得到以下输出:

#mm10.kgXref.geneSymbol mm10.kgXref.refseq  mm10.knownToEnsembl.name
19    Rp1   NM_011283   ENSMUST00000027032.5
21    Gm37483       ENSMUST00000194382.1
29    Sox17    NM_011441    ENSMUST00000027035.9

我想删除带有行枚举的列。
希望您能对这两个问题有所了解

编辑:在文档中找到有关枚举问题的答案。 如果这与其他人有关,只需使用:

a.to_csv('mouse_conversion_by_gene_symbol', sep='\t', index=False)

而不是原来的行

编辑2:在实现建议的解决方案后,我能够按第一列和最后一列对数据帧进行排序。
当我尝试按第二列对数据帧进行排序时,我从上面得到了完全相同的回溯。
我看到的唯一逻辑区别是第二列包含NaN值,而其他列不包含。
如何修改代码以解决此问题


Tags: keytextinpypandas排序mainline
2条回答
with open("test.tsv","r") as f:
    table=[[b,a,c] for [a,b,c] in [r.split('\t') for r in f.read().split('\n')] ]
table.sort()
with open("output.tsv","w") as f:
    f.write('\n'.join(['\t'.join([a,b,c]) for [b,a,c] in table]))

如果没有熊猫,您可以使用上面的python代码对test.tsv中的数据进行排序,并写入output.tst
此程序基于第二列进行排序。要根据其他列进行排序,请相应更改第2行和第5行。例如,如果要根据第三列进行排序,请将两行中的[b,a,c]更改为[c,a,b],使“要排序的列”成为列表中的第一列

根据docs key func应获取并给出一个系列(顺便说一句,pd.read\u csv不需要打开),因此请尝试以下操作:

import re
import pandas as pd

def natural_sort_key(S, _nsre=re.compile('([0-9]+)')):
    return pd.Series([[int(text) if text.isdigit() else text.lower() for text in _nsre.split(s)] for s in S.values])

def main(path):
    df = pd.read_csv(path, delimiter='\t')

    a = df.sort_values('#mm10.kgXref.geneSymbol', key=natural_sort_key, na_position='first')
    a.to_csv('mouse_conversion_by_gene_symbol', sep='\t')

if __name__ == '__main__':
    main('mouse_conversion')

相关问题 更多 >