Python中的R函数rep()(复制列表/向量的元素)

时间:2012-09-02 11:23:06

标签: python

R函数rep()复制向量的每个元素:

> rep(c("A","B"), times=2)
[1] "A" "B" "A" "B"

这就像Python中的列表乘法:

>>> ["A","B"]*2
['A', 'B', 'A', 'B']

但是使用rep()R函数,还可以指定向量的每个元素的重复次数:

> rep(c("A","B"), times=c(2,3))
[1] "A" "A" "B" "B" "B"

Python中是否有这样的函数availbale?否则怎么定义呢?顺便说一句,我也对这种复制数组行的函数感兴趣。

8 个答案:

答案 0 :(得分:41)

使用numpy数组和numpy.repeat函数:

import numpy as np

x = np.array(["A", "B"])
print np.repeat(x, [2, 3], axis=0)

['A' 'A' 'B' 'B' 'B']

答案 1 :(得分:9)

不确定是否有可用的内置功能,但你可以尝试这样的事情:

>>> lis = ["A", "B"]
>>> times = (2, 3)
>>> sum(([x]*y for x,y in zip(lis, times)),[])
['A', 'A', 'B', 'B', 'B']

请注意sum()以二次方运行。所以,这不是推荐的方式。

>>> from itertools import chain, izip, starmap
>>> from operator import mul
>>> list(chain.from_iterable(starmap(mul, izip(lis, times))))
['A', 'A', 'B', 'B', 'B']

时间比较:

>>> lis = ["A", "B"] * 1000
>>> times = (2, 3) * 1000
>>> %timeit list(chain.from_iterable(starmap(mul, izip(lis, times))))
1000 loops, best of 3: 713 µs per loop
>>> %timeit sum(([x]*y for x,y in zip(lis, times)),[])
100 loops, best of 3: 15.4 ms per loop

答案 2 :(得分:5)

因为你说" array"并提到R.你可能想要使用numpy数组,然后使用:

import numpy as np
np.repeat(np.array([1,2]), [2,3])
编辑:既然你提到你想要重复行,我认为你应该使用numpy。 np.repeat有一个轴参数来执行此操作。

除此之外,或许:

from itertools import izip, chain, repeat
list(chain(*(repeat(a,b) for a, b in izip([1,2], [2,3]))))

因为它没有假设您有一个列表或字符串可以相乘。虽然我承认,将所有内容作为参数传递到链中可能并不完美,所以编写自己的迭代器可能会更好。

答案 3 :(得分:1)

l = ['A','B']
n = [2, 4]

您的示例使用已经可迭代的字符串。 您可以生成类似于列表的结果字符串。

''.join([e * m for e, m in zip(l, n)])
'AABBBB'

更新:此处不需要列表理解:

''.join(e * m for e, m in zip(l, n))
'AABBBB'

答案 4 :(得分:0)

您如何看待这种情况?

要重复一个值:

>>> repetitions=[]
>>> torep=3
>>> nrep=5
>>> for i in range(nrep):
>>>     i=torep
>>>     repetitions.append(i)
[3, 3, 3, 3, 3]

要重复序列:

>>> repetitions=[]
>>> torep=[1,2,3,4]
>>> nrep= 2
>>> for i in range(nrep):
>>>     repetitions=repetitions+torep
>>> print(repetitions)
[1, 2, 3, 4, 1, 2, 3, 4]

答案 5 :(得分:0)

以下内容可能对您有用:

>>>[['a','b'],['A','B']]*5


[['a', 'b'], ['A', 'B'], ['a', 'b'], ['A', 'B'], ['a', 'b'], ['A', 'B'], ['a', 'b'], ['A', 'B'], ['a', 'b'], ['A', 'B']]

答案 6 :(得分:0)

已经提到了numpy.repeat,这显然与您想要的等效。但是出于完整性考虑,repeat标准库中也有itertools。但是,这通常用于可迭代对象,因此不允许按索引重复(因为可迭代对象通常未定义索引)。

我们可以使用此处给出的代码作为粗略的等效方法

def repeat(object, times=None):
    # repeat(10, 3) --> 10 10 10
    if times is None:
        while True:
            yield object
    else:
        for i in xrange(times):
            yield object

定义我们自己的广义重复:

def repeat_generalised(object, times=None):
    # repeat(10, 3) --> 10 10 10
    if times is None:
        while True:
            yield object
    else:
        for reps, elem in zip(times, object):
            for i in xrange(reps): 
                yield elem

当然,问题在于,您必须定义很多可能的极端情况(如果对象和时间具有不同数量的元素,会发生什么情况?),这取决于您的个别用例。

答案 7 :(得分:0)

这是我尝试克隆R rep

def rep(x, times = 1, each = 1, length_out = None):
    if not isinstance(times, list):
        times = [times]

    res = ''.join([str(i) * each for i in x])

    if len(times) > 1:   
        res = ''.join(str(i) * m for i, m in zip(x, times))
    else:
        res = ''.join(res * times[0])
    
    if length_out is None:
        return res
    else:
        return res[0:length_out]

复制R示例:

rep(range(4), times = 2)
rep(range(4), each = 2)
rep(range(4), times = [2,2,2,2])
rep(range(4), each = 2, length_out = 4)
rep(range(4), each = 2, times = 3)

,除了没有回收较短的向量/列表(这是R最糟糕的功能)之外。