【问题标题】:iterating through a file with millions of lines遍历具有数百万行的文件
【发布时间】:2014-05-18 00:48:18
【问题描述】:

我正在尝试遍历一个包含数百万行包含一些数据的文件,并且我正在检索它。不幸的是,这进展得很慢,我想知道如何让它更有效率。 目前我正在加载两个文件,并且每行都在迭代。

代码:

# Retrieve session data
UBList = array([line.split('\t') for line in source])
SID = set(UBList[:,1])
n_unique_sessions = len(Counter(UBList[:,1]))
source.close()
sessions = {}
session_info = {}
purchases = array([line.split('\t') for line in open('Data/order_overview.txt', 'r').readlines()])

for sid in SID:
    print sid
    s = [line for line in UBList if line[1]==sid]
    uline = [line for line in s if line[3]=='17']
    tline = [line[2] for line in s]
    t_format = "%Y-%m-%d %H:%M:%S.%f"
    s_start = datetime.strptime(tline[0], t_format)
    s_end = datetime.strptime(tline[-1], t_format)
    s_length = (s_end - s_start).total_seconds()
    d_time = [line[2] for line in s if line[3]=='4']
    if len(uline) > 0: 
        uid = uline[0][12]
    else: 
        uid = 'NotFound'
    num_queries = len([line for line in s if line[3]=='27'])
    num_purchases = nonzero(purchases[:,0]==sid)[0].shape[0]
    sessions.update({sid: (uid, num_queries, num_purchases, s)})
    f = open('Results/' + sid + '_' + uid + '_' + str(num_queries) + '_' + str(num_purchases) + '_' + str(s_length) + '.txt', 'w')
    f.writelines(['\t'.join(line) for line in s])
    f.close()

这样的事情会加快速度吗?

somevar = dict([sid, [] for sid in SID])
for line in UBList:
sid = line[1]
dSID[sid].append('\t'.join(line))

还可以在满足特定条件后获取下一行吗?例如,我发现一条线用下一条获取它的值并进行计算。如果多次找到符合条件的行,则添加结果。

【问题讨论】:

  • 我觉得这个问题更适合codereview.stackexchange.com
  • 是啊,我试试你说的缓存UBList,用csvreader(docs.python.org/2/library/csv.html)读取文件,说明你的分隔符是制表符(\t) 例子有点让我理解那里发生的事情并提供更明确的答案很复杂。
  • 我认为arraynumpy模块中的函数。你能描述一下source 中的行的结构吗?我认为您在使用 numpy 对象时存在几个错误
  • @eyquem 源代码中的每一行都是制表符分隔的字符串。所以每行都像 abc [tab] def [tab] 123 [tab] 456 等等。 BorrajaX:所以不是存储 UBList 而是逐行读取?我是否应该将数据存储在 csv 文件中?我当前的数据在一个 txt 文件中。
  • array 是不是 numpy.array 方法?如果不是,我不会理解 UBList[:,1] 中带有逗号的文字

标签: python loops large-files


【解决方案1】:

如果source 是您的文件对象,请不要事先将其全部读入内存。您可以同时处理和读取,Python 足够聪明,可以在等待读取下一个块的同时处理数据。为此,请使用列表生成器,而不是列表推导。

您创建了很多实际上并不需要的数组,例如s。用生成器替换它们并获得加速。创建标准 Python 数组是一项繁重的操作,如果它大于 4kB,生成器应该会更好。

【讨论】:

  • 所以我应该阅读并处理它而不是存储它?使用类似 while open(source) do .....
猜你喜欢
  • 1970-01-01
  • 2011-03-05
  • 2011-01-04
  • 2018-12-21
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-29
相关资源
最近更新 更多