Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中对2D和1D NumPy数组上的迭代操作进行矢量化?_Python_Arrays_Numpy_Vectorization_Array Broadcasting - Fatal编程技术网

如何在Python中对2D和1D NumPy数组上的迭代操作进行矢量化?

如何在Python中对2D和1D NumPy数组上的迭代操作进行矢量化?,python,arrays,numpy,vectorization,array-broadcasting,Python,Arrays,Numpy,Vectorization,Array Broadcasting,我正试图加速我的代码,以充分利用NumPy的矢量化。我已经能够在我的大多数代码(clr/vlr函数)中对所有计算进行矢量化,我认为这是NumPy的最佳选择。我不相信这些可以再加快了,因为np.einsum实际上并不适用。我不知道如何将rho函数矢量化。特别是,这个嵌套for循环给我带来了麻烦:1-(比率[i,j]/(方差[i]+方差[j])。我曾尝试使用np.meshgrid来扩展方差,但没有成功。我一直在尝试后续的np.einsum,但仍然有点混乱,我仍然不确定它是否适用于这种情况,因为它涉及

我正试图加速我的代码,以充分利用NumPy的矢量化。我已经能够在我的大多数代码(
clr/vlr
函数)中对所有计算进行矢量化,我认为这是NumPy的最佳选择。我不相信这些可以再加快了,因为
np.einsum
实际上并不适用。我不知道如何将
rho
函数矢量化。特别是,这个嵌套for循环给我带来了麻烦:
1-(比率[i,j]/(方差[i]+方差[j])
。我曾尝试使用
np.meshgrid
来扩展方差,但没有成功。我一直在尝试后续的
np.einsum
,但仍然有点混乱,我仍然不确定它是否适用于这种情况,因为它涉及的运算比点积和矩阵乘法更多

有人知道如何矢量化此函数吗?

另外,对于前2个函数,是否有加快代码速度的建议

import numpy as np
import pandas as pd

def clr(X):
    index = None
    labels = None
    if isinstance(X, pd.DataFrame):
        index = X.index
        labels = X.columns
        X = X.values
    X_log = np.log(X)
    geometric_mean = X_log.mean(axis=1)
    X_clr = X_log - geometric_mean[:,np.newaxis]
    if labels is not None:
        X_clr = pd.DataFrame(X_clr, index=index, columns=labels)
    return X_clr

def vlr(X):
    labels = None
    if isinstance(X, pd.DataFrame):
        labels = X.columns
        X = X.values
    n,m = X.shape
    X_log = np.log(X)
    covariance = np.cov(X_log.T)
    diagonal = np.diagonal(covariance)
    output = -2*covariance + diagonal[:,np.newaxis] + diagonal
    if labels is not None:
        output = pd.DataFrame(output, index=labels, columns=labels)
    return output

def rho(X):
    n, m = X.shape
    labels = None
    if isinstance(X, pd.DataFrame):
        labels = X.columns
        X = X.values

    ratios = vlr(X)
    X_clr = clr(X)
    variances = np.var(X_clr, axis=0)

    # How to vectorize?
    rhos = np.ones_like(ratios)
    for i in range(n):
        for j in range(i+1,m):
            coef = 1 - (ratios[i,j]/ (variances[i] + variances[j]))
            rhos[i,j] = rhos[j,i] = coef

    if labels is not None:
        rhos = pd.DataFrame(rhos, index=labels, columns=labels)
    return rhos

# Load data
X_iris = pd.read_csv("https://pastebin.com/raw/dR59vTD4", sep="\t", index_col=0)
# Calculation
print(rho(X_iris))
#               sepal_length  sepal_width  petal_length  petal_width
# sepal_length      1.000000     0.855012     -0.796224    -0.796770
# sepal_width       0.855012     1.000000     -0.670387    -0.964775
# petal_length     -0.796224    -0.670387      1.000000     0.493560
# petal_width      -0.796770    -0.964775      0.493560     1.000000

可以替换循环:

for i in range(n):
    for j in range(i+1,m):
        coef = 1 - (ratios[i,j]/ (variances[i] + variances[j]))
        rhos[i,j] = rhos[j,i] = coef
与:

np.add.outer(方差,方差)
方差的外部和。例如:

np.add.outer(range(3), range(3))
>>> array([[0, 1, 2],
           [1, 2, 3],
           [2, 3, 4]])
给定数组的形状和循环数学,我们可以使用上面的代码一次完成比率/方差[i]+方差[j]

我想确认一下:

# original loop
for i in range(n):
    for j in range(i+1,m):
        coef = 1 - (ratios[i,j]/ (variances[i] + variances[j]))
        rhos[i,j] = rhos[j,i] = coef

# array math replacement
rhos2 = 1-ratios / np.add.outer(variances, variances)
np.allclose(rhos, rhos2)
>>> True

可以替换循环:

for i in range(n):
    for j in range(i+1,m):
        coef = 1 - (ratios[i,j]/ (variances[i] + variances[j]))
        rhos[i,j] = rhos[j,i] = coef
与:

np.add.outer(方差,方差)
方差的外部和。例如:

np.add.outer(range(3), range(3))
>>> array([[0, 1, 2],
           [1, 2, 3],
           [2, 3, 4]])
给定数组的形状和循环数学,我们可以使用上面的代码一次完成比率/方差[i]+方差[j]

我想确认一下:

# original loop
for i in range(n):
    for j in range(i+1,m):
        coef = 1 - (ratios[i,j]/ (variances[i] + variances[j]))
        rhos[i,j] = rhos[j,i] = coef

# array math replacement
rhos2 = 1-ratios / np.add.outer(variances, variances)
np.allclose(rhos, rhos2)
>>> True