簡體   English   中英

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

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM