假设我们有一个包含行的大文件,如下所示
ID value string
1 105 abc
1 98 edg
1 100 aoafsk
2 160 oemd
2 150 adsf
...假设该文件名为file.txt,并由选项卡分隔。
我希望保留每个ID的最大值。
ID value string
1 105 abc
2 160 oemd
...我如何按块读取并处理数据?如果我以块的形式读取数据,如何确保在每个块的末尾完成每个ID的记录?
发布于 2016-10-26 22:24:55
在这种格式的字典中跟踪数据:
data = {
ID: [value, 'string'],
}当您从文件中读取每一行时,请查看该ID是否已经在dict中。如果没有,则添加它;如果是,并且当前ID更大,则在dict中替换它。
最后,你的白痴应该有所有最大的身份证。
# init to empty dict
data = {}
# open the input file
with open('file.txt', 'r') as fp:
# read each line
for line in fp:
# grab ID, value, string
item_id, item_value, item_string = line.split()
# convert ID and value to integers
item_id = int(item_id)
item_value = int(item_value)
# if ID is not in the dict at all, or if the value we just read
# is bigger, use the current values
if item_id not in data or item_value > data[item_id][0]:
data[item_id] = [item_value, item_string]
for item_id in data:
print item_id, data[item_id][0], data[item_id][1]字典不强制对其内容进行任何特定的排序,因此在程序结束时,当您将数据从字典中取出时,它可能与原始文件的顺序不同(例如,您可能首先看到ID 2,然后是ID 1)。
如果这对您很重要,您可以使用OrderedDict,它保留了元素的原始插入顺序。
(当你说“分块阅读”的时候,你有什么特别的想法吗?如果您指的是特定数量的字节,那么如果块边界恰好落在一个单词的中间,则可能会遇到问题.)
发布于 2017-09-19 13:34:26
码
import csv
import itertools as it
import collections as ct
with open("test.csv") as f:
reader = csv.DictReader(f, delimiter=" ") # 1
for k, g in it.groupby(reader, lambda d: d["ID"]): # 2
print(max(g, key=lambda d: float(d["value"]))) # 3
# {'value': '105', 'string': 'abc', 'ID': '1'}
# {'value': '160', 'string': 'oemd', 'ID': '2'}详细信息
with块确保文件f的安全打开和关闭。该文件是可迭代的,允许您循环它或理想地应用itertools。
f的每一行,csv.DictReader拆分数据并将头行信息维护为字典的键值对,例如[{'value': '105', 'string': 'abc', 'ID': '1'}, ...。groupby,ID对所有数据进行块处理。见how groupby works。max()内置与一个特殊的键函数相结合,返回具有最大"value"的dicts。见 function。https://stackoverflow.com/questions/40272817
复制相似问题