2015-07-13 2 views
0

Скажем, у меня есть следующие:многомерный нарезка список строк с NumPy

my_list = np.array(["abc", "def", "ghi"]) 

, и я хотел бы получить:

np.array(["ef", "hi"]) 

Я пробовал:

my_list[1:,1:] 

Но затем я получаю:

IndexError: too many indices for array 

Поддерживает ли Numpy поддерживающие строки?

ответ

-2

Ваша нарезка неверно синтаксиса. Вам нужно всего лишь сделать my_list[1:], чтобы получить то, что вам нужно. Если вы хотите скопировать элементы дважды в список, вы можете сделать something = mylist[1:].extend(mylist[1:])

+0

Обратите внимание, что я говорю о многомерном разрезе в Numpy, что позволяет использовать синтаксис, который я использовал. Кроме того, 'my_list [1:]' получает меня '['def', 'ghi']', а не '['ef', 'hi']'. – Ben

2

Нет, вы не можете этого сделать. Для numpy np.array(["abc", "def", "ghi"]) представляет собой 1D массив строк, поэтому вы не можете использовать 2D-нарезку.

Вы можете либо определить свой массив как массив 2D или символы, или просто использовать список понимание для нарезки,

In [4]: np.asarray([el[1:] for el in my_list[1:]]) 
Out[4]: 
array(['ef', 'hi'], dtype='|S2') 
0

Согласно Джо Кингтон here, питон очень хорошо строковых манипуляций и генератор/списковых быстрые и гибкие для строковых операций. Если вам не понадобится использовать numpy позже в вашем конвейере, я бы попросил его.

[s[1:] for s in my_list[1:]] 

является быстро:

In [1]: from string import ascii_lowercase 
In [2]: from random import randint, choice 
In [3]: my_list_rand = [''.join([choice(ascii_lowercase) 
           for _ in range(randint(2, 64))]) 
         for i in range(1000)] 
In [4]: my_list_64 = [''.join([choice(ascii_lowercase) for _ in range(64)]) 
         for i in range(1000)] 

In [5]: %timeit [s[1:] for s in my_list_rand[1:]] 
10000 loops, best of 3: 47.6 µs per loop 
In [6]: %timeit [s[1:] for s in my_list_64[1:]] 
10000 loops, best of 3: 45.3 µs per loop 

numpy Использование только добавляет накладные расходы.

0

Ваш массив строк хранит данные в виде непрерывного блока символов, используя DTYPE в «S3», чтобы разделить его на строки длины 3.

In [116]: my_list 
Out[116]: 
array(['abc', 'def', 'ghi'], 
     dtype='|S3') 

S1,S2 DTYPE рассматривает каждый элемент в виде 2-х строк, с 1 и 2 полукокса каждого:

In [115]: my_list.view('S1,S2') 
Out[115]: 
array([('a', 'bc'), ('d', 'ef'), ('g', 'hi')], 
    dtype=[('f0', 'S1'), ('f1', 'S2')]) 

выбрать 2-ю поле, чтобы получить массив с нужными символами:

In [114]: my_list.view('S1,S2')[1:]['f1'] 
Out[114]: 
array(['ef', 'hi'], 
     dtype='|S2') 

Моя первая попытка с view было разделить массив на отдельные строки байт, и играть с результирующим 2d массива:

In [48]: my_2dstrings = my_list.view(dtype='|S1').reshape(3,-1) 

In [49]: my_2dstrings 
Out[49]: 
array([['a', 'b', 'c'], 
     ['d', 'e', 'f'], 
     ['g', 'h', 'i']], 
     dtype='|S1') 

Этот массив может быть нарезана в обоих направлениях. Я использовал flatten для удаления измерения и принудительного копирования (чтобы получить новый непрерывный буфер).

In [50]: my_2dstrings[1:,1:].flatten().view(dtype='|S2') 
Out[50]: 
array(['ef', 'hi'], 
     dtype='|S2') 

Если строки уже в массиве (в отличие от списка), то этот подход гораздо быстрее, чем список понимание подходов.

Некоторые тайминги со списком 1000 х 64, что wflynny тесты

In [98]: timeit [s[1:] for s in my_list_64[1:]] 
10000 loops, best of 3: 173 us per loop # mine's slower computer 

In [99]: timeit np.array(my_list_64).view('S1').reshape(64,-1)[1:,1:].flatten().view('S63') 
1000 loops, best of 3: 213 us per loop 

In [100]: %%timeit arr =np.array(my_list_64) 
    .....: arr.view('S1').reshape(64,-1)[1:,1:].flatten().view('S63') .....: 
10000 loops, best of 3: 23.2 us per loop 

Создание массива из списка медленно, но когда-то создал view подход гораздо быстрее.


См. Мою историю изменений для моих ранних заметок на np.char.

Смежные вопросы