在Python中协调np.fromiter和多维数组。

时间:2022-08-25 21:34:14

I love using np.fromiter from numpy because it is a resource-lazy way to build np.array objects. However, it seems like it doesn't support multidimensional arrays, which are quite useful as well.

我喜欢使用numpy中的np.fromiter,因为它是构建np的一种资源惰性方式。数组对象。然而,它似乎不支持多维数组,这也是非常有用的。

import numpy as np

def fun(i):
    """ A function returning 4 values of the same type.
    """
    return tuple(4*i + j for j in range(4))

# Trying to create a 2-dimensional array from it:
a = np.fromiter((fun(i) for i in range(5)), '4i', 5) # fails

# This function only seems to work for 1D array, trying then:
a = np.fromiter((fun(i) for i in range(5)),
        [('', 'i'), ('', 'i'), ('', 'i'), ('', 'i')], 5) # painful

# .. `a` now looks like a 2D array but it is not:
a.transpose() # doesn't work as expected
a[0, 1] # too many indices (of course)
a[:, 1] # don't even think about it

How can I get a to be a multidimensional array while keeping such a lazy construction based on generators?

如何使a成为一个多维数组,同时保持基于生成器的惰性结构?

1 个解决方案

#1


10  

By itself, np.fromiter only supports constructing 1D arrays, and as such, it expects an iterable that will yield individual values rather than tuples/lists/sequences etc. One way to work around this limitation would be to use itertools.chain.from_iterable to lazily 'unpack' the output of your generator expression into a single 1D sequence of values:

np.fromiter本身只支持构建一维数组,它预计一个iterable,将产生个人价值观而不是元组/清单/序列等。解决这个限制的一种方法是使用itertools.chain.from_iterable懒洋洋地“解压缩”生成器表达式的输出到一个一维序列的值:

import numpy as np
from itertools import chain

def fun(i):
    return tuple(4*i + j for j in range(4))

a = np.fromiter(chain.from_iterable(fun(i) for i in range(5)), 'i', 5 * 4)
a.shape = 5, 4

print(repr(a))
# array([[ 0,  1,  2,  3],
#        [ 4,  5,  6,  7],
#        [ 8,  9, 10, 11],
#        [12, 13, 14, 15],
#        [16, 17, 18, 19]], dtype=int32)

#1


10  

By itself, np.fromiter only supports constructing 1D arrays, and as such, it expects an iterable that will yield individual values rather than tuples/lists/sequences etc. One way to work around this limitation would be to use itertools.chain.from_iterable to lazily 'unpack' the output of your generator expression into a single 1D sequence of values:

np.fromiter本身只支持构建一维数组,它预计一个iterable,将产生个人价值观而不是元组/清单/序列等。解决这个限制的一种方法是使用itertools.chain.from_iterable懒洋洋地“解压缩”生成器表达式的输出到一个一维序列的值:

import numpy as np
from itertools import chain

def fun(i):
    return tuple(4*i + j for j in range(4))

a = np.fromiter(chain.from_iterable(fun(i) for i in range(5)), 'i', 5 * 4)
a.shape = 5, 4

print(repr(a))
# array([[ 0,  1,  2,  3],
#        [ 4,  5,  6,  7],
#        [ 8,  9, 10, 11],
#        [12, 13, 14, 15],
#        [16, 17, 18, 19]], dtype=int32)