我正在寻找一种加速代码的方法。我设法加快了代码的大部分时间,将运行时间减少到大约10个小时,但它仍然不够快,因为我已经没时间了,我正在寻找一种快速优化代码的方法。
示例:
text = pd.read_csv(os.path.join(dir,"text.csv"),chunksize = 5000)
new_text = [np.array(chunk)[:,2] for chunk in text]
new_text = list(itertools.chain.from_iterable(new_text))
在上面的代码中,我以大块的形式阅读了大约600万行文本文档并将它们展平。此代码大约需要3-4个小时才能执行。这是我的计划的主要瓶颈。 编辑:我意识到我不清楚主要问题是什么,扁平化是需要花费大量时间的部分。
此程序的这部分还需要很长时间:
train_dict = dict(izip(text,labels))
result = [train_dict[test[sample]] if test[sample] in train_dict else predictions[sample] for sample in xrange(len(predictions))]
上面的代码首先使用相应的标签来压缩文本文档(这是一个机器学习任务,train_dict是训练集)。在程序的早期,我在测试集上生成了预测。我的火车和测试装置之间有重复,所以我需要找到那些重复的。因此,我需要逐行迭代我的测试集(总共200万行),当我发现重复时我实际上不想使用预测标签,而是来自train_dict中副本的标签。我将此迭代的结果分配给上面代码中的变量result。
我听说python中有各种库可以加速部分代码,但我不知道哪些可以完成这项工作而且知道我没有时间去调查这个,这就是为什么我需要有人指出我正确的方向。有没有办法可以加快上面的代码片段?
EDIT2
我再次调查过。这肯定是一个记忆问题。我尝试逐行读取文件,一段时间后速度急剧下降,此外我的ram使用率接近100%,而python的磁盘使用量急剧增加。如何减少内存占用?或者我应该找到一种方法来确保我不把所有东西都记在内存中?
EDIT3 由于记忆是我的问题的主要问题,我将概述我的程序的一部分。我暂时放弃了预测,这大大降低了程序的复杂性,而是在我的测试集中为每个非重复插入标准样本。
import numpy as np
import pandas as pd
import itertools
import os
train = pd.read_csv(os.path.join(dir,"Train.csv"),chunksize = 5000)
train_2 = pd.read_csv(os.path.join(dir,"Train.csv"),chunksize = 5000)
test = pd.read_csv(os.path.join(dir,"Test.csv"), chunksize = 80000)
sample = list(np.array(pd.read_csv(os.path.join(dir,"Samples.csv"))[:,2]))#this file is only 70mb
sample = sample[1]
test_set = [np.array(chunk)[:,2] for chunk in test]
test_set = list(itertools.chain.from_iterable(test_set))
train_set = [np.array(chunk)[:,2] for chunk in train]
train_set = list(itertools.chain.from_iterable(train_set))
labels = [np.array(chunk)[:,3] for chunk in train_2]
labels = list(itertools.chain.from_iterable(labels))
"""zipping train and labels"""
train_dict = dict(izip(train,labels))
"""finding duplicates"""
results = [train_dict[test[item]] if test[item] in train_dict else sample for item in xrange(len(test))]
虽然这不是我的整个程序,但这是我需要优化的代码的一部分。正如你所看到的,我只使用了这个部分中的三个重要模块,pandas,numpy和itertools。展平train_set和test_set时会出现内存问题。我唯一要做的就是读取文件,获取必要的部分,用字典中的相应标签压缩列车文档。然后搜索重复项。
编辑4 根据要求,我将解释我的数据集。我的Train.csv包含4列。第一列包含每个样本的ID,第二列包含标题,第三列包含文本正文样本(从100-700个单词变化)。第四列包含类别标签。 Test.csv仅包含ID和文本正文和标题。列以逗号分隔。
答案 0 :(得分:1)
您可以尝试Cython。它支持numpy,可以给你一个很好的加速。 以下是对需要完成的工作的介绍和解释 http://www.youtube.com/watch?v=Iw9-GckD-gQ
答案 1 :(得分:1)
请你发一个半打左右的虚拟样本数据集吗?
我不太清楚你的代码在做什么,我不是Pandas专家,但我认为我们可以大大加快这段代码的速度。它将所有数据读入内存,然后不断将数据重新复制到各个位置。
通过编写“懒惰”代码,我们应该能够避免所有重新复制。理想的是读取一行,根据需要进行转换,并将其存储到最终目的地。此代码也应该在迭代值时使用索引;我们也可以在那里加快速度。
您发布的代码是您的实际代码,还是您要发布的内容?它似乎包含一些错误,所以我不确定它实际上是做什么的。特别是,train
和labels
似乎包含相同的数据。
我会回来看看你是否发布了样本数据。如果是这样,我可能会为您编写“懒惰”代码,这将减少对数据的重新复制,并且速度会更快。
编辑:根据您的新信息,这是我的虚拟数据:
id,title,body,category_labels
0,greeting,hello,noun
1,affirm,yes,verb
2,deny,no,verb
以下是阅读上述内容的代码:
def get_train_data(training_file):
with open(training_file, "rt") as f:
next(f) # throw away "headers" in first line
for line in f:
lst = line.rstrip('\n').split(',')
# lst contains: id,title,body,category_labels
yield (lst[1],lst[2])
train_dict = dict(get_train_data("data.csv"))
这是构建results
的更快捷方式:
results = [train_dict.get(x, sample) for x in test]
我们只是迭代测试中的值,而不是重复索引test
来查找下一个项目。 dict.get()
方法处理我们需要的if x in train_dict
测试。
答案 2 :(得分:0)
如果您的行的顺序不重要,您可以使用集来查找列车集但不在测试集(交集列车集和测试集)中的元素,并将它们首先添加到您的“结果”中,之后使用集合差异(testset-trainset)用于添加测试集中但不在列车集中的元素。这样可以节省检查样品是否在火车组中。