【问题标题】:What is a more efficient way to load 1 column with 1 000 000+ rows than pandas read_csv()?与 pandas read_csv() 相比,加载 1 000 000+ 行的 1 列更有效的方法是什么?
【发布时间】:2019-06-20 12:04:25
【问题描述】:

我正在尝试在 Python 中导入大文件(.tab/.txt、300 多列和 1 000 000 多行)。该文件是制表符分隔的。这些列用整数值填充。我的目标之一是对每一列求和。但是,文件太大而无法使用 pandas.read_csv() 导入,因为它消耗了太多 RAM。 样本数据:

因此,我编写了以下代码来导入 1 列,对该列进行求和,将结果存储在数据框 (= summed_cols) 中,删除该列,然后继续处理文件的下一列:

x=10 ###columns I'm interested in start at col 11

#empty dataframe to fill
summed_cols=pd.DataFrame(columns=["sample","read sum"])

while x<352:
    x=x+1
    sample_col=pd.read_csv("file.txt",sep="\t",usecols=[x])
    summed_cols=summed_cols.append(pd.DataFrame({"sample":[sample_col.columns[0]],"read sum":sum(sample_col[sample_col.columns[0]])}))
    del sample_col

每一列代表一个样本,“读取总和”是该列的总和。所以这段代码的输出是一个有 2 列的数据帧,第一列每行一个样本,第二列是相应的读取总和。

这段代码完全符合我的要求,但是效率不高。对于这个大文件,完成计算大约需要 1-2 小时。尤其是仅加载 1 列需要很长时间。

我的问题:有没有更快的方法来导入这个大标签文件的一列,并执行与上面代码相​​同的计算?

【问题讨论】:

  • 为什么不用pandas内置求和函数
  • 我不确定它是否会更快,但是如果你只需要列 sum 用 python 逐行读取文件并累加总和会不会更容易?跨度>
  • @Robvh 数据框的内置函数会比求和函数 sample_cols['amount'].sum() 快得多
  • @Robvh 我认为这里的问题是 OP 正在打开文件并在每次迭代时生成一个 DataFrame。确实,sum() 内置的 pandas 速度更快。但在这种情况下,它并没有多大帮助。代码需要彻底重新设计。

标签: python pandas dataframe


【解决方案1】:

你可以试试这样的:

samples = []
sums = []

with open('file.txt','r') as f:
    for i,line in enumerate(f):
        columns = line.strip().split('\t')[10:] #from column 10 onward
        if i == 0: #supposing the sample_name is the first row of each column
            samples = columns #save sample names
            sums = [0 for s in samples] #init the sums to 0
        else:
            for n,v in enumerate(columns):
                sums[n] += float(v)

result = dict(zip(samples,sums)) #{sample_name:sum, ...}

我不确定这是否可行,因为我不知道您输入文件的内容,但它描述了一般过程。您只打开一次文件,遍历每一行,拆分以获取列,并存储您需要的数据。 请注意,此代码不处理缺失值。

else 块可以使用 numpy 进行改进:

import numpy as np
...
else:
    sums = np.add(sums, map(float,columns))

【讨论】:

  • 感谢您的代码!我会尽快尝试的。我希望我没有对您要求太多,但是您可以在每行之后添加 cmets 吗?由于我对 Python 比较陌生,我无法 100% 遵循代码,我想尽可能多地学习。
  • @Robvh 我已经评论了必要的内容。代码可读性很强有什么不清楚的地方?
  • 字典有键:值对,而不是列。在您的情况下,字典应该类似于 {'sample1':123, 'sample2':99, ...} typesize 是键还是值?如果您可以输入 2-3 行输入文件,我可以相应地修复代码,不知道文件格式是不可行的。
  • 嗯,没关系。无论如何,答案作为一般方法是有效的。你有一个有效的代码,这才是最重要的。
猜你喜欢
  • 1970-01-01
  • 2021-06-26
  • 1970-01-01
  • 1970-01-01
  • 2020-01-08
  • 1970-01-01
  • 1970-01-01
  • 2014-04-10
  • 2022-11-19
相关资源
最近更新 更多