使用python比较单个文件中的行

使用python比较单个文件中的行,python,loops,python-2.7,Python,Loops,Python 2.7,我有一个文本文件,其中包含空格分隔的数据,如下所示: aaa bbb 10 aaa bbb 5 aaa bbb 6 aaa bbb 2 aaa ccc 4 aaa ccc 11 aaa ccc 7 aaa ddd 9 aaa ddd 13 aaa ddd 12 aaa ddd 19 xxx yyy 20 xxx yyy 4 xxx yyy 6 xxx yyy 8 xxx yyy 12 xxx zzz 10 xxx zzz 11 xxx zzz 4 xxx zzz 5 xxx zzz 6 我不知

我有一个文本文件,其中包含空格分隔的数据,如下所示:

aaa bbb 10
aaa bbb 5
aaa bbb 6
aaa bbb 2
aaa ccc 4
aaa ccc 11
aaa ccc 7
aaa ddd 9
aaa ddd 13
aaa ddd 12
aaa ddd 19
xxx yyy 20
xxx yyy 4
xxx yyy 6
xxx yyy 8
xxx yyy 12
xxx zzz 10
xxx zzz 11
xxx zzz 4
xxx zzz 5
xxx zzz 6
我不知道如何用文字来解释,但我想把数值最大的行写入一个单独的文件

输出应该如下所示:

aaa bbb 10
aaa ccc 11
aaa ddd 19
xxx yyy 20
xxx zzz 11
这里有一些代码我已经尝试过了,但是没有成功

for line in r.readlines()[1:]:
    z = re.split(' ', line)
    a = []
    a.append(z)
    for i in xrange(len(a)):
        if z[0] == a[i][0] and z[1] == a[i][1]:
            if z[7] > a[i][7]:
               del a[i]
               a.append(z)
    for x in a:
    p.write(' '.join(x))
我最初在问题中没有明确说明这一点(我尽量不透露太多关于我正在处理的数据的信息),但在这个文件中有8个“列”。前三个是字母数字,第四个是整数,最后四个是浮点。我需要使用最后一列(浮点)作为最大值。对不起

另一个解决方案

allLines = r.readlines()

bestOf = re.split(' ', allLines[1])

f = open("results_filtered.txt", 'a')
for line in allLines[2:]:
   z = re.split(' ', line)
   if z[0] == bestOf[0] and z[1] == bestOf[1]:
       # match, compare signals
       if z[7] > bestOf[7]:
           bestOf = z
   else:
        # no match, next set
    f.write(' '.join(bestOf))
    bestOf = z

如果您有许多字段,那么值得使用pandas(这里
data
是您的文本示例):

复制第二列用于测试

>>> df[3]=df[2]
按所需列分组(本例中的前两列)

并计算最大值

>>> gb.max().reset_index()
     0    1   2   3
0  aaa  bbb  10  10
1  aaa  ccc  11  11
2  aaa  ddd  19  19
3  xxx  yyy  20  20
4  xxx  zzz  11  11

如果您有许多字段,那么值得使用pandas(这里
data
是您的文本示例):

复制第二列用于测试

>>> df[3]=df[2]
按所需列分组(本例中的前两列)

并计算最大值

>>> gb.max().reset_index()
     0    1   2   3
0  aaa  bbb  10  10
1  aaa  ccc  11  11
2  aaa  ddd  19  19
3  xxx  yyy  20  20
4  xxx  zzz  11  11

如果未对行进行排序,请使用字典跟踪最大值或跟踪最大值:

from collections import defaultdict

maxima = defaultdict(int)

with open(inputfilename, 'r') as ifh:
    for line in ifh:
        key, value = line.rsplit(None, 1)
        value = int(value)
        if value > maxima[key]:
            maxima[key] = value

with open(outputfilename, 'w') as ofh:
    for key in sorted(maxima):
        ofh.write('{} {}\n'.format(key, maxima[key])
一本普通字典也行;您应该使用
maxima={}
if value>maxima.get(键,0):

在上面的示例代码中,我使用分隔两个单词的行中的最后一个空格进行拆分;这确保我们只获取行末尾的整数值。该行的其余部分用作键

如果“键”仅取自部分线,则进一步拆分线,并存储最大值和线。如果这些值实际上是浮动的,那么您可能希望以
float('-inf')
作为该键到目前为止的“最大值”开始:

from collections import defaultdict

maxima = defaultdict(lambda: (float('-inf'), ''))

with open(inputfilename, 'r') as ifh:
    for line in ifh:
        columns = line.rsplit(None, 1)
        key = tuple(columns[:2])    # first two columns are the key
        value = float(columns[-1])  # last column is the value
        if value > maxima[key][0]:
            maxima[key] = (value, line)

with open(outputfilename, 'w') as ofh:
    for key in sorted(maxima):
        # write the tracked lines
        ofh.write(maxima[key][1])

现在,每个键都存储最大值和具有该最大值的整行。选择什么样的钥匙取决于你自己;我选择了前两列。

如果行未排序,请使用字典跟踪最大值或跟踪最大值:

from collections import defaultdict

maxima = defaultdict(int)

with open(inputfilename, 'r') as ifh:
    for line in ifh:
        key, value = line.rsplit(None, 1)
        value = int(value)
        if value > maxima[key]:
            maxima[key] = value

with open(outputfilename, 'w') as ofh:
    for key in sorted(maxima):
        ofh.write('{} {}\n'.format(key, maxima[key])
一本普通字典也行;您应该使用
maxima={}
if value>maxima.get(键,0):

在上面的示例代码中,我使用分隔两个单词的行中的最后一个空格进行拆分;这确保我们只获取行末尾的整数值。该行的其余部分用作键

如果“键”仅取自部分线,则进一步拆分线,并存储最大值和线。如果这些值实际上是浮动的,那么您可能希望以
float('-inf')
作为该键到目前为止的“最大值”开始:

from collections import defaultdict

maxima = defaultdict(lambda: (float('-inf'), ''))

with open(inputfilename, 'r') as ifh:
    for line in ifh:
        columns = line.rsplit(None, 1)
        key = tuple(columns[:2])    # first two columns are the key
        value = float(columns[-1])  # last column is the value
        if value > maxima[key][0]:
            maxima[key] = (value, line)

with open(outputfilename, 'w') as ofh:
    for key in sorted(maxima):
        # write the tracked lines
        ofh.write(maxima[key][1])

现在,每个键都存储最大值和具有该最大值的整行。选择什么样的钥匙取决于你自己;我选择了前两列。

您可以使用字典对喜欢的内容进行分组,然后使用
max
,最后一列上的键值转换为浮点值:

data='''\
aaa bbb 10 2.2
aaa bbb 5 3.3
aaa bbb 6 55
aaa bbb 2 6.66
aaa ccc 4 22
aaa ccc 11 35.5
aaa ccc 7 66
aaa ddd 9 .00001
aaa ddd 13 1e10
aaa ddd 12 1e-22
aaa ddd 19 22
xxx yyy 20 123456
xxx yyy 4 66.6666
xxx yyy 6 26
xxx yyy 8 35
xxx yyy 12 2e99
xxx zzz 10 45
xxx zzz 11 55
xxx zzz 4 65
xxx zzz 5 1
xxx zzz 6 12345'''

d={}

for line in data.splitlines():
    l=line.split()
    k=' '.join(l[0:2])      # select how many columns comprise a group
    d.setdefault(k,[]).append(line)

for k in sorted(d):
    max(d[k], key=lambda s: float(s.rsplit(' ',1)[1]))
印刷品:

aaa bbb 6 55
aaa ccc 7 66
aaa ddd 13 1e10
xxx yyy 12 2e99
xxx zzz 6 12345

您可以使用字典对喜欢进行分组,然后使用
max
,将最后一列上的键值转换为浮点值:

data='''\
aaa bbb 10 2.2
aaa bbb 5 3.3
aaa bbb 6 55
aaa bbb 2 6.66
aaa ccc 4 22
aaa ccc 11 35.5
aaa ccc 7 66
aaa ddd 9 .00001
aaa ddd 13 1e10
aaa ddd 12 1e-22
aaa ddd 19 22
xxx yyy 20 123456
xxx yyy 4 66.6666
xxx yyy 6 26
xxx yyy 8 35
xxx yyy 12 2e99
xxx zzz 10 45
xxx zzz 11 55
xxx zzz 4 65
xxx zzz 5 1
xxx zzz 6 12345'''

d={}

for line in data.splitlines():
    l=line.split()
    k=' '.join(l[0:2])      # select how many columns comprise a group
    d.setdefault(k,[]).append(line)

for k in sorted(d):
    max(d[k], key=lambda s: float(s.rsplit(' ',1)[1]))
印刷品:

aaa bbb 6 55
aaa ccc 7 66
aaa ddd 13 1e10
xxx yyy 12 2e99
xxx zzz 6 12345

因此,假设您需要最左边的三列是您的标识符,这应该可以工作:

f = open("test.txt", 'r')
lines = f.readlines()
f.close()

identifiers = set([' '.join(line.split()[0:2]) for line in lines])
output = []

for identifier in identifiers:
    output.append((' '.join(line.split()[:-1], max([float(line.split()[-1]) for line in lines if ' '.join(line.split()[0:2]) == identifier])))

f = open("newFile.txt", 'w')
for item in output:
    f.write("{} {}\n".format(item[0],item[1]))
f.close()

因此,假设您需要最左边的三列是您的标识符,这应该可以工作:

f = open("test.txt", 'r')
lines = f.readlines()
f.close()

identifiers = set([' '.join(line.split()[0:2]) for line in lines])
output = []

for identifier in identifiers:
    output.append((' '.join(line.split()[:-1], max([float(line.split()[-1]) for line in lines if ' '.join(line.split()[0:2]) == identifier])))

f = open("newFile.txt", 'w')
for item in output:
    f.write("{} {}\n".format(item[0],item[1]))
f.close()

下面的shell命令是否满足您的要求

sort -nk3 $filename | tail
这是上面的演示数据,并给出:

aaa ccc 11
xxx zzz 11
aaa ddd 12
xxx yyy 12
aaa ddd 13
aaa ddd 19
xxx yyy 20
(当然,用文件名替换
$filename


对于您提到的8列版本,只需将
k3
替换为
k8
,或者替换您需要的任何列号…

以下shell命令是否满足您的需要

sort -nk3 $filename | tail
这是上面的演示数据,并给出:

aaa ccc 11
xxx zzz 11
aaa ddd 12
xxx yyy 12
aaa ddd 13
aaa ddd 19
xxx yyy 20
(当然,用文件名替换
$filename


对于您提到的8列版本,只需将
k3
替换为
k8
,或您需要的任何列编号…

无需使用任何外部库或任何max函数。最简单的方法是使用前两个项作为字典的索引,并在读取中的数据时更新字典中的项(如果该项大于现有项)

output_dict = {} with open(input_file, 'r') as input: for row in input: id, value = row.rsplit(' ', 1) value = int(value) if id not in output_dict or value > output_dict[id]: output_dict[id] = value with open(output_file, 'w') as output: for id in output_dict: output.write('{0} {1}\n'.format(id, output_dict[id])) 输出_dict={} 打开(输入_文件,'r')作为输入: 对于输入中的行: id,value=row.rsplit(“”,1) value=int(值) 如果id不在输出目录或值>输出目录[id]: 输出dict[id]=值 将打开的(输出_文件,'w')作为输出: 对于输出目录中的id: output.write('{0}{1}\n'.格式(id,output_dict[id]))
用文件路径替换“input_file”和“output_file”,这将按原样工作,并且应该相对容易理解。对于包含浮点数的数据,您可以将“int”替换为“float”,它应该仍然有效。

无需使用任何外部库或任何max函数。最简单的方法是使用前两个项作为字典的索引,并在读取中的数据时更新字典中的项(如果该项大于现有项)

output_dict = {} with open(input_file, 'r') as input: for row in input: id, value = row.rsplit(' ', 1) value = int(value) if id not in output_dict or value > output_dict[id]: output_dict[id] = value with open(output_file, 'w') as output: for id in output_dict: output.write('{0} {1}\n'.format(id, output_dict[id])) 输出_dict={} 打开(输入_文件,'r')作为输入: 对于输入中的行: id,value=row.rsplit(“”,1) value=int(值) 如果id不在输出目录或值>输出目录[id]: 输出dict[id]=值 将打开的(输出_文件,'w')作为输出: 对于输出目录中的id: output.write('{0}{1}\n'.格式(id,output_dict[id]))
用文件路径替换“input_file”和“output_file”,这将按原样工作,并且应该相对容易理解。对于包含浮点数的数据,可以将“int”替换为“float”,并且应该仍然有效。

此解决方案假定要比较的行被分组在一起

allLines = r.readlines()
bestOf = re.split(' ', allLines)
f = open("output.txt", 'w')
for line in allLines[2:]:
    z = re.split(' ', line)
    if z[0] == bestOf[0] and z[1] == bestOf[1]:
        # match, compare values
        if z[7] > bestOf[7]:
            bestOf = z
    else:
        # no match, next set
        f.write(bestOf)
        bestOf = z
与选择排序算法类似,如果行更好