1. 程式人生 > >Python vs Matlab—— find 與 np.where

Python vs Matlab—— find 與 np.where

1. matlab中的find函式

將陣列中的偶數值返回:

x = randperm(100, 10)
x(mod(x, 2) == 0)

matlab中find的函式的強大之處在於其能返回下標,且視返回引數的個數,返回以列全排序的一維下標(返回引數的個數為1),返回行列索引的二維座標(返回引數的個數為2):

>>A = [1, 2, 3; 1, 2, 3; 1, 2, 3]
>>idx = find(A > 2)
            % idx = 7 8 9   
>>A(idx)    % 3 3 3

% 當然也可以更簡潔地索引符合某一條件(predicate,斷言)的元素
>>A(A>2) >>[rows, cols] = find(A > 2) rows = 1 2 3 cols = 3 3 3

2. python:遍歷+判斷

>>a = [1, 2, 3, 1, 2, 3, 1, 2, 3]
>>idx = [idx for (idx, val) in enumerate(a) if val > 2]
>>idx
[2, 5, 8]
>>vals = [val for (idx, vals) in enumerate(a) if val
> 2] [3, 3, 3]

3. python numpy:np.where

python或者numpy中能夠返回符合某一條件的下標的函式是np.where(),不過np.where()並不接受list型別的引數,可見np.where()既可以接收三個引數,用於三目運算,也可接收一個引數,返回符合條件的下標。

>>a = np.array(a)
>>a
array([1, 2, 3, 1, 2, 3, 1, 2, 3])
>>idx = np.where(a > 2)
>>idx
(array([2, 5, 8], dtype=int32),)
>>a
[idx] # 這種做法並不推薦 array([3, 3, 3]) >>a[a>2] # 推薦的做法 array([3, 3, 3])

注意,這種情況下,也即 np.where() 用於返回斷言成立時的索引,返回值的形式為 arrays of tuple,由 np.array 構成的 tuple,一般 tuple 的 len 為2(當判斷的物件是多維陣列時),哪怕是一維陣列返回的仍是 tuple,此時tuple 的 len 為 1;

  • np.where()[0] 表示行的索引,
  • np.where()[1] 則表示列的索引

np.where()用於三目運算的情況:

>>y = np.array([1, 2, 3, 4, 5, 6])  # 將奇數轉換為偶數,偶數轉換為奇數
>>y = np.where(y%2 == 0, y+1, y-1)
>>y 
array([0, 3, 2, 5, 4, 7])

4. 處理NaN(not a number)

將nan所在的列非nan的均值賦給這些nan值

>>A = np.array([[1, 2, 3, 4], [5, 6, np.nan, 8], [9, 10, 11, np.nan]])
>>idx = np.where(np.isnan(A))
>>idx
(array([1, 2], dtype=int32), array([2, 3], dtype=int32))
for i in idx:
    A[i[0], i[1]] = A[~np.isnan(A[:, i[1]]), i[1]].mean()