Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将二进制值的文本转换为numpy文件_Python_Memory_Numpy_Text - Fatal编程技术网

Python 将二进制值的文本转换为numpy文件

Python 将二进制值的文本转换为numpy文件,python,memory,numpy,text,Python,Memory,Numpy,Text,如何将包含二进制字符(0和1)的大型文本文件(>16G)转换为numpy数组文件,而不占用python中的内存?假设机器上有足够的存储空间,但没有足够的RAM进行转换 样本数据: 0,0,0,0,0,1,0,0,0 1,0,0,1,0,0,0,0,0 ... 示例代码: converted_data = [ map(int,line.split(',')) for line in f ] 您使用pickle创建了许多bin文件,并且有一些代码可以加载和卸载数据的不同部分 假设你有一个16G

如何将包含二进制字符(
0
1
)的大型文本文件(>16G)转换为numpy数组文件,而不占用python中的内存?假设机器上有足够的存储空间,但没有足够的RAM进行转换

样本数据:

0,0,0,0,0,1,0,0,0 
1,0,0,1,0,0,0,0,0
...
示例代码:

converted_data = [ map(int,line.split(',')) for line in f ]

您使用pickle创建了许多bin文件,并且有一些代码可以加载和卸载数据的不同部分

假设你有一个16GB的文件,你可以创建16个1GB的pickle文件


如果您说您有足够的RAM,那么在完成pickle文件之后,您应该能够将其全部加载到内存中。

据我所知,您读取该文件的方法已经非常节省内存了

我假设使用获取文件对象不会将整个文件从文件系统读入RAM,而是根据需要访问文件系统上的文件

然后,迭代文件对象的(在您的情况下是字符串,当您以文本模式打开文件时),也就是说,文件对象充当一个字符串。因此,我们可以假设这里没有构造所有行的列表,并且这些行被逐个读取以持续消耗

您可以在列表收缩中执行此操作。列表收缩是否会收集其右侧(关键字中
之后的部分)生成的所有值,然后将其传递到左侧(关键字中
之前的部分)进行处理?一个小小的实验可以告诉我们:

print('defining generator function')

def firstn(n):
        num = 0
        while num < n:
                print('yielding ' + str(num))
                yield num
                num += 1

print('--')

[print('consuming ' + str(i)) for i in firstn(5)]
因此答案是否定的,在从右手侧产生任何其他值之前,左手侧立即消耗每个产生的值。一次只需将文件中的一行保存在内存中

因此,如果文件中的各行不太长,您的阅读方法似乎与它得到的内存效率一样

当然,列表收缩仍然需要收集左侧处理的结果。毕竟,结果列表是您希望从中得到的。因此,如果内存不足,很可能是结果列表变得太大

我不知道NumPy是否利用了这样一个事实,即布尔集合可以比数字更有效地存储。但如果是这样的话,您必须意识到整数实际上是布尔值,才能从内存效率更高的数据类型中获益:

import numpy as np
f = open ( "data.txt" , 'r')
converted_data = [ np.fromstring(line, dtype=bool, sep=',') for line in f ]

如果你不需要一下子就需要所有的代码> CurrdEXDATA < /COD>,而是必须能够迭代它,考虑把它变成一个生成器,而不是一个列表。您不需要使用

yield
关键字来实现这一点。只需将列表的方括号替换为圆括号,即可得到生成器表达式:

converted_data_generator = ( np.fromstring(line, dtype=bool, sep=',') for line in f )

“二进制值字符串”是什么意思?现有文件的确切格式是什么?根据现有的格式,您可能可以使用内存映射数组执行某些操作。这是一个很好的主题,但没有提供足够的信息来提供有用的答案。你能发布可以读取较小文件的代码吗?如果您不能这样做,请提供有关文件格式等的更多信息。测试文件包含用逗号分隔的“0”和“1”字符。以下是我用于进行转换的示例代码:您对导入过程的内存消耗感兴趣吗(可以通过串行读取和转换数据而不是一次读取所有数据来减少)或在
转换的\u数据
的占用空间中(除非您可以使用稀疏结构,否则将大于1G)?希望从我的措辞中可以看出,我的许多结论都是基于猜测。因此,如果有人知道得更好,请纠正我。