我正在尝试在Python中导入大型文件(.tab / .txt,300多个列和1000万以上的行)。该文件以制表符分隔。这些列填充有整数值。我的目标之一是对每一列求和。但是,文件太大,无法使用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列就需要花费很长时间。
我的问题:是否有一种更快的方法来仅导入此大选项卡文件的一列,并执行与上述代码相同的计算?
答案 0 :(得分:3)
您可以尝试以下操作:
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, ...}
我不确定这是否行得通,因为我不知道您输入文件的内容,但是它描述了一般过程。您只打开文件一次,遍历每一行,拆分以获取列,然后存储所需的数据。 请注意,此代码不会处理缺少的值。
可以使用numpy来改善else
块:
import numpy as np
...
else:
sums = np.add(sums, map(float,columns))