Список слов и эквивалентный массив:
In [153]: words = [' woRd ', ' amaZINg ', ' PossiblE ']
In [154]: arr = np.array(words)
Ваша операция с массивом:
In [155]: np.char.lower(np.char.strip(arr))
Out[155]: array(['word', 'amazing', 'possible'], dtype='<U15')
Эквивалентное понимание списка:
In [156]: [word.strip().lower() for word in words]
Out[156]: ['word', 'amazing', 'possible']
или с использованием генератор внутри понимания:
In [159]: [word.lower() for word in (word.strip() for word in words)]
Out[159]: ['word', 'amazing', 'possible']
Некоторые тайминги:
In [160]: timeit [word.lower() for word in (word.strip() for word in words)]
1.33 µs ± 10.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [161]: timeit [word.strip().lower() for word in words]
848 ns ± 13.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [162]: timeit np.char.lower(np.char.strip(arr))
12.3 µs ± 143 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
Понимание списка происходит быстрее всего. Иногда операции numpy лучше масштабируются, но, исходя из прошлого опыта работы с функциями np.char
, я не думаю, что здесь это произойдет. Функции np.char
являются простыми оболочками для строковых методов Python.
Хорошо, есть способ вызвать два метода python в строке и выполнить итерацию в numpy
:
In [164]: np.frompyfunc(lambda word: word.strip().lower(),1,1)(arr)
Out[164]: array(['word', 'amazing', 'possible'], dtype=object)
In [165]: timeit np.frompyfunc(lambda word: word.strip().lower(),1,1)(arr)
6.87 µs ± 14.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
Поскольку его время составляет половину связанного np.char
, можно сказать, что он сокращает временную сложность с 2n до n.
O(n)
отсчетов имеет смысл только в том случае, если вы используете те же методы итерация. Благодаря сочетанию интерпретируемого и скомпилированного кода, используемого Python / numpy, O (n) имеет ограниченное значение. Более важно оптимально использовать быстрее компилируемый код.