【问题标题】:Increment 3D array of counters from 2D list of indices (x,y,z) using: Python Numpy Slicing使用 Python Numpy Slicing 从 2D 索引列表 (x,y,z) 增加 3D 计数器数组
【发布时间】:2018-01-24 09:18:15
【问题描述】:

我想从 2D 事件数组 (x,y,t) 中增加计数器的 3D 矩阵 (nparray) 下面的代码有效:

TOF_cube=np.zeros((324,324,4095),np.int32) #initialise a 3d array for whole data set

data = np.fromfile(f, dtype='<i2', count=no_I16) #read all events, x,y,t as 1D array
data=data.reshape(events,cols)
xpos=data[:,0]
ypos=data[:,1]
tpos=data[:,2]
i=0
while i < events:              
    TOF_cube[xpos[i],ypos[i],tpos[i]] += 1
    i+=1

为了使用切片和索引,我用

替换了我的 while 循环
    TOF_cube[xpos,ypos,tpos] += 1

但不是复制正确的 4365520 个事件(通过 while 循环并独立检查),我只记录 4365197。

为什么切片方法会丢失事件?

我在 while 循环中使用完全相同的切片并作为索引的“参数”。

【问题讨论】:

  • 每种方法的TOF_cube.max() 是什么?

标签: python numpy indexing slice


【解决方案1】:

如果有重复索引,+= 不会添加两次。

要以矢量化方式获得等效输出,您需要np.add.at

np.add.at(TOF_cube, [xpos, ypos, tpos], 1)

【讨论】:

  • 谢谢!是这个问题,谢谢!我很惊讶np.add.at(TOF_cube, [xpos, ypos, tpos], 1). 的运行速度似乎比 += 版本慢很多。 (我知道我错过了一些活动,但很少)。有人会认为+= 必须执行IF duplicated: ignore 检查np.add 循环的位置。有什么想法吗?谢谢 D
  • += 构造不像np.add.at 那样是顺序的,它是一个并行(线程)调用来增加一组内存位置。这就是为什么它只能增加一次任何东西(并通过set 运行位置以确保没有重复) - 否则这些单独的线程可能会锁定,因为两个线程试图同时增加相同的内存位。
  • 如果答案是你要找的,别忘了标记检查。
【解决方案2】:

由于我们不确切知道您的数据是什么样的,因此很难猜测实际问题是什么。如果这没有帮助,请举例说明我们可以自己运行(即没有文件f)。

假设你有x_pos = [1,1,2,3,5]

a = np.zeros(10)
for i in range(len(x_pos)):
    a[x_pos[i]]+=1
# gives a = array([ 0.,  2.,  1.,  1.,  0.,  1.,  0.,  0.,  0.,  0.])

但是其他代码

a[x_pos]+=1
# gives a = array([ 0.,  1.,  1.,  1.,  0.,  1.,  0.,  0.,  0.,  0.])

因此,如果其中一个索引出现两次,它只会在短版本中更新一次。检查您的 xpos 等是否确实是这种情况。

PS:我做了一个稍微简单的版本,只有一个维度,但规则保持不变。

【讨论】:

  • 您已经准确地发现了问题,谢谢!完全修复了建议np.add.at(TOF_cube, [xpos, ypos, tpos], 1)
猜你喜欢
  • 1970-01-01
  • 2019-12-23
  • 1970-01-01
  • 2012-09-30
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
  • 2016-02-10
  • 1970-01-01
相关资源
最近更新 更多