Numpy中的矢量化作业

Cin*_*hty 9 python arrays numpy

假设我有一个大的2D numpy数组,例如1000x1000个元素.我还有两个长度为L的1D整数数组,以及一个长度相同的float 1D arrray.如果我想根据整数数组简单地将浮点数分配给原始数组中的不同位置,我可以写:

mat = np.zeros((1000,1000))
int1 = np.random.randint(0,999,size=(50000,))
int2 = np.random.randint(0,999,size=(50000,))
f = np.random.rand(50000)
mat[int1,int2] = f
Run Code Online (Sandbox Code Playgroud)

但是如果存在冲突,即多个浮点数对应于单个位置,则除了最后一个浮点数之外的所有浮点数都将被覆盖.有没有办法以某种方式聚合所有碰撞,例如落在同一位置的所有浮子的平均值或中位数?我想利用矢量化,希望避免解释器循环.

谢谢!

Jul*_*ien 5

基于hpaulj的建议,以下是如何在发生碰撞时获得平均值:

import numpy as np

mat = np.zeros((2,2))
int1 = np.zeros(2, dtype=int)
int2 = np.zeros(2, dtype=int)
f = np.array([0,1])

np.add.at(mat, [int1, int2], f)
n = np.zeros((2,2))
np.add.at(n, [int1, int2], 1)
mat[int1, int2] /= n[int1, int2]
print(mat)

array([[0.5, 0. ],
       [0. , 0. ]])
Run Code Online (Sandbox Code Playgroud)


raf*_*elc 5

您可以操作您的数据pandas,然后分配。

从...开始

mat = np.zeros((1000,1000))
a = np.random.randint(0,999,size=(50000,))
b = np.random.randint(0,999,size=(50000,))
c = np.random.rand(50000)
Run Code Online (Sandbox Code Playgroud)

你可以定义一个函数

def get_aggregated_collisions(a,b,c):
    df = pd.DataFrame({'x':a, 'y':b, 'v':c})
    df['coord'] = df[['x','y']].apply(tuple,1)
    d = df.groupby('coord').agg({"v":'mean','x':'first', 'y':'first'}).to_dict('list')
    return d
Run Code Online (Sandbox Code Playgroud)

进而

d = get_aggregated_collisions(a,b,c)
mat[d['x'], d['y']] = d['v']
Run Code Online (Sandbox Code Playgroud)

整个操作(包括生成矩阵np.random等)运行良好

1.05 s ± 30.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Run Code Online (Sandbox Code Playgroud)

制作 a tupleof 坐标背后的想法是有一个可散列的选项来按坐标对值进行分组。也许有更聪明的方法来做到这一点:) 总是对建议持开放态度。