Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.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 3.x 如何使用Dask从文本文件加载大的numpy数组?_Python 3.x_Numpy_Dask - Fatal编程技术网

Python 3.x 如何使用Dask从文本文件加载大的numpy数组?

Python 3.x 如何使用Dask从文本文件加载大的numpy数组?,python-3.x,numpy,dask,Python 3.x,Numpy,Dask,我有一个文本文件,其中包含通过强制执行自定义numpy.dtype读取到内存中的数据。虽然文本文件比可用的RAM小,但我经常会得到一个内存错误(我不理解,但这不是这个问题的重点)。在寻找解决问题的方法时,我遇到了一个问题。在API中,我找到了用于数据加载的接口,但没有一个可以读取文本文件,更不用说我需要在genfromtxt()中支持转换器 我看到有一个dask.dataframe.read_csv()方法,但在我的例子中,我不使用pandas,而是使用带有自定义数据类型和列名称的普通numpy

我有一个文本文件,其中包含通过强制执行自定义
numpy.dtype
读取到内存中的数据。虽然文本文件比可用的RAM小,但我经常会得到一个
内存错误
(我不理解,但这不是这个问题的重点)。在寻找解决问题的方法时,我遇到了一个问题。在API中,我找到了用于数据加载的接口,但没有一个可以读取文本文件,更不用说我需要在
genfromtxt()
中支持转换器

我看到有一个
dask.dataframe.read_csv()
方法,但在我的例子中,我不使用pandas,而是使用带有自定义数据类型和列名称的普通
numpy.array
,如上所述。我拥有的文本文件无论如何都不是CSV(因此上面提到的在
genfromtxt()
中使用转换器)


如果您有任何关于如何处理的想法,我们将不胜感激。

您应该使用函数
dask.bytes.read\u bytes
delimiter=“\n”
来读取您的文件并在行尾将其拆分为块。返回一组
dask.delayed
对象,您可以将其传递给numpy。不幸的是,numpy需要一个类似的文件,因此必须再次打包字节:

import dask
import dask.array as da
_, blocks = dask.bytes.read_bytes(files, delimiter="\n")

@dask.delayed
def parse(block):
    return numpy.genfromtext(io.BytesIO(block), ...)

arrays = [da.from_delayed(parse(block), ...) for block in blocks]
arr = da.stack/concat(arrays)

因此,编辑拒绝了我对@mdurant答案的编辑,因此,我在这里发布了工作代码(基于该答案):


谢谢你,但是当我在arr上调用
compute()
时,我得到了以下错误:“TypeError:由于试图将
io.BytesIO(block)
传递到
numpy.genfromtxt()
中,需要一个类似字节的对象,而不是'list'”。我认为
numpy.getnfromtxt()
只需要一个文件名,不能处理字节块。按照您的想法,我想我应该将原始文件拆分为磁盘上的多个文件,然后对每个文件调用
numpy.genfromtxt()
,以便稍后对生成的数组进行分析,对吗?啊,我忘了blocks是列表的列表。请压平,这样就行了。Genfromtxt处理类似文件的对象。我注意到列表问题,扁平化没有帮助,但我错误地认为这是由于
Genfromtxt()
print(io.BytesIO(blocks[0])
产生
#类型错误:需要一个类似字节的对象,而不是'list'
print(io.BytesIO(blocks[0][0])
产生
#类型错误:需要一个类似字节的对象,而不是'Delayed'
,因此问题似乎与延迟的对象如何不被处理为BytesIO有关,在解析函数中,
blocks[0][0]
是一个
bytes
对象,我不知道为什么。为了使其工作,我还必须将
shape
参数添加到对
from\u delayed()
的调用中。我也不明白,为什么Dask不能自己计算形状,我不必事先知道文本文件中数组的大小。另外,
stack
也工作了,但是没有
concat
。对不起,我没有收到任何编辑通知!很高兴你让它工作了。不是你,是一些“高级”用户在审查编辑。他们拒绝了我的。不管怎样,我把这个答案贴了出来,以备将来有人需要。谢谢你的帮助。
import numpy 
import dask
import dask.array as da
import io

fname = 'data.txt'
# data.txt is:
# 1 2
# 3 4
# 5 6

files = [fname]
_, blocks = dask.bytes.read_bytes(files, delimiter="\n")

my_type = numpy.dtype([
                    ('f1', numpy.float64),
                    ('f2', numpy.float64)
                    ])

native_type = numpy.float
used_type = numpy.float64
# If the below line is uncommented, then creating the dask array will work, but it won't
# be possible to perform any operations on it
# used_type = my_type

# Debug
# print('blocks', blocks)
# print('type(blocks)', type(blocks))
# print('blocks[0]', blocks[0])
# print('type(blocks[0])', type(blocks[0]))

@dask.delayed
def parse(block):
    r = numpy.genfromtxt(io.BytesIO(block[0]))
    print('parse() about to return:\n', r, '\n')
    return r

# Below I added shape, which seems compulsatory, the reason for which I don't understand
arrays = [da.from_delayed(value=parse(block), shape=(3, ), dtype=used_type) for block in blocks]
# da.concat did not not work for me
arr = da.stack(arrays)
# The below will not work if used_type is set to my_type
arr += 1
# Neither the below woudl work, it raises NotImplementedError
# arr['f1'] += 1
arr_np = arr.compute()
print('numpy array incremented by one: \n', arr_np)