2014-10-12 56 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]) 
相关问题