python - 将生成器中的数据加载到已分配的 numpy 数组中

标签 python numpy

我有一个大数组

data = np.empty((n, k))

nk 都很大。我还有很多生成器 g,每个都有 k 元素,我想将每个生成器加载到 data 中的一行中。我能做到:

data[i] = list(g)

或类似的东西,但这会复制 g 中的数据。我可以使用 for 循环加载:

for j, x in enumerate(g):
    data[i, j] = x

但我想知道 numpy 是否已经有一种方法可以做到这一点,而无需在 Python 中进行复制或循环。

我知道 g 有长度 k 并且很乐意在必要时做一些 __len__ 子类修补。 np.fromiter 在创建新数组时会接受类似的东西,但由于上下文的限制,我宁愿尽可能加载到这个已经存在的数组中。

最佳答案

如评论中所述,您无能为力。

虽然可以考虑这两种方案:

使用 numpy.fromiter

与其自己创建 data = np.empty((n, k)),不如使用 numpy.fromitercount 参数,这是专门根据这种情况制作的,您可以提前知道项目的数量。这样 numpy 就不必“猜测”大小并重新分配,直到猜测足够大为止。 使用 fromiter 允许在 C 而不是 python 中运行 for 循环。这可能会快一点,但真正的瓶颈可能无论如何都在您的生成器中。

请注意 fromiter 仅处理平面数组,因此您需要读取所有平面数组(例如使用 chain.from_iterable)然后才调用 reshape:

from itertools import chain

n = 20
k = 4
generators = (
   (i*j for j in range(k))
   for i in range(n)
)

flat_gen = chain.from_iterable(generators)
data = numpy.fromiter(flat_gen, 'int64', count=n*k)
data = data.reshape((n, k))
"""
array([[ 0,  0,  0,  0],
       [ 0,  1,  2,  3],
       [ 0,  2,  4,  6],
       [ 0,  3,  6,  9],
       [ 0,  4,  8, 12],
       [ 0,  5, 10, 15],
       [ 0,  6, 12, 18],
       [ 0,  7, 14, 21],
       [ 0,  8, 16, 24],
       [ 0,  9, 18, 27],
       [ 0, 10, 20, 30],
       [ 0, 11, 22, 33],
       [ 0, 12, 24, 36],
       [ 0, 13, 26, 39],
       [ 0, 14, 28, 42],
       [ 0, 15, 30, 45],
       [ 0, 16, 32, 48],
       [ 0, 17, 34, 51],
       [ 0, 18, 36, 54],
       [ 0, 19, 38, 57]])
"""

使用赛通

如果你可以重用data并且想避免重新分配内存,你就不能再使用numpy的fromiter了。恕我直言,避免 python 的 for 循环的唯一方法是在 cython 中实现它。同样,这极有可能矫枉过正,因为您仍然需要阅读 python 中的生成器。

作为引用,fromiter 的 C 实现如下所示:https://github.com/numpy/numpy/blob/v1.18.3/numpy/core/src/multiarray/ctors.c#L4001-L4118

关于python - 将生成器中的数据加载到已分配的 numpy 数组中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55924831/

相关文章:

python - (PyQt) 如何重置整个 QTextEdit 的 CharFormat?

python - 搜索文件并从行中返回所需字段的最佳方法

python - 输入图像的小波二维散射变换

python - 我可以在没有循环的情况下清理 numpy 数组吗?

python - python 中的 4d 插值

python - 同一张图上的 Matplotlib 极轴和笛卡尔轴

python - 在扩展的圆形螺旋中迭代二维数组

python - 使用完整矩阵模拟 scipy 中的 ode(对象对于所需数组来说太深)

python - 无法在 matplotlib 图中出现次要网格线

python - 使用 numpy 或 pandas 处理长格式的 csv 文件