2013-07-24 612 views
2

如何計算ndarray中每個數據點的元素數量?計算numpy ndarray中元素的數量

我想要做的是對我的ndarray中至少存在N次的所有值運行OneHotEncoder。

我也想用另一個它不出現在數組中的元素(我們稱之爲new_value)替換出現少於N次的所有值。

因此,例如,我有:

import numpy as np 

a = np.array([[[2], [2,3], [3,34]], 
       [[3], [4,5], [3,34]], 
       [[3], [2,3], [3,4] ]]]) 

與閾值N = 2我想是這樣的:

b = [OneHotEncoder(a[:,[i]])[0] if count(a[:,[i]])>2 
else OneHotEncoder(new_value) for i in range(a.shape(1)] 

所以才明白,我想換人,不考慮onehotencoder和使用new_value = 10我的數組應該看起來像:

a = np.array([[[10], [2,3], [3,34]], 
       [[3], [10], [3,34]], 
       [[3], [2,3], [10] ]]]) 
+1

你真的需要有列表數組嗎?這會非常嚴重地破壞numpy。通常由快速C函數調用處理的許多操作(比如相等比較)現在必須被中繼到昂貴的Python調用。 @Ophion的代碼按照陳述解決了你的問題,但是你應該認真考慮一下不同的方法(用np.nan的浮點數組,還是用例如-1表示缺失值的int整數),它們可以讓你利用numpy的功能最充分的是不是一個更好的選擇。 – Jaime

+0

這個結構就像是考慮各種各樣的bigrams/trigrams combinatinon 如果我有條目[3,2,1],那麼我想考慮unigrams [3],[2],[1],但也可以是bigrams [ 3,2]和[2,1],因此條目將變爲[[3],[2],[1],[3,2],[2,1]] 我沒有編寫代碼,我不想修改它,因爲它非常複雜,我只是想看看性能(就修正後的預測而言)是否會增加對罕見事件的過濾並將它們全部放在同一類別中。 但是可能你很厲害,我應該加快速度,因爲我無論如何都在等待。 – user2616532

回答

6

這樣的事情呢?

第一計數unqiue元件的數量在一個陣列:

>>> a=np.random.randint(0,5,(3,3)) 
>>> a 
array([[0, 1, 4], 
     [0, 2, 4], 
     [2, 4, 0]]) 
>>> ua,uind=np.unique(a,return_inverse=True) 
>>> count=np.bincount(uind) 
>>> ua 
array([0, 1, 2, 4]) 
>>> count 
array([3, 1, 2, 3]) 

uacount陣列它表明0表示了3次,圖1示出了1次,等等。

import numpy as np 

def mask_fewest(arr,thresh,replace): 
    ua,uind=np.unique(arr,return_inverse=True) 
    count=np.bincount(uind) 
    #Here ua has all of the unique elements, count will have the number of times 
    #each appears. 


    #@Jamie's suggestion to make the rep_mask faster. 
    rep_mask = np.in1d(uind, np.where(count < thresh)) 
    #Find which elements do not appear at least `thresh` times and create a mask 

    arr.flat[rep_mask]=replace 
    #Replace elements based on above mask. 

    return arr 


>>> a=np.random.randint(2,8,(4,4)) 
[[6 7 7 3] 
[7 5 4 3] 
[3 5 2 3] 
[3 3 7 7]] 


>>> mask_fewest(a,5,50) 
[[10 7 7 3] 
[ 7 5 10 3] 
[ 3 5 10 3] 
[ 3 3 7 7]] 

對於上面的例子:讓我知道你是否打算使用2D數組或3D數組。

>>> a 
[[[2] [2, 3] [3, 34]] 
[[3] [4, 5] [3, 34]] 
[[3] [2, 3] [3, 4]]] 


>>> mask_fewest(a,2,10) 
[[10 [2, 3] [3, 34]] 
[[3] 10 [3, 34]] 
[[3] [2, 3] 10]] 
+0

非常感謝,但是當我寫了[3,4]時,我的意思是一個有兩個元素的數組,並且是的,我的數據集將會非常大 – user2616532

+2

+1如果我有任何錢,我很快就會下注'np.count_unique'函數調用'np.unique'返回的索引中的'np.bincount',並且'return_inverse = True',這是一個我發現自己一遍又一遍地打字的結構。作爲一個潛在的改進,我對你正在構建的二維數組有點困擾,並且爲計算掩碼而崩潰:這種欺騙通常非常嚴重。我發現對於大型數據集來說,速度要快得多,而對於真正的小數據集,速度要慢得多:'rep_mask = np.in1d(a,ua [count Jaime

+0

@Jaime:感謝您的評論,我忘記了'np.in1d'。我一直在查找'np.intersect1d',並知道我錯過了一些東西。作爲一個方面說明,我認爲這將很難修改以實際回答OP的問題,因爲他需要一個'object array'-它應該被刪除嗎? – Daniel