Python 初始化长度未知的numpy数组
我希望能够动态“构建”一个numpy阵列,我事先不知道这个阵列的大小 例如,我想做这样的事情:Python 初始化长度未知的numpy数组,python,arrays,numpy,Python,Arrays,Numpy,我希望能够动态“构建”一个numpy阵列,我事先不知道这个阵列的大小 例如,我想做这样的事情: a= np.array() for x in y: a.append(x) 这将导致a包含x的所有元素,显然这是一个微不足道的答案。我只是好奇这是否可行?您可以这样做: a = np.array([]) for x in y: a = np.append(a, x) 构建Python列表并将其转换为Numpy数组。每追加一次需要摊销O(1)时间+O(n)才能转换为数组,总共O(n
a= np.array()
for x in y:
a.append(x)
这将导致a包含x的所有元素,显然这是一个微不足道的答案。我只是好奇这是否可行?您可以这样做:
a = np.array([])
for x in y:
a = np.append(a, x)
构建Python列表并将其转换为Numpy数组。每追加一次需要摊销O(1)时间+O(n)才能转换为数组,总共O(n)
对子孙后代来说,我认为这样更快:
a = np.array([np.array(list()) for _ in y])
您甚至可以传入一个生成器(即[]->()),在这种情况下,内部列表永远不会完全存储在内存中
对以下评论作出答复:
>>> import numpy as np
>>> y = range(10)
>>> a = np.array([np.array(list) for _ in y])
>>> a
array([array(<type 'list'>, dtype=object),
array(<type 'list'>, dtype=object),
array(<type 'list'>, dtype=object),
array(<type 'list'>, dtype=object),
array(<type 'list'>, dtype=object),
array(<type 'list'>, dtype=object),
array(<type 'list'>, dtype=object),
array(<type 'list'>, dtype=object),
array(<type 'list'>, dtype=object),
array(<type 'list'>, dtype=object)], dtype=object)
>>将numpy作为np导入
>>>y=范围(10)
>>>a=np.array([np.array(list)表示y中的uu])
>>>a
数组([array(,dtype=object),
数组(,dtype=object),
数组(,dtype=object),
数组(,dtype=object),
数组(,dtype=object),
数组(,dtype=object),
数组(,dtype=object),
数组(,dtype=object),
数组(,dtype=object),
数组(,dtype=object)],dtype=object)
由于y是一个iterable,我真的不明白为什么要调用append:
a = np.array(list(y))
可以,而且速度更快:
import timeit
print timeit.timeit('list(s)', 's=set(x for x in xrange(1000))')
# 23.952975494633154
print timeit.timeit("""li=[]
for x in s: li.append(x)""", 's=set(x for x in xrange(1000))')
# 189.3826994248866
我写了一个小的实用函数。(以上大多数答案都很好。我觉得这个看起来更好) 您可以按以下方式使用上述功能:
acc = None # accumulator
arr1 = np.ones((3,4))
acc = np_unknown_cat(acc, arr1)
arr2 = np.ones((3,4))
acc = np_unknown_cat(acc, arr2)
这种方法每次追加都复制数组,即O(sum(range(n)))。在我的笔记本电脑上,这个方法比@larsman的方法慢42倍:按照larsman的方法建立一个列表需要1000个循环,最好是每个循环3:1.53毫秒。按照这个方法我只需要10个循环,最好是3:64.8毫秒一个循环。代码应该是可读的,而不是快速的,除非速度是你的瓶颈。为什么要优化只运行一次的代码?很好的注释@AlexGaudio。我真的不知道。非常感谢。可能更有效的方法是分配一些大型数组,每次达到容量时将其大小增加一倍。我在这里做了一个更改:list(_)和那起作用的greatTo be clear@javadba,你不需要这样做——我肯定有些Python学家会生气:)这不是风格问题。如果没有列表(41;,它最终甚至不起作用,因为我知道y本身就是一个数组,OP说“这将导致
a
包含x的所有元素”,所以你确实需要做list(4141;
,或者更好的是:a=np.array([x代表x在y中])
;或者干脆a=np.array(list(y))
当x具有非标量维度时,这将不起作用。例如,如果x=np.ones((3,5)),它将失败。
import timeit
print timeit.timeit('list(s)', 's=set(x for x in xrange(1000))')
# 23.952975494633154
print timeit.timeit("""li=[]
for x in s: li.append(x)""", 's=set(x for x in xrange(1000))')
# 189.3826994248866
def np_unknown_cat(acc, arr):
arrE = np.expand_dims(arr, axis=0)
if acc is None:
return arrE
else:
return np.concatenate((acc, arrE))
acc = None # accumulator
arr1 = np.ones((3,4))
acc = np_unknown_cat(acc, arr1)
arr2 = np.ones((3,4))
acc = np_unknown_cat(acc, arr2)