Python numpy相当于R rep和rep_len函数

时间:2017-09-12 02:19:38

标签: python r numpy recycle

我想找到py {(numpy是可能的) - 等价的R reprep_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"

如何回收列表或1-d 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

如何使用python发生这种情况(使列表或numpy数组的循环元素符合预定长度并连续按预定次数列出每个元素)?

如果以前曾问过这个问题,我道歉;我一般都是新的堆栈溢出和一般的编程新手。

5 个答案:

答案 0 :(得分:4)

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]

答案 1 :(得分: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')

答案 2 :(得分:1)

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

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

转换为 - &gt;

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

答案 3 :(得分:1)

numpy.repeat()就像R的rep()函数一样,每个= True。当每个= False时,可以通过转置来实现回收:

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)

例如,如果我们设置each = True:

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

......我们得到:

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

但是当每个=假:

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

......结果是:

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

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

答案 4 :(得分: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的乘积,它将默认为lambda形式的Psidom的np_rep函数。