亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Numpy 將較小的矩陣添加到較大的矩陣

Numpy 將較小的矩陣添加到較大的矩陣

慕萊塢森 2022-10-11 10:18:21
我有大的 3D 矩陣,指示代理在 3D 空間中的位置。如果上面沒有代理,則矩陣的值為 0,如果上面有代理,則為 1。然后,我的問題是我希望代理“成長”,因為我希望它們由一個立方體(3x3x3)決定。如果已經有辦法做到這一點,但是當代理靠近邊界時我遇到了麻煩。例如,我有一個位置矩陣 100x100x100,如果我知道我的代理在位置 (x, y, z) 我會這樣做:positions_matrix = numpy.zeros((100, 100, 100)) positions_matrix[x - 1: x + 2, y - 1: y + 2, z - 1: z + 2] +=  numpy.ones((3, 3, 3))當然,在我的真實代碼中,我會循環更多位置,但基本上就是這樣。這是可行的,但是當代理接近無法求和的邊界時,問題就來了,因為切片得到的矩陣將小于那些矩陣。知道如何解決它,或者 numpy 或任何其他包是否有這個實現?雖然我很確定我不是第一個面對這個問題的人,但我找不到它。
查看完整描述

3 回答

?
慕斯王

TA貢獻1864條經驗 獲得超2個贊

解決問題的更程序化的方法:


import numpy as np



m = np.zeros((100, 100, 100))


slicing = tuple(

    slice(max(0, x_i - 1), min(x_i + 2, d - 1))

    for x_i, d in zip((x, y, z), m.shape))

ones_shape = tuple(s.stop - s.start for s in slicing)


m[slicing] += np.ones(ones_shape)

但在其他方面與接受的答案相同。



查看完整回答
反對 回復 2022-10-11
?
小怪獸愛吃肉

TA貢獻1852條經驗 獲得超1個贊

您應該使用以下方法在下限和上限處進行切割:


import numpy as np

m = np.zeros((100, 100, 100))


x_min, x_max = np.max([0, x-1]), np.min([x+2, m.shape[0]-1])

y_min, y_max = np.max([0, y-1]), np.min([y+2, m.shape[1]-1])

z_min, z_max = np.max([0, z-1]), np.min([z+2, m.shape[2]-1])


m[x_min:x_max, y_min:y_max, z_min:z_max] += np.ones((x_max-x_min, y_max-y_min, z_max-z_min))


查看完整回答
反對 回復 2022-10-11
?
慕標琳琳

TA貢獻1830條經驗 獲得超9個贊

有一個使用np.put, 及其'clip'選項的解決方案。它只需要一點技巧,因為該函數需要扁平矩陣中的索引;幸運的是,該功能np.ravel_multi_index完成了這項工作:


import itertools

import numpy as np

x, y, z = 2, 0, 4

positions_matrix = np.zeros((100,100,100))


indices = np.array( list( itertools.product( (x-1, x, x+1), (y-1, y, y+1), (z-1, z, z+1)) ))

flat_indices = np.ravel_multi_index(indices.T, positions_matrix.shape, mode='clip')

positions_matrix.put(flat_indices, 1+positions_matrix.take(flat_indices))

# positions_matrix[2,1,4] is now 1.0

這個解決方案的好處是您可以使用其他模式,例如'wrap'(如果您的代理住在甜甜圈上;-) 或周期性空間)。


我將解釋它如何在較小的 2D 矩陣上工作:


import itertools

import numpy as np


positions_matrix = np.zeros((8,8))

ones = np.ones((3,3))

x, y = 0, 4


indices = np.array( list( itertools.product( (x-1, x, x+1), (y-1, y, y+1) )))

# array([[-1,  3],

#        [-1,  4],

#        [-1,  5],

#        [ 0,  3],

#        [ 0,  4],

#        [ 0,  5],

#        [ 1,  3],

#        [ 1,  4],

#        [ 1,  5]])


flat_indices = np.ravel_multi_index(indices.T, positions_matrix.shape, mode='clip')

# array([ 3,  4,  5,  3,  4,  5, 11, 12, 13])


positions_matrix.put(flat_indices, ones, mode='clip')

# positions_matrix is now:

# array([[0., 0., 0., 1., 1., 1., 0., 0.],

#        [0., 0., 0., 1., 1., 1., 0., 0.],

#        [0., 0., 0., 0., 0., 0., 0., 0.],

#        [ ...

順便說一句,在這種情況下mode='clip'是多余的put。


好吧,我只是作弊put做作業。+=1需要take和put:_


positions_matrix.put(flat_indices, ones.flat + positions_matrix.take(flat_indices))

# notice that ones has to be flattened, or alternatively the result of take could be reshaped (3,3)

# positions_matrix is now: 

# array([[0., 0., 0., 2., 2., 2., 0., 0.],

#        [0., 0., 0., 2., 2., 2., 0., 0.],

#        [0., 0., 0., 0., 0., 0., 0., 0.],

#        [ ...

與其他解決方案相比,此解決方案有一個重要區別:ones矩陣始終為 (3,3),這可能是優勢,也可能不是優勢。訣竅就在這個 flat_indices 列表中,它有重復的條目(剪輯的結果)。


因此,如果您在最大索引處添加非常數子矩陣,則可能需要采取一些預防措施:


x, y = 1, 7

values = 1 + np.arange(9)

indices = np.array( list( itertools.product( (x-1, x, x+1), (y-1, y, y+1) )))

flat_indices = np.ravel_multi_index(indices.T, positions_matrix.shape, mode='clip')

positions_matrix.put(flat_indices, values, mode='clip')

# positions_matrix is now:

# array([[0., 0., 0., 2., 2., 2., 1., 3.],

#        [0., 0., 0., 2., 2., 2., 4., 6.],

#        [0., 0., 0., 0., 0., 0., 7., 9.],

...您可能期望最后一列是 2 5 8。目前,您可以處理flat_indices,例如通過放置-1越界位置。但是,如果np.put接受非平面索引,或者如果有一個 clip ,這一切都會更容易mode='ignore'。


查看完整回答
反對 回復 2022-10-11
  • 3 回答
  • 0 關注
  • 170 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號