首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python Numpy从对象追加多个列表

Python Numpy从对象追加多个列表
EN

Stack Overflow用户
提问于 2018-08-29 13:31:00
回答 3查看 506关注 0票数 2

我多次调用一个对象,返回一个numpy列表:

代码语言:javascript
运行
复制
for x in range(0,100):
        d = simulation3()

d = [0, 1, 2, 3]
d = [4, 5, 6, 7]

..and还有更多

我想获取每个列表并将其附加到一个2D数组中。

final_array = [[0, 1, 2, 3],[4, 5, 6, 7]...and等]

我尝试创建一个空数组(final_array = np.zeros(4,4))并将其追加,但在创建4X4 matrix之后会追加这些值。

有人能帮我吗?谢谢!

EN

回答 3

Stack Overflow用户

发布于 2018-08-29 20:02:47

您可以使用np.fromiter从可迭代对象创建数组。默认情况下,此函数仅适用于标量,因此您可以使用itertools.chain来提供帮助:

代码语言:javascript
运行
复制
np.random.seed(0)

from itertools import chain

def simulation3():
    return np.random.randint(0, 10, 4)

n = 5
d = np.fromiter(chain.from_iterable(simulation3() for _ in range(5)), dtype='i')
d.shape = 5, 4

print(d)

array([[5, 0, 3, 3],
       [7, 9, 3, 5],
       [2, 4, 7, 6],
       [8, 8, 1, 6],
       [7, 7, 8, 1]], dtype=int32)

但这是相对低效的。使用固定大小的数组时,NumPy的性能最好。如果事先知道数组的大小,则可以定义一个空数组并按顺序更新行。请参阅@norok2描述的alternatives

票数 1
EN

Stack Overflow用户

发布于 2018-08-29 15:33:36

在numpy中有多种方法可以做到这一点,最简单的方法是像这样使用vstack:

对于Ex:

代码语言:javascript
运行
复制
#you have these array you want to concat

d1 = [0, 1, 2, 3]
d2 = [4, 5, 6, 7]
d3 = [4, 5, 6, 7]

#initialize your variable with zero raw 
X = np.zeros((0,4))

#then each time you call your function use np.vstack like this :
X = np.vstack((np.array(d1),X))
X = np.vstack((np.array(d2),X))
X = np.vstack((np.array(d2),X))

# and finally you have your array like below
#array([[4., 5., 6., 7.],
#       [4., 5., 6., 7.],
#       [0., 1., 2., 3.]])
票数 0
EN

Stack Overflow用户

发布于 2018-08-29 19:47:54

最佳解决方案取决于您正在处理的数字/大小。我最喜欢的解决方案(只有当你已经知道最终结果的大小时才有效)是初始化包含结果的数组,然后填充每个数组,你可以初始化结果,然后使用视图填充它。这是内存效率最高的解决方案。

如果您不知道最终结果的大小,那么您最好生成一个列表列表,该列表可以在过程结束时转换(或堆叠)为NumPy数组。

以下是一些示例,其中gen_1d_list()用于生成一些随机数来模拟simulate3()的结果(这意味着在以下代码中,您应该将gen_1d_list(n, dtype)替换为simulate3()):

  • stacking1()使用views
  • stacking2()实现填充,array
  • stacking3()实现列表生成,array
  • stacking4()转换为NumPy实现列表生成,堆叠到NumPy array实现前面提出的使用vstack()动态修改NumPy数组。

代码语言:javascript
运行
复制
import numpy as np

def gen_1d_list(n, dtype=int):
    return list(np.random.randint(1, 100, n, dtype))

def stacking1(n, m, dtype=int):
    arr = np.empty((n, m), dtype=dtype)
    for i in range(n):
        arr[i] = gen_1d_list(m, dtype)
    return arr

def stacking2(n, m, dtype=int):
    items = [gen_1d_list(m, dtype) for i in range(n)]
    arr = np.array(items)
    return arr

def stacking3(n, m, dtype=int):
    items = [gen_1d_list(m, dtype) for i in range(n)]
    arr = np.stack(items, dtype)
    return arr

def stacking4(n, m, dtype=int):
    arr = np.zeros((0, m), dtype=dtype)
    for i in range(n):
        arr = np.vstack((gen_1d_list(m, dtype), arr))
    return arr

在时间方面,stacking1()stacking2()的速度大致相同,而stacking3()stacking4()的速度要慢得多(从比例上讲,小尺寸输入的速度要慢得多)。

一些数字,用于小尺寸输入:

代码语言:javascript
运行
复制
n, m = 4, 10
%timeit stacking1(n, m)
# 15.7 µs ± 182 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit stacking2(n, m)
# 14.2 µs ± 141 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit stacking3(n, m)
# 22.7 µs ± 282 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit stacking4(n, m)
# 31.8 µs ± 270 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

对于较大尺寸的输入:

代码语言:javascript
运行
复制
n, m = 4, 1000000
%timeit stacking1(n, m)
# 344 ms ± 1.64 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit stacking2(n, m)
# 350 ms ± 1.65 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit stacking3(n, m)
# 370 ms ± 2.75 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit stacking4(n, m)
# 369 ms ± 3.01 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52070051

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档