这可能是一个愚蠢的问题,但我无法找到合适的答案。我想存储(不要问为什么)(2000, 2000, 2000)
零的二进制表示形式的磁盘,二进制格式。实现这一目标的传统方法是:
with open('myfile', 'wb') as f:
f.write('\0' * 4 * 2000 * 2000 * 2000) # 4 bytes = float32
但这意味着要创建一个非常大的字符串,这根本不是必需的。我知道另外两个选择:
迭代元素并一次存储一个字节(非常慢)
创建一个numpy数组并将其刷新到磁盘(与上面示例中的字符串创建一样昂贵的内存)
我正在寻找像write(char, ntimes)
(因为它存在于C和其他语言中)以C速度复制到磁盘char
ntimes
而不是Python循环速度的东西,无需在内存上创建如此大的数组。
答案 0 :(得分:1)
这将是使用numpy's memmap:
从Python填充文件的有效答案shape = (2000, 2000, 2000) # or just (2000 * 2000 * 2000,)
fp = np.memmap(filename, dtype='float32', mode='w+', shape=shape)
fp[...] = 0
答案 1 :(得分:1)
我不知道为什么你会对“Python的循环速度”这么大惊小怪,但写作的方式是
for i in range(2000 * 2000):
f.write('\0' * 4 * 2000) # 4 bytes = float32
将告诉操作系统写入8000个0字节。在write
返回后,在下一个循环运行中再次调用它。
可能是循环的执行速度比在C中稍慢,但这绝对不会产生影响。
如果可以使用稀疏文件,您也可以寻找所需文件大小的位置,然后截断文件。
答案 2 :(得分:0)
要编写零,有一个很好的黑客:以读写方式打开文件,寻找偏移减1,然后再写零。
这也用零填充文件的开头:
mega_size = 100000
with open("zeros.bin","wb+") as f:
f.seek(mega_size-1)
f.write(bytearray(1))
答案 3 :(得分:0)
原始海报无法说明为什么确实需要使用python来完成。因此,这是一个小的Shell脚本命令,它执行相同的操作,但速度可能会稍快一些。假设OP位于类似Unix的系统(Linux / Mac)上
定义:bs(块大小)= 2000 * 2000,计数= 4 * 2000 if(输入文件)是一个特殊的“零产生”设备。 (输出文件)的of必须指定为wel。
dd bs=4000000 count=8000 if=/dev/zero of=/Users/me/thirtygig
在我的计算机(ssd)上,这大约需要110秒: 在108.435354秒(295106705字节/秒)中传输了32000000000字节
您始终可以从python调用此小shell命令。
为了进行比较,@ glglgl小python脚本在303秒内在同一台计算机上运行,因此只慢了3倍,这可能足够快。
答案 4 :(得分:-2)
数据量约为30G字节。 显然,在将文件放入文件之前,它不能存储在RAM中。
也许最好的方法是使用磁盘集群大小的缓冲区(4k,128k,512k?)