[英]How to replace repeated consecutive elements in a 2d numpy array with single element
我有一個numpy的形狀數組(1080,960)
[[0 0 255 ... 0 0 0]
[0 0 0 ... 0 0 0]
[0 0 0 ... 255 0 0]
...
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
[0 255 255 ... 0 0 0]]
我想輸出一個用單個0和單個255替換0和255的重復值的numpy數組
numpy數組表示二進制圖像,其像素形式為BBBWWWWWWWBBBBBBWWW,其中B為黑色,W為白色。 我想將其轉換為BWBW。
范例 :
輸入:
[[0,0,0,255,255,255,0,0,0,0],
[255,255,255,0,0,0,255,255,255],
[0,0,255,0,0,255,0,0,255]]
輸出:
[[0,255,0],
[255,0,255]
[0,255,0,255,0,255]]
您可以遍歷行並通過構建新數組來對元素進行分組,同時檢查最后一個元素並僅在有差異時追加。
功能如下:
def groupRow(row):
newRow = [row[0]]
for elem in row:
if elem != newRow[-1]:
newRow.append(elem)
return newRow
使用該函數的newRow迭代並替換形狀中的每一行
您無法輸出2D numpy數組,因為輸出行的長度可能不同。 我會滿足於numpy數組的列表。 因此,首先讓我們生成一些數據:
img = np.random.choice([0,255], size=(1080, 960))
然后遍歷每一行:
out=[]
for row in img:
idx=np.ediff1d(row, to_begin=1).nonzero()[0]
out.append(row[idx])
通過求和,我們僅檢測變化發生的位置,然后使用這些索引idx
在連續的條紋中選擇起始元素。 此解決方案比@DavidWinder的解決方案簡單一些,並且速度更快(30毫秒對150毫秒)。
完全矢量化的解決方案可能會更快一些,但是代碼會有些復雜。 這將涉及到對數組進行展平,對索引進行np.split
和解散...並在末尾應用np.split
,這不是一個非常快的操作,因為它涉及創建列表。 因此,我認為這個答案足以在速度/代碼簡單性之間做出折衷。
如果首選輸出是末尾填充0的數組,則最好創建一個zeros數組並用out
列表的值填充它。 首先找出哪一行包含更多元素,然后創建數組:
max_elms = np.max([len(x) for x in out])
arr = np.zeros((1080, max_elms), dtype=np.int32)
然后遍歷out
列表和arr
,填充值arr
用在那些out
名單:
for row, data in zip(arr, out):
row[:len(data)] = data
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.