2014-10-12 78 views
1

讓我們考慮一個numpy的陣列從長長的numpy數組中保留兩個元素的最快方法?

a = array([1,2,25,13,10,9,4,5]) 

含有偶數個元件。 我需要隨意到陣列的每兩個的僅一個元件保持: 第一或第二個,則第三或第四等 例如,使用一個,它應導致成:

c = array([1,13,9,5]) 
d = array([2,13,10,4]) 
e = array([2,25,10,5]) 

我必須在長陣列的上百個元素和上千個巨大的循環陣列上做這件事。什麼將是使用pair_index+random.randint(0,1) ,保持一個元素每隔三,四等,將是不錯;-) 感謝

結果的通用方法在兩個迭代元素和保存或刪除一個最快的算法:

import timeit 
import numpy 

def soluce1(): 
    k=2 
    a = numpy.array([1,2,25,13,10,9,4,5]) 
    aa = a.reshape(-1, k) 
    i = numpy.random.randint(k, size = aa.shape[0]) 
    return numpy.choose(i, aa.T) 
def soluce2(): 
    k=2 
    a = numpy.array([1,2,25,13,10,9,4,5]) 
    w = len(a) // k 
    i = numpy.random.randint(0, 2, w) + numpy.arange(0, 2 * w, 2) 
    return a[i] 
def random_skip(): 
    a= numpy.array([1,2,25,13,10,9,4,5]) 
    k=2 
    idx = numpy.arange(0, len(a), k) 
    idx += numpy.random.randint(k, size=len(idx)) 
    idx = numpy.clip(idx, 0, len(a)-1) 
    return a[idx] 


>  ts1=timeit.timeit(stmt='soluce1()',setup='from __main__ import soluce1',number=10000) 
> --> 161 µs 
>  ts2=timeit.timeit(stmt='soluce2()',setup='from __main__ import soluce2',number=10000) 
> --> 159 µs 
>  ts3=timeit.timeit(stmt='random_skip()',setup='from __main__ import random_skip',number=10000) 
> --> 166 µs 

似乎是等效的建議。再次感謝所有。

+0

http://stackoverflow.com/questions/1623849/fastest-way-to-zero-out-low-values-in-array – 2014-10-12 13:34:37

回答

1

一種解決方案可以是:

>>> xs 
array([ 1, 2, 25, 13, 10, 9, 4, 5]) 
>>> k = len(xs) // 2 
>>> i = np.random.randint(0, 2, k) + np.arange(0, 2 * k, 2) 
>>> xs[i] 
array([ 1, 13, 10, 5] 

推廣到其它步長,只要數組的長度是步長的倍數;說爲4步長:

>>> k = len(xs) // 4 
>>> i = np.random.randint(0, 4, k) + np.arange(0, 4 * k, 4) 
>>> xs[i] 
array([1, 5]) 

替代地

>>> np.apply_along_axis(np.random.choice, 1, xs.reshape(len(xs)/2, 2)) 
array([ 2, 13, 10, 4]) 
>>> np.apply_along_axis(np.random.choice, 1, xs.reshape(len(xs)/4, 4)) 
array([ 1, 10]) 
+0

而不是'4 * arange(k)',你可以使用'arange(0,4 * k,4)'。對於大'k',它大約快兩倍。 – 2014-10-12 13:54:59

+0

@WarrenWeckesser,這是非常真實的,事實上它可以比2更快的因數,這取決於數組的大小。 – 2014-10-12 16:31:46

4

可以使用花式索引選擇的元素,a[idx]

def random_skip(a, skipsize=2): 
    idx = np.arange(0, len(a), skipsize) 
    idx += np.random.randint(skipsize, size=len(idx)) 
    idx = np.clip(idx, 0, len(a)-1) 
    return a[idx]  


In [141]: a = array([1,2,25,13,10,9,4,5])   
In [142]: random_skip(a) 
Out[142]: array([ 1, 13, 9, 4]) 

In [143]: random_skip(a, skipsize=3) 
Out[143]: array([1, 9, 5]) 

In [144]: random_skip(a, skipsize=4) 
Out[144]: array([ 1, 10]) 

idx = np.arange(0, len(a), skipsize)在每個選擇第一項組。

idx += np.random.randint(skipsize, size=len(idx)) 隨機化索引到每個組中的某個項目。

idx = np.clip(idx, 0, len(a)-1)在skipsize不是a長度的倍數的情況下防止索引超出界限。

3

np.choose對於從一組數組或者2dim數組中選擇元素非常有用(而且快!)。所以,你可以重塑你的陣列是MX2,並使用切片np.choose

a = array([1,2,25,13,10,9,4,5]) 
k = 2 

aa = a.reshape(-1, k) # 1dim -> 2dim 
i = np.random.randint(k, size = aa.shape[0]) # random indices 
np.choose(i, aa.T) 
=> array([ 1, 13, 9, 4]) 
相關問題