Можно ли умножить строку на целое число, используя умножение числа? - PullRequest
1 голос
/ 23 сентября 2019

Я пытаюсь поэлементно умножить два массива на одну строку.

Кто-нибудь может посоветовать?

import numpy as np


def array_translate(array):

    intlist = [x for x in array if isinstance(x, int)]
    strlist = [x for x in array if isinstance(x, str)]
    joinedlist = np.multiply(intlist, strlist)
    return "".join(joinedlist)


print(array_translate(["Cat", 2, "Dog", 3, "Mouse", 1]))    # => "CatCatDogDogDogMouse"

Я получаю эту ошибку:

File "/Users/peteryoon/PycharmProjects/Test3/Test3.py", line 8, in array_translate
    joinedlist = np.multiply(intlist, strlist)
numpy.core._exceptions.UFuncTypeError: ufunc 'multiply' did not contain a loop with signature matching types (dtype('<U21'), dtype('<U21')) -> dtype('<U21')

Мне удалось решить с использованием списка понимания ниже.Но любопытно посмотреть, как работает NumPy.

def array_translate(array):

    intlist = [x for x in array if isinstance(x, int)]
    strlist = [x for x in array if isinstance(x, str)]
    return "".join(intlist*strlist for intlist, strlist in zip(intlist, strlist))


print(array_translate(["Cat", 2, "Dog", 3, "Mouse", 1]))    # => "CatCatDogDogDogMouse"

Ответы [ 2 ]

4 голосов
/ 23 сентября 2019
In [79]: arr = np.array(['Cat','Dog','Mouse'])                                  
In [80]: cnt = np.array([2,3,1])  

Сроки для различных альтернатив.Относительное размещение может варьироваться в зависимости от размера массивов (и от того, начинаете ли вы со списков или массивов).Так что проведите собственное тестирование:

In [93]: timeit ''.join(np.repeat(arr,cnt))                                     
7.98 µs ± 57.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [94]: timeit ''.join([str(wd)*i for wd,i in zip(arr,cnt)])                   
5.96 µs ± 167 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [95]: timeit ''.join(arr.astype(object)*cnt)                                 
13.3 µs ± 50.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [96]: timeit ''.join(np.char.multiply(arr,cnt))                              
27.4 µs ± 307 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [100]: timeit ''.join(np.frompyfunc(lambda w,i: w*i,2,1)(arr,cnt))           
10.4 µs ± 164 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [101]: %%timeit f = np.frompyfunc(lambda w,i: w*i,2,1) 
     ...: ''.join(f(arr,cnt))                                                                       
7.95 µs ± 93.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [102]: %%timeit x=arr.tolist(); y=cnt.tolist() 
     ...: ''.join([str(wd)*i for wd,i in zip(x,y)])                                                                      
1.36 µs ± 39.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

np.repeat работает для всех видов массивов.

Для понимания списка используется умножение строк, и его нельзя сбрасывать со счетов.Часто это происходит быстрее, особенно если начать со списков.

Объект dtype преобразует строку dtype в строки Python, а затем делегирует действие для умножения строки.

np.char применяет строковые методы кэлементы массива.Хотя это удобно, оно редко быстрая.

edit

In [104]: timeit ''.join(np.repeat(arr,cnt).tolist())                           
4.04 µs ± 197 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
3 голосов
/ 23 сентября 2019

возможно, используя повтор

z = array(['Cat', 'Dog', 'Mouse'], dtype='<U5')
"".join(np.repeat(z, (2, 3, 1)))
'CatCatDogDogDogMouse'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...