简体   繁体   English

如何在 python 的 2D 阵列中加速 2D arrays?

[英]How to speed up 2D arrays in 2D array in python?

I am looking at how to speed up one of my functions.我正在研究如何加快我的一项功能。 The function is called with a number of two-dimensional arrays of the same size. function是用多个相同大小的二维arrays调用的。 I want to combine these into a 4D with 3x3 in the last two dimensions, and later get the eigenvalues of the whole array.我想将它们组合成最后两个维度为 3x3 的 4D,然后得到整个数组的特征值。

I have managed to do it using two nested for loops, but it is a bit slower then I would desire, so is there any good way of speeding up the code?我已经设法使用两个嵌套for循环来做到这一点,但是它比我想要的要慢一些,那么有什么好方法可以加快代码速度吗?

def principal(xx, xy, xz, yy, yz, zz):

    import numpy as np

    xx = np.array(xx)
    xy = np.array(xy)
    xz = np.array(xz)
    yy = np.array(yy)
    yz = np.array(yz)
    zz = np.array(zz)

    size = np.shape(xx)
    Princ = np.empty((size[1], size[0], 3, 3))
    for j in range(size[1]):
        for i in range(size[0]):
            Princ[j, i, :, :] = np.array([[xx[i, j], xy[i, j], xz[i, j]],
                                          [xy[i, j], yy[i, j], yz[i, j]],
                                          [xz[i, j], yz[i, j], zz[i, j]]])
    Princ = np.linalg.eigvalsh(Princ)

    return Princ


import numpy as np

number_arrays_1 = 3
number_arrays_2 = 4

xx = np.ones((number_arrays_1, number_arrays_2))*80
xy = np.ones((number_arrays_1, number_arrays_2))*30
xz = np.ones((number_arrays_1, number_arrays_2))*0
yy = np.ones((number_arrays_1, number_arrays_2))*40
yz = np.ones((number_arrays_1, number_arrays_2))*0
zz = np.ones((number_arrays_1, number_arrays_2))*60

Princ = principal(xx, xy, xz, yy, yz, zz)
print(Princ)

The reason I convert with xx = np.array(xx) is that in the larger program, I pass a pandas dataframe rather than a numpy array into the function. The reason I convert with xx = np.array(xx) is that in the larger program, I pass a pandas dataframe rather than a numpy array into the function.

This looks like a simple stack and reshape operation:这看起来像一个简单的堆栈和重塑操作:

def principal(xx, xy, xz, yy, yz, zz):
    princ = np.stack((xx.T, xy.T, xz.T, xy.T, yy.T, yz.T, xz.T, yz.T, zz.T), axis=-1).reshape(*xx.shape[::-1], 3, 3)
    return = np.linalg.eigvalsh(princ)

You don't need to explicitly call np.array on the inputs if they are already arrays.如果输入已经是 arrays,则不需要在输入上显式调用np.array xx.values() on the dataframes should return the numpy values.数据帧上的xx.values()应返回 numpy 值。

An alternative approach is to build the array, and then swap out the 3x3 dimensions to the back.另一种方法是构建数组,然后将 3x3 维度换到后面。 This will likely be less efficient since the first approach makes the 3x3 dimensions contiguous, while this one does not:这可能会降低效率,因为第一种方法使 3x3 维度连续,而这种方法没有:

princ = np.array([[xx, xy, xz], [xy, yy, yz], [xz, yz, zz]]).T

Not really related, but you could generate your arrays faster like this:不是很相关,但您可以像这样更快地生成 arrays:

target_shape = (3, 4)
values = np.array([80, 30, 0, 40, 0, 60])
xx, xy, xz, yy, yz, zz = np.full((6, *target_shape), values.reshape(-1, 1, 1))

In fact, if your data allows it, you can even save on unpacking:事实上,如果您的数据允许,您甚至可以节省拆包时间:

data = np.full((6, *target_shape), values.reshape(-1, 1, 1))
principal(*data)

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

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