[英]R function rep() in Python (replicates elements of a list/vector)
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 中是否有這樣的函數可用? 不然怎么定義呢? 順便說一下,我也對這樣一個用於復制數組行的函數感興趣。
使用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']
不確定是否有可用的內置函數,但您可以嘗試以下操作:
>>> 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
既然你說“數組”並提到 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]))))
因為它沒有假設你有一個列表或字符串要相乘。 盡管我承認,將所有內容作為參數傳遞到鏈中可能並不完美,因此編寫自己的迭代器可能會更好。
你怎么看這種方式?
重復一個值:
>>> 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]
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'
以下可能對您有用:
>>>[['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']]
已經提到了numpy.repeat
,這顯然等同於您想要的。 但為了完整起見, itertools
標准庫中也有repeat
。 但是,這通常用於可迭代對象,因此它不允許按索引重復(因為通常可迭代對象沒有定義索引)。
我們可以使用那里給出的代碼作為粗略的等價物
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
當然,問題是您必須定義很多可能的邊緣情況(如果對象和時間具有不同數量的元素會發生什么?),這取決於您的個人用例。
這是我對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)
除了沒有更短的向量/列表的回收(imo這是R
最糟糕的特性)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.