我有一个文本文件,其中包含空格分隔数据,如下所示:
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
答案 0 :(得分:2)
如果未对行进行排序,请使用字典或collections.defaultdict
跟踪最大值以跟踪最大值:
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(key, 0):
代替。
在上面的示例代码中,我使用str.rsplit()
来分割分隔两个单词的行中的最后一个空格;这可以确保我们在行尾抓取只整数值。该行的其余部分用作键。
如果'key'仅取自该行的 part ,则进一步拆分该行,并存储最大值和行。如果值确实是浮点数,那么到目前为止,您可能希望以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])
现在,每个键都存储了具有该最大值的最大值和。你选择一把钥匙取决于你;我选了前两列。
答案 1 :(得分: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
答案 2 :(得分:1)
因此,假设您需要最左边的三列是您的标识符,这应该有效:
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()
答案 3 :(得分:0)
如果你有很多字段,那么值得使用pandas(这里data
是你的样本文本):
>>> import pandas as pd
>>> from StringIO import StringIO
>>> df = pd.read_csv(StringIO(data),sep=' ',header=None)
复制第二列用于测试目的
>>> df[3]=df[2]
按需要的列分组(本例中的前两个)
>>> gb = df.groupby([0,1])
并计算最大值
>>> 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
答案 4 :(得分:0)
以下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
,或将您需要的任何列号替换为...
答案 5 :(得分:0)
无需使用任何外部库或任何最大功能。最简单的方法是使用前两个项作为字典的索引,如果在读取数据时大于现有项,则更新该字典中的项。
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]))
将'input_file'和'output_file'替换为文件路径,这将按原样运行,并且应该相对容易理解。对于包含浮点数的数据,可以将'int'替换为'float',它仍然可以工作。
答案 6 :(得分:0)
此解决方案假定要比较的行组合在一起
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
与选择排序算法类似,如果线条优于当前最佳线条,请改为使用线条。当前两个元素不匹配时,假设我们已经移动到另一个组并将之前的最佳元素写入文件。