Использование \b
может дать неожиданные результаты. Вам будет лучше выяснить, что отделяет слово от его определения и включает эту информацию в ваш шаблон.
#!/usr/bin/perl
use strict; use warnings;
use re 'debug';
my $str = 'S.P.E.C.T.R.E. (Special Executive for Counter-intelligence,
Terrorism, Revenge and Extortion) is a fictional global terrorist
organisation';
my $word = 'S.P.E.C.T.R.E.';
if ( $str =~ /\b(\Q$word\E)\b/ ) {
print $1, "\n";
}
Выход:
Compiling REx "\b(S\.P\.E\.C\.T\.R\.E\.)\b" Final program: 1: BOUND (2) 2: OPEN1 (4) 4: EXACT (9) 9: CLOSE1 (11) 11: BOUND (12) 12: END (0) anchored "S.P.E.C.T.R.E." at 0 (checking anchored) stclass BOUND minlen 14 Guessing start of match in sv for REx "\b(S\.P\.E\.C\.T\.R\.E\.)\b" against "S.P .E.C.T.R.E. (Special Executive for Counter-intelligence,"... Found anchored substr "S.P.E.C.T.R.E." at offset 0... start_shift: 0 check_at: 0 s: 0 endpos: 1 Does not contradict STCLASS... Guessed: match at offset 0 Matching REx "\b(S\.P\.E\.C\.T\.R\.E\.)\b" against "S.P.E.C.T.R.E. (Special Exec utive for Counter-intelligence,"... 0 | 1:BOUND(2) 0 | 2:OPEN1(4) 0 | 4:EXACT (9) 14 | 9:CLOSE1(11) 14 | 11:BOUND(12) failed... Match failed Freeing REx: "\b(S\.P\.E\.C\.T\.R\.E\.)\b"
In [2]: import pandas as pd
In [3]: df = pd.DataFrame({'col': ['abc', 'def']})
...: mapping = {v: k for k, v in enumerate('abcdef')}
...: df['new'] = df['col'].apply(lambda x: list(x))
In [7]: df['new']
Out[7]:
0 [a, b, c]
1 [d, e, f]
Name: new, dtype: object
In [8]: df['new'].values
Out[8]: array([list(['a', 'b', 'c']), list(['d', 'e', 'f'])], dtype=object)
np.stack
ведет себя подобно np.array
, объединяя элементы на новой начальной оси:
In [9]: np.stack(df['new'].values)
Out[9]:
array([['a', 'b', 'c'],
['d', 'e', 'f']], dtype='<U1')
или на другой оси, которую вы выбираете:
In [10]: np.stack(df['new'].values, axis=1)
Out[10]:
array([['a', 'd'],
['b', 'e'],
['c', 'f']], dtype='<U1')
[ 1118] np.array
также работает, если массив объектов превращается в список (как показывает @coldspeed):
In [11]: df['new'].values.tolist()
Out[11]: [['a', 'b', 'c'], ['d', 'e', 'f']]
In [12]: np.array(df['new'].values.tolist())
Out[12]:
array([['a', 'b', 'c'],
['d', 'e', 'f']], dtype='<U1')
Что касается скорости, давайте сделаем больший массив:
In [16]: arr = np.frompyfunc(lambda x: np.arange(1000),1,1)(np.arange(1000))
In [17]: arr.shape
Out[17]: (1000,)
In [18]: np.stack(arr).shape
Out[18]: (1000, 1000)
In [20]: np.array(arr.tolist()).shape
Out[20]: (1000, 1000)
In [21]: timeit np.stack(arr).shape
5.24 ms ± 190 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [22]: timeit np.array(arr.tolist()).shape
4.45 ms ± 138 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
[1120 В основном то же самое, с небольшим перевесом к подходу np.array
.
stack
подобно vstack
расширяет размеры каждого элемента по мере необходимости. Пропуск этого с concatenate
немного быстрее:
In [27]: timeit np.concatenate(arr).reshape(-1,1000).shape
4.04 ms ± 12.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Этот arr
содержит массивы. Если вместо этого он содержит списки, подход array(arr.tolist())
работает лучше (относительно), поскольку у него есть только один список (списков) для преобразования в массив. Подход stack
должен сначала преобразовать каждый из подсписков в массивы.
Я думаю, что было бы лучше создать массив из списка значений напрямую.
df
col new
0 abc [a, b, c]
1 def [d, e, f]
arr = np.array(df['new'].tolist())
arr
# array([['a', 'b', 'c'],
# ['d', 'e', 'f']], dtype='<U1')
arr.shape
# (2, 3)
Большой отказ от ответственности: Это будет работать, только если у всех списков есть одинаковое количество элементов. Если нет, это будет означать, что они являются рваными массивами, и numpy не сможет использовать эффективный формат памяти для представления вашего массива (следовательно, dtype='object'
).