Numpy中的向量化分配

时间:2018-06-29 00:25:32

标签: python arrays numpy

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

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

但是,如果发生冲突,即对应于单个位置的多个浮动,则除最后一个浮动外的所有浮动都将被覆盖。有没有办法以某种方式汇总所有冲突,例如落在同一位置的所有浮子的均值或中位数?我想利用向量化的优势,并希望避免解释器循环。

谢谢!

3 个答案:

答案 0 :(得分: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. ]])

答案 1 :(得分:4)

您可以在if viewController == tabBarController.viewControllers?[3] { let menuRightNavigationController = storyboard!.instantiateViewController(withIdentifier: "RightMenuNavigationController") as! UISideMenuNavigationController SideMenuManager.default.menuRightNavigationController = menuRightNavigationController present(SideMenuManager.default.menuRightNavigationController!, animated: true, completion: nil) return false } 中操作数据,然后进行分配。

开始
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)

然后

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

整个操作(包括生成矩阵,d = get_aggregated_collisions(a,b,c) mat[d['x'], d['y']] = d['v'] 等)运行正常

np.random

制作1.05 s ± 30.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) 坐标的想法是要有一个可散列的选项,以便按坐标对值进行分组。也许有一种更聪明的方法可以做到这一点:)总是愿意接受建议。

答案 2 :(得分:2)

我的试验基于RafaelC的回答。

首先在[“ x”,“ y”]上进行groupby,然后取每个组的meanmedian,最后用reset_index()重设索引。

import pandas as np
# setup
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)
# Start here
df = pd.DataFrame({"x":a, "y":b, "val":c})
v = df.groupby(["x", "y"]).mean().reset_index()
mat[v["x"], v["y"]] += v["val"]

如果需要中位数,请将v修改为

v = df.groupby(["x", "y"]).median().reset_index()