我有非常大的文件,其中包含正整数的二维数组
我想在不将文件读入内存的情况下处理它们。幸运的是,我只需要查看输入文件中从左到右的值。我希望能够处理mmap每个文件,这样我就可以像在内存中一样处理它们,但实际上无需将文件读入内存。
较小版本的示例:
[[2, 2, 6, 10, 2, 6, 7, 15, 14, 10, 17, 14, 7, 14, 15, 7, 17],
[3, 3, 7, 11, 3, 7, 0, 11, 7, 16, 0, 17, 17, 7, 16, 0, 0],
[4, 4, 8, 7, 4, 13, 0, 0, 15, 7, 8, 7, 0, 7, 0, 15, 13],
[5, 5, 9, 12, 5, 14, 7, 13, 9, 14, 16, 12, 13, 14, 7, 16, 7]]
Run Code Online (Sandbox Code Playgroud)
是否可以使用mmap这样的文件,以便我可以使用以下方法处理np.int64值
for i in range(rownumber):
for j in range(rowlength):
process(M[i, j])
Run Code Online (Sandbox Code Playgroud)
需要明确的是,我不想将所有输入文件都放在内存中,因为它不适合。
更新答案
根据您的评论和说明,您似乎实际上有一个带有一堆方括号的文本文件,该文件大约有 4 行长,每行有 1,000,000,000 个 ASCII 整数,用逗号分隔。不是一个非常有效的格式!我建议您简单地预处理文件以删除所有方括号、换行符和空格并将逗号转换为换行符,以便每行获得一个您可以轻松处理的值。
使用tr命令音译,就是这样:
# Delete all square brackets, newlines and spaces, change commas into newlines
tr -d '[] \n' < YourFile.txt | tr , '\n' > preprocessed.txt
Run Code Online (Sandbox Code Playgroud)
然后您的文件看起来像这样,您可以轻松地在 Python 中一次处理一个值。
2
2
6
10
2
6
...
...
Run Code Online (Sandbox Code Playgroud)
如果您使用的是 Windows,则该tr工具可用于 WindowsGNUWin32中的 Windows 和 Linux 子系统(git bash?)。
你可以更进一步,memmap()在我的答案的第二部分制作一个你喜欢的文件,然后你可以在文件中随机找到任何字节。因此,利用preprocessed.txt上面创建的内容,您可以制作一个二进制版本,如下所示:
import struct
# Make binary memmapable version
with open('preprocessed.txt', 'r') as ifile, open('preprocessed.bin', 'wb') as ofile:
for line in ifile:
ofile.write(struct.pack('q',int(line)))
Run Code Online (Sandbox Code Playgroud)
原答案
你可以这样做。第一部分只是设置:
#!/usr/bin/env python3
import numpy as np
# Create 2,4 Numpy array of int64
a = np.arange(8, dtype=np.int64).reshape(2,4)
# Write to file as binary
a.tofile('a.dat')
Run Code Online (Sandbox Code Playgroud)
现在通过在 shell 中十六进制转储来检查文件:
xxd a.dat
00000000: 0000 0000 0000 0000 0100 0000 0000 0000 ................
00000010: 0200 0000 0000 0000 0300 0000 0000 0000 ................
00000020: 0400 0000 0000 0000 0500 0000 0000 0000 ................
00000030: 0600 0000 0000 0000 0700 0000 0000 0000 ................
Run Code Online (Sandbox Code Playgroud)
现在我们都设置好了,让我们来看看memmap()文件:
# Memmap file and access values via 'mm'
mm = np.memmap('a.dat', dtype=np.int64, mode='r', shape=(2,4))
print(mm[1,2]) # prints 6
Run Code Online (Sandbox Code Playgroud)