简体   繁体   English

如何将2D numpy数组的2D numpy数组重组为浮点数的4D数组?

[英]How to restructure a 2D numpy array of 2D numpy arrays into a 4D array of floats?

I have an issue currently where I have a numpy array of shape (60,60) where each point is itself a numpy array of shape (11,11). 我目前遇到一个问题,我有一个形状为(60,60)的numpy数组,其中每个点本身都是一个形状为(11,11)的numpy数组。 This is causing problems for me, because each point of the (60,60) array is an object and not a float: 这给我带来了问题,因为(60,60)数组的每个点都是对象,而不是浮点数:

    P_arr.shape
    (60,60)
    P_arr[i,j].shape
    (11,11)
    P_arr[i,j][k,l]
    1.0

For matrix operations that I need to carry out later on, I need to access each float value of the array in a particular order. 对于稍后需要执行的矩阵运算,我需要以特定顺序访问数组的每个浮点值。 I need a new array to have a shape of (11,11,60,60), with each point being a float. 我需要一个新数组,形状为(11,11,60,60),每个点都是浮点数。 Ideally, I would like to reach this point: 理想情况下,我想达到这一点:

    New_P_arr[k,l,i,j]
    1.0

Is there any way to extract the float values out of the interior 2D arrays to reshape it into the desired form? 有什么方法可以从内部2D数组中提取float值以将其重塑为所需的形式? I need a solution that is faster than looping, because this will scale up quite a bit in the future. 我需要一个比循环更快的解决方案,因为这将来会扩展很多。 I have tried flattening, vstack, concatenate, etc. The issue with flattening, for example, is this: 我已经尝试了flattening,vstack,concatenate等。例如,flattening的问题是这样的:

    New_P_arr = np.concatenate(P_arr)
    New_P_arr.shape
    (3600,)
    New_P_arr[i].shape
    (11,11)

So, flattening the array (or the other operations) will not allow me to access all the values within a single square bracket index. 因此,展平数组(或其他操作)将不允许我访问单个方括号索引中的所有值。 My initial thought was to flatten the array in order to reshape it, but because the points are objects and not floats that won't work either. 我最初的想法是将数组弄平以便对其进行整形,但是因为这些点是对象而不是浮点,所以它们也不起作用。

EDIT: Here is how I generated P_arr. 编辑:这是我生成P_arr的方式。 I need to solve the associated Legendre function for a selection of 11 l and 11 m values over a grid of theta values with the shape (60,60). 我需要解决关联的Legendre函数,以便在形状为(60,60)的theta值网格上选择11 l和11 m值。 Scipy has a package, lpmn, which computes the associated Legendre polynomials as well as their derivatives (which I don't need), but it isn't vectorized. Scipy有一个程序包lpmn,它可以计算相关的Legendre多项式及其导数(我不需要),但是它没有向量化。 It returns an (11,11) array at a given theta value for each l and m up to the value I input (from 0-10, that's where the 11 comes from). 对于每个l和m,它以给定的theta值返回(11,11)数组,直到输入的值(从0-10开始,这就是11的来源)。 This is the code: 这是代码:

    import numpy as np
    from scipy.special import lpmn
    lmax = 10
    mmax = lmax
    theta = np.arange(0, 180., 3)
    theta = theta*np.pi/180.
    phi = theta
    ph, th = np.meshgrid(theta, phi)
    cos_th = np.cos(th)
    th is a (60,60) array of theta values from 0-pi in equal steps    

    @np.vectorize
    def asscP(m, l, cos_theta):
        return lpmn(m, l, cos_theta)[0]

    asscP = np.vectorize(asscP, excluded={0,1}, otypes=[np.ndarray])
    P_arr = asscP(mmax, lmax, cos_th)
  • you can first stack inner level then outer level. 您可以先堆叠内层然后再堆叠外层。
>>>new_P_arr = np.stack([np.stack(p) for x in P_arr])
>>>new_P_arr.shape
(60,60,11,11)

As you are concerned with performance, you probably should review your data generation code. 当您关心性能时,可能应该查看数据生成代码。 Two points to consider: 需要考虑两点:

  1. As per the docs np.vectorize does not make your code faster, it is just a convenience function and will loop over your elements. 根据docs np.vectorize并不能使您的代码更快,它只是一个便利函数,会在您的元素上循环。
  2. Your cos_th array has the same values so the expensive call to lpmn is made 60x more often than necessary. 您的cos_th数组具有相同的值,因此对lpmn进行昂贵的调用的频率比必需的多60倍。

Based on this, I suggest you use python loops and numpy slice assignments as follows: 基于此,我建议您使用python循环和numpy slice分配,如下所示:

import numpy as np
from scipy.special import lpmn
lmax = 10
mmax = lmax
theta = np.arange(0, 180., 3)
theta = theta*np.pi/180.
cos_theta = np.cos(theta)
P_arr = np.zeros(shape=(len(theta), len(theta), mmax+1, lmax+1))
for e, ct in enumerate(cos_theta):
    P_arr[0,e,:] = lpmn(mmax, lmax, ct)[0]
    for i in range(1, len(theta)):
        P_arr[i,e,:] = P_arr[e,0,:] # copy data 60x
P_arr = P_arr.swapaxes(0,2)
P_arr = P_arr.swapaxes(1,3)
P_arr.shape

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM