簡體   English   中英

numpy交換數組中的多個元素

[英]numpy swap multiple elements in an array

我有一個包含 1 和 0 隨機分布的 numpy 數組。 我想用 0 替換所有的 1,用 1 替換所有的零。

arr[arr == 0] = 2
arr[arr == 1] = 0
arr[arr == 2] = 1

我目前必須使用一個臨時值(在這種情況下為 2),以避免所有 0 變為 1,然后使整個數組充滿 0。 有沒有更優雅/有效的方法來做到這一點?

您可以在覆蓋任何值之前計算和存儲您的布爾索引器:

ones = a == 1
zeros = a == 0

a[ones] = 0
a[zeros] = 1

如果您有01以外的值,該解決方案也有效。


如果您不需要就地解決方案,您可以使用np.where

a = np.where(ones, 0, np.where(zeros, 1, a))

這是一個非常適合您的問題的解決方案,但也應該非常快。 鑒於數組:

>>> a
array([[1, 0, 0, 1],
       [1, 1, 1, 0]])

您可以從所有值中減去 1,然后乘以負 1:

>>> (a-1)*-1
array([[0, 1, 1, 0],
       [0, 0, 0, 1]])

對於您的特定值與 1 按位異或。

In [19]: a=np.random.randint(2, size=10)

In [18]: a
Out[18]: array([1, 1, 1, 1, 1, 1, 0, 0, 1, 1])

In [19]: a^1
Out[19]: array([0, 0, 0, 0, 0, 0, 1, 1, 0, 0])

int 類型的更通用的解決方案。

In [62]: convert=np.array([1,0])

In [63]: convert[a]
Out[63]: array([0, 0, 0, 0, 0, 0, 1, 1, 0, 0])

更改 'convert' 數組的內容意味着可以映射一系列值。 結果使用數組 'a' 的內容作為數組 'convert' 的索引。

給定的

>>> a
array([[1, 0, 0, 1],
       [1, 1, 1, 0]])

你可以使用numpy.where

>>> np.where(a == 0, 1, 0) # read as (if, then, else)
array([[0, 1, 1, 0],
       [0, 0, 0, 1]])

... 或者否定a並進行一些類型轉換。

>>> (~a.astype(bool)).astype(int)
array([[0, 1, 1, 0],
       [0, 0, 0, 1]])

(IPython) 時間:差別不大。

>>> a = np.eye(1000, dtype=int)
>>> %timeit np.where(a == 0, 1, 0)
1.56 ms ± 2.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
>>> %timeit (~a.astype(bool)).astype(int)
1.74 ms ± 87.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

其他人回答的時間:

>>> %timeit a^1 # Tls Chris
920 µs ± 31.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
>>> %timeit np.array([1, 0])[a] # Tls Chris
1.4 ms ± 102 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
>>> %timeit (a - 1)*-1 # sacul
1.57 ms ± 13.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
>>> %timeit 1 - a # user3483203
905 µs ± 2.16 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

我的意見: a^11 - a是干凈、優雅和快速的。 使用np.where可以處理您可能想要交換的任何值。

如果有效的解決方案比優雅的解決方案更重要,您可以編寫一個非常簡單的Numba解決方案。

例子

import numba as nb
import numpy as np

@nb.njit()
def nb_where(arr):
  for i in range(arr.shape[0]):
    for j in range(arr.shape[1]):
      if arr[i,j]==1:
        arr[i,j] = 0
      else:
        arr[i,j] = 1
  return arr

時間安排

a = np.eye(1000, dtype=int)
np.where(a == 0, 1, 0) #timgeb    -> 2.06ms 
a^1                    #Tls Chris -> 1.31ms 
nb_where(a)                       -> 152 µs

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM