如何在没有固定宽度领域组织的情况下对输入进行分类



我有一个.txt文件,其中包含:

Name | Email@example.com | Score
Name2 | Email2@madeupsite.com | Score 

其中Score是0到10亿的整数。

我想按得分从大到小的分数对此文件进行排序。我的问题是,由于名称和电子邮件是不同的长度,因此每次我可以访问它的分数并不是一致的位置。我将如何克服这个问题?

(我不太确定该如何说标题,所以我希望这个机构能更好地解释它;如果问题不清楚,请告诉我(


#a list to store your data, open the file to retrieve the data
data = []
with open( 'fname.txt' ) as f:
    for line in f:
        # line.split( '|' ) splits the string into a list separated by '|' )
        data.append( line.strip().split('|') )
# convert the scores into an integer
for d in data:
    d[2] = int( d[2] )
# sort the data using 2nd element of row from big to small
sorted_data = sorted( data, key=lambda x: return x[2], reverse=True )

在列表中有线条后,您可以使用sortsorted对其进行排序。诀窍将是传递一个钥匙,该钥匙可以拔出整数。一种选择是将切片从最后一个|到行的末端,并从该字符串中制作一个整数。rfind()对此很有帮助:

lines = ['Name | Email@example.com | 1001',
         'Name2 | Email2@madeupsite.com | 2',
         'Name2 | Email2@madeupsite.com | 200'
]
s = sorted(lines, key = lambda s: int(s[s.rfind('|')+1:]))
list(s)

结果:

['Name2 | Email2@madeupsite.com | 2',
 'Name2 | Email2@madeupsite.com | 200',
 'Name | Email@example.com | 1001']

首先,我们可以读取文件的行。接下来,我们使用列表理解来拆分分隔器" |"上的每一行,取最后一个索引,然后转换为整数进行排序。我们以相反的顺序排序并设置键,以便输出将是行索引,然后将lines_sorted设置为等于排序行的顺序。

with open("file.txt", "r") as f:
    lines = f.readlines()
    scores = [int(l.split("|")[-1]) for l in lines]
    sorted_idx = sorted(range(len(scores)), key=lambda k: scores[k], reverse=True)
    lines_sorted = [lines[i] for i in sorted_idx]

有关分类和返回索引的更多建议,请参见此问题。

示例包含以下内容的" file.txt":

Name | Email@example.com | 1000
Name2 | Email2@madeupsite.com | 10
Name3 | Email3@madeupsite.com | 100

lines_sorted将包含:

["Name | Email@example.com | 1000",
 "Name3 | Email3@madeupsite.com | 100", 
 "Name2 | Email2@madeupsite.com | 10"]

在每个字符串的rpartition上使用自定义排序键函数

输入:

lines = ['Name | Email@example.com | 50',
         'Name2 | Email2@madeupsite.com | 400',
         'Name3 | Email2@madeupsite.com | 15']

输出:

sorted(lines, key=lambda x: int(x.rpartition('|')[-1]))
Out[1128]:
['Name3 | Email2@madeupsite.com | 15',
 'Name | Email@example.com | 50',
 'Name2 | Email2@madeupsite.com | 400']

您的输入数据是PSV(管道分离值(。您可以使用pandas.read_csv with sep='|'阅读:

dat = """
Name1 | Email@example.com | 456
Name2 | Email2@madeupsite.com | 123 
Name44 | jimmy@yahoo.co.ar | 79
"""
import pandas as pd
df = pd.read_csv(pd.compat.StringIO(dat), sep='|', header=None)
df.sort_values(2, ascending=True)
         0                        1    2
2  Name44        jimmy@yahoo.co.ar    79
1   Name2    Email2@madeupsite.com   123
0   Name1        Email@example.com   456

相关内容

最新更新