Python中嵌套for循环的矢量化

Python中嵌套for循环的矢量化,python,numpy,for-loop,vectorization,Python,Numpy,For Loop,Vectorization,我有以下嵌套for循环(为简单起见,随机): 将numpy导入为np lat_idx=np.random.randint(121,size=4800) lon_idx=np.random.randint(201,size=(48004800)) 求和单元=np.零((121201)) 数据=np.random.rand(48004800) 对于范围(4800)内的j: 对于范围内的i(4800): 如果lat_idx[i]=0) #获得正指数 横向位置,纵向位置=np.广播到(横向idx2,m.

我有以下嵌套for循环(为简单起见,随机):

将numpy导入为np
lat_idx=np.random.randint(121,size=4800)
lon_idx=np.random.randint(201,size=(48004800))
求和单元=np.零((121201))
数据=np.random.rand(48004800)
对于范围(4800)内的j:
对于范围内的i(4800):
如果lat_idx[i]<0或lon_idx[i,j]<0:
持续
和单元[lat_idx[i],lon_idx[i,j]+=data[i,j]
#打印(总和单元格)

有没有一种方法可以把它写成矩阵运算或是一些“numpy动作”?现在真的很慢。我的问题是
lon_idx
既依赖于
i
又依赖于
j

这就是如何以矢量化的方式做到这一点:

import numpy as np

# Make input data
np.random.seed(0)
data = np.random.rand(4800, 4800)
# Add some negative values in indices
lat_idx = np.random.randint(-20, 121, size=4800)
lon_idx = np.random.randint(-50, 201, size=(4800, 4800))
# Output array
sum_cell = np.zeros((121, 201))
# Make mask for positive indices
lat_idx2 = lat_idx[:, np.newaxis]
m = (lat_idx2 >= 0) & (lon_idx >= 0)
# Get positive indices
lat_pos, lon_pos = np.broadcast_to(lat_idx2, m.shape)[m], lon_idx[m]
# Add values
np.add.at(sum_cell, (lat_pos, lon_pos), data[m])
# Check result with previous method
sum_cell2 = np.zeros((121, 201))
for j in range(4800):
    for i in range(4800):
        if lat_idx[i] < 0 or lon_idx[i, j] < 0: 
            continue
        sum_cell2[lat_idx[i], lon_idx[i, j]] += data[i, j]
print(np.allclose(sum_cell, sum_cell2))
# True
将numpy导入为np
#输入数据
np.random.seed(0)
data=np.random.rand(48004800)
#在索引中添加一些负值
lat_idx=np.random.randint(-20121,size=4800)
lon_idx=np.random.randint(-50201,size=(48004800))
#输出阵列
sum_cell=np.零((121201))
#为正指数制作掩码
lat_idx2=lat_idx[:,np.newaxis]
m=(纬度idx2>=0)和(纬度idx>=0)
#获得正指数
横向位置,纵向位置=np.广播到(横向idx2,m.形状)[m],纵向idx[m]
#增加价值
np.add.at(总和单元格,(横向位置,纵向位置),数据[m])
#用以前的方法检查结果
sum_cell2=np.零((121201))
对于范围(4800)内的j:
对于范围内的i(4800):
如果lat_idx[i]<0或lon_idx[i,j]<0:
持续
和单元2[lat_idx[i],lon_idx[i,j]+=data[i,j]
打印(np.allclose(总和单元格,总和单元格2))
#真的

我怀疑您必须使用无缓冲的
np.add.at
函数,因为您将把多个
d[I,j]
元素组合成一个
sum\u单元格
lat\u idx[I]<0或lon\u idx[I,j]<0
怎么可能是真的,如果您只使用正数?@Aryerez这一行是我的原始代码的剩余部分,其中可能有负值。这里的缩进正确吗?或者你为什么要检查if语句,即使没有依赖于它的操作?无论如何,我建议将lat_idx转换为与lon_idx相同的维度,然后根据您的情况使用掩码。@clearseplex我误读了代码的最后一部分,我为错误的答案道歉。
import numpy as np

# Make input data
np.random.seed(0)
data = np.random.rand(4800, 4800)
# Add some negative values in indices
lat_idx = np.random.randint(-20, 121, size=4800)
lon_idx = np.random.randint(-50, 201, size=(4800, 4800))
# Output array
sum_cell = np.zeros((121, 201))
# Make mask for positive indices
lat_idx2 = lat_idx[:, np.newaxis]
m = (lat_idx2 >= 0) & (lon_idx >= 0)
# Get positive indices
lat_pos, lon_pos = np.broadcast_to(lat_idx2, m.shape)[m], lon_idx[m]
# Add values
np.add.at(sum_cell, (lat_pos, lon_pos), data[m])
# Check result with previous method
sum_cell2 = np.zeros((121, 201))
for j in range(4800):
    for i in range(4800):
        if lat_idx[i] < 0 or lon_idx[i, j] < 0: 
            continue
        sum_cell2[lat_idx[i], lon_idx[i, j]] += data[i, j]
print(np.allclose(sum_cell, sum_cell2))
# True