加载一个非常大的 txt 文件并进行转置
Posted
技术标签:
【中文标题】加载一个非常大的 txt 文件并进行转置【英文标题】:Loading a very large txt file and taking transpose 【发布时间】:2016-04-13 16:15:09 【问题描述】:我有一个制表符分隔的 .txt 文件,将数字保存为矩阵。行数为 904,652,列数为 26,600(制表符分隔)。该文件的总大小约为 48 GB。我需要将此文件加载为矩阵并采用矩阵的转置来提取训练和测试数据。我正在使用 Python、pandas 和 sklearn
包。我运行 500GB 内存服务器,但用 pandas 包加载它是不够的。谁能帮我解决我的问题?
加载代码部分如下:
def open_with_pandas_read_csv(filename):
df = pandas.read_csv(filename, sep=csv_delimiter, header=None)
data = df.values
return data
【问题讨论】:
我添加了将文件加载到内存中的代码部分。我相信应该有一个预处理部分来在加载之前减小文件的大小。 你需要什么数据类型float64
,或者int32
或者别的什么?
矩阵不是稀疏的吗?你里面有很多0吗?这也可能有用:pandas.pydata.org/pandas-docs/stable/…
是的,它是一个稀疏矩阵。你有什么建议?
【参考方案1】:
在我看来,您正在研究基因数据。如果是这样,考虑使用 --transpose 和 plink,它非常快:http://pngu.mgh.harvard.edu/~purcell/plink/dataman.shtml#recode
【讨论】:
【参考方案2】:我在 *** 上找到了一个解决方案(我相信还有更有效和更合乎逻辑的解决方案)。 np.fromfile()
方法比np.loadtxt()
和np.genfromtxt()
甚至pandas.read_csv()
更有效地加载大文件。在没有任何修改或压缩的情况下,它只花了大约 274 GB。我感谢所有试图在这个问题上帮助我的人。
【讨论】:
【参考方案3】:它是一个文本文件的事实使它有点困难。作为第一步,我会从中创建一个二进制文件,其中每个数字占用恒定的字节数。它可能还会减小文件大小。
然后,我会进行多次传递,并且在每次传递中,我会在输出文件中写入 N 行。
伪代码:
transposed_rows = [ [], .... , [] ] # length = N
for p in range(columns / N):
for row in range(rows):
x = read_N_numbers_from_row_of_input_matrix(row,pass*N)
for i in range(N):
transposed_rows[i].append(x)
for i in range(N):
append_to_output_file(transposed_rows[i])
转换为二进制文件可以从行中间读取一个数字序列。
N 应该足够小以适应内存中的 transposed_rows(),即 N*rows 应该是合理的。
N 应该足够大,以便我们利用缓存。如果 N=1,这意味着我们浪费了大量的读取来生成单行输出。
【讨论】:
注意pass
是python中的一个关键字,所以不是一个好的变量名选择:)【参考方案4】:
如果您的服务器有 500GB 的 RAM,那么使用 numpy 的 loadtxt 方法应该没有问题。
data = np.loadtxt("path_to_file").T
【讨论】:
我会尽力让你知道发生了什么。 我测试过它失败了。 您是内存不足还是发生了其他事情? 它仍在运行,只有大约 200MB 的可用内存。这就是我杀死它的原因。以上是关于加载一个非常大的 txt 文件并进行转置的主要内容,如果未能解决你的问题,请参考以下文章
⭐️ LeetCode解题系列 ⭐️ 194. 转置文件(Shell)