2017-09-12 141 views
3

我想找到python(numpy是可能的) - 等效的R reprep_len函数。Python的numpy当量的R rep和rep_len函数

问题1:关于rep_len功能,说我跑,

rep_len(paste('q',1:4,sep=""), length.out = 7) 

然后载体['q1','q2','q3','q4']的元素将被回收,以填补7位,你会得到输出

[1] "q1" "q2" "q3" "q4" "q1" "q2" "q3" 

我该如何做一个列表或一维numpy数组的循环元素以适应预定的长度?从我看到的numpy的重复功能可以指定一定数量的代表,但不会重复填充预定长度的值。

问题2:关于rep功能,说我跑,

rep(2000:2004, each = 3, length.out = 14) 

然后输出

[1] 2000 2000 2000 2001 2001 2001 2002 2002 2002 2003 2003 2003 2004 2004 

我怎么能做出这样(列表或numpy的阵列的回收元素以适应预定的长度,并连续列出每个元素预定的次数)发生使用python?

我很抱歉,如果这个问题之前已经问过;我对堆栈溢出是完全陌生的,对编程来说也是新的。

回答

2

对于rep_len,类似的numpy方法是np.tile,但它不提供length.out参数;但是你可以用slice很容易地实现它:

x = ['q1', 'q2', 'q3', 'q4'] 
def np_rep_len(x, length_out): 
    return np.tile(x, length_out // len(x) + 1)[:length_out] 

np_rep_len(x, 7) 
# array(['q1', 'q2', 'q3', 'q4', 'q1', 'q2', 'q3'], 
#  dtype='<U2') 

对于rep法,numpy的当量为numpy.repeat,你也需要实现length.out与片:

def np_rep(x, repeat, length_out): 
    return np.repeat(x, repeat)[:length_out] 

np_rep(x, 3, 10) 
# array(['q1', 'q1', 'q1', 'q2', 'q2', 'q2', 'q3', 'q3', 'q3', 'q4'], 
#  dtype='<U2') 
1

您可以使用如果你愿意的话,可以将乘法和切片与python内建的隐式迭代相结合。 (我知道你想要一个numpy的解决方案,但我只是想出这个不能伤害...)

rep_len(paste('q',1:4,sep=""), length.out = 7) 

转化为 - >

(["q"+str(k) for k in range(1,5)]*(7/4+1))[:7] 
+0

啊,是的,这是非常真实的。感谢您的答复! –

3

NumPy的实际执行提供了rep_len等效。这是numpy.resize

new_arr = numpy.resize(arr, new_len) 

注意,resize方法垫用零来代替重复的元素,所以arr.resize(new_len)没有你想要什么。

至于rep,我知道没有等价物。有numpy.repeat,但它不允许你限制输出的长度。 (重复全矢量功能也有numpy.tile,但同样没有length.out等效。)您可以对结果进行分割,但它仍然会花费所有时间和内存来生成未截断的数组:

new_arr = numpy.repeat(arr, repetitions)[:new_len] 
+0

感谢np.resize info..I确保将来使用np.resize。此外,感谢您让我知道生成未截断数组所花费的时间/内存。 –

0

在评论Psidom的np_rep函数时,我相信R的rep函数(使用each =参数)的一个附加特性是它将重复使用重复向量中的元素,直到达到由length.out指定的长度。例如,

rep(2000:2001, each = 4, length.out = 15) 

返回

[1] 2000 2000 2000 2000 2001 2001 2001 2001 2000 2000 2000 2000 2001 2001[15] 2001 

。在Python,定义np_rep如Psidom定义它,

def np_rep(x, repeat, length_out): 
    return np.repeat(x, repeat)[:length_out] 

和呼叫

np_rep(list(range(2000,2002)), repeat = 4, length_out = 15) 

,输出是

array([2000, 2000, 2000, 2000, 2001, 2001, 2001, 2001]) 

;所以该函数不会回收以达到所需的长度,而是会在参数x的元素重复参数重复次数后停止。

我相信以下将正常运行,包含了版本回收:

def repeat_recycle(x, repeat, length_out): 
    rep = lambda x,length_out,repeat:np.repeat(x,repeat)[:length_out] 
    repeated = rep(x, length_out, repeat) 
    if len(x)*repeat >= length_out: 
     return repeated 
    v = [None for i in range(length_out)] 
    n = len(repeated) 
    for i in range(length_out): 
     v[i] = repeated[i%n] 
    return np.array(v) 

呼叫,

repeat_recycle(list(range(2000,2002)), repeat = 4, length_out = 15) 

回报

array([2000, 2000, 2000, 2000, 2001, 2001, 2001, 2001, 2000, 2000, 2000, 
    2000, 2001, 2001, 2001]) 

,这是循环使用的版本,填补增加15个元素。

如果length_out不超过len(x)和repeat的乘积,它将默认为Psidom的np_rep函数的lambda表单。

1

numpy.repeat()的行为就像R的rep()函数,每个= True。当每个=假,循环利用,可通过换位来实现:

import numpy as np 

def np_rep(x, reps=1, each=False, length=0): 
    """ implementation of functionality of rep() and rep_len() from R 

    Attributes: 
     x: numpy array, which will be flattened 
     reps: int, number of times x should be repeated 
     each: logical; should each element be repeated reps times before the next 
     length: int, length desired; if >0, overrides reps argument 
    """ 
    if length > 0: 
     reps = np.int(np.ceil(length/x.size)) 
    x = np.repeat(x, reps) 
    if(not each): 
     x = x.reshape(-1, reps).T.ravel() 
    if length > 0: 
     x = x[0:length] 
    return(x) 

为,例如,如果我们设置每个= TRUE:

np_rep(np.array(['tinny', 'woody', 'words'], reps=3, each=True) 

...我们得到:

array(['tinny', 'tinny', 'tinny', 'woody', 'woody', 'woody', 'words', 'words', 'words'], 
    dtype='<U5') 

但是当每个= False时:

np_rep(np.array(['tinny', 'woody', 'words']), reps=3, each=False) 

...结果是:

array(['tinny', 'woody', 'words', 'tinny', 'woody', 'words', 'tinny', 'woody', 'words'], 
    dtype='<U5') 

请注意,x变平了,结果也变平了。要实现长度参数,需要计算所需的最少次数,然后将结果截断为所需的长度。