2016-05-07 25 views
2

我想为其他numpy.array's做一个numpy.array,以进行蒙特卡洛模拟。我想获取数组的元素(另一个1d数组)并在其上执行一些函数,该函数返回该数组的子部分,然后重新分配它。 最初所有阵列长度相同这似乎导致问题。numpy - 将np.arrays自动隐式转换为列表

我想做例如:

c1 = np.array([np.array(xi) for xi in [[1,2],[1],[1,3]]]) 
c1[2] = np.array([5]) 

的正常工作,并提供:

array([array([1, 2]), array([1]), array([5])], dtype=object) 

,我也得到相同类型的结构时,我做了改造这让所有的子阵列相同的长度。

c2 = np.array([np.array(xi) for xi in [[1,2],[1],[1,3]]]) 
c2[1] = np.array([4,5]) 

array([array([1, 2]), array([4, 5]), array([1, 3])], dtype=object). 

相反会发生什么是:例如

当我开始所有阵列长度相同时,它们将从np.arrays转换为lists

c3 = np.array([np.array(xi) for xi in [[1,2],[1,2],[1,4]]]) 

这给

array([[1, 2], [1, 2], [1, 4]]). 

现在,如果我尝试调整列表中的一个的长度

c3[1] = np.array([5]) 

我得到广播

array([[1, 2], [5, 5], [1, 4]]) 

的时候,而不是我通缉

array([array([1, 2]), array([5]), array([1, 4])]) 

性能问题

这是所有蒙特卡洛模拟,通常我期待处理大约10000个子阵列,其中每个子阵列的阵列大约1'000个元素的阵列(浮标)。我一直在使用numpy,因为它的随机数生成速度非常快,而且它对矢量化函数有很好的性能,特别是我想对这些最终执行某种累积和(np.cumsum)以及其他一些更深奥的函数。我能够通过列表完成这类事情,但花费了大约20倍的时间,并且希望尽可能优化。

很多感谢。

+0

你有没有测试np.array列表的性能,而不是NP。 np.array数组? – kennytm

+1

我建议重新考虑这种方法。不同长度阵列的阵列看起来很奇怪,不方便,可能很慢。 –

+0

@kennytm我没有测试性能,因为我正在通过'np.insert'使用以下内容:'np.insert(np.array([many_np_arrays]),0,x0,axis = 1)。 cumsum(axis = 1))'其中'x0'是一组初始条件,然后使用'.cumsum'将它们转换为累加和。使用'np.insert'来添加一个初始条件是非常有用的,而不是做一个'for循环'然后做一些'x0.append(etc)'。基本上我想保留'np.array's的功能。我希望这是明确的。 – oliversm

回答

1

numpy不允许您更改np的np.arrays的形状。数组:

>>> c3 = np.array([np.array(xi) for xi in [[1,2],[1,2],[1,4]]]) 
>>> c4 = np.array([c3[:1],np.array([5]), c3[2:]]) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: could not broadcast input array from shape (2) into shape (1) 

你可以做的是使用dtype=np.ndarrynp.empty

>>> ourList = [[1,2],[1,2],[1,4]] 
>>> c3 = np.empty(len(ourList), dtype=np.ndarray) 
>>> for i in xrange(len(ourList)): 
>>>  c3[i] = np.array(outList[i]) 
>>> c3 
array([array([1, 2]), array([1, 2]), array([1, 4])], dtype=object) 
>>> c3[1] = np.array([5]) 
>>> c3 
array([array([1, 2]), array([5]), array([1, 4])], dtype=object) 

这是你在找什么?

您可能希望只是把零或一些巨大的正/负,这将不会影响你的模拟号码:

>>> c3 = np.array([np.array(xi) for xi in [[1,2],[1,2],[1,4]]]) 
>>> c3[1] = np.array([5]) 
>>> c3 
array([[1, 2], 
     [5, 5], 
     [1, 4]]) 
>>> c3[1][1] = -9999999 
>>> c3 
array([[  1,  2], 
     [  5, -9999999], 
     [  1,  4]]) 
+1

注意它将'dtype = np.array'变成'dtype = object'。这种数组包含指向任何类型对象的指针; – hpaulj

+0

该解决方案正如我想要的那样工作!我的意思是我必须做更多的代码行和一些额外的连接/嵌套操作(只有几个!),而不是我最初设想的,但是现在我读到的性能提高了40倍以上最初''列表'列表'方法,其中作为我的'列表'方法的最初'np.array'(上面概述的问题)只给了20个改进因素(我只说...)。谢谢@Kenneth – oliversm

+0

尝试'c3 [...] = ourList'来填充对象数组。 – hpaulj