7

I have an array of strings

>>> lines
array(['RL5\\Stark_223', 'RL5\\Stark_223', 'RL5\\Stark_223', ...,
       'RL5\\Stark_238', 'RL5\\Stark_238', 'RL5\\Stark_238'], 
      dtype='|S27')

Why can I index into a string for the first array element

>>> lines[0][0:3]
'RL5'

But not into the same place for all array elements

>>> lines[:][0:3]
array(['RL5\\Stark_223', 'RL5\\Stark_223', 'RL5\\Stark_223'], 
      dtype='|S27')

Can anyone suggest a method to get the following result:

array(['RL5', 'RL5', 'RL5', ...'RL5', 'RL5')

5 Answers 5

5

To extract the first n characters of every string you can abuse .astype:

>>> s = np.array(['RL5\\Stark_223', 'RL5\\Stark_223', 'RL5\\Stark_223'])
>>> s
array(['RL5\\Stark_223', 'RL5\\Stark_223', 'RL5\\Stark_223'], 
      dtype='|S13')
>>> s.astype('|S3')
array(['RL5', 'RL5', 'RL5'], 
      dtype='|S3')
Sign up to request clarification or add additional context in comments.

1 Comment

Don't know why this answer was so hard to find! Simple and to the point -- thanks!
3

Dont forget chararrays!

lines.view(np.chararray).ljust(3)
chararray(['RL5', 'RL5', 'RL5', 'RL5', 'RL5', 'RL5'], 
      dtype='|S3')

Although its strangely slower:

#Extend lines to 600000 elements

%timeit lines.view(np.chararray).ljust(3)
1 loops, best of 3: 542 ms per loop

%timeit np.vectorize(lambda x: x[:3])(lines)
1 loops, best of 3: 239 ms per loop

%timeit map(lambda s: s[0:3], lines)
1 loops, best of 3: 243 ms per loop

%timeit arr.astype('|S3')
100 loops, best of 3: 4.72 ms per loop

Could be because its duplicating the data, the benefit of this is the dtype of the output array is minimized: S3 vs S64.

Comments

1

try this

map(lambda s:s[0:3],lines)

Comments

0

You can use numpy's vectorize:

In [11]: np.vectorize(lambda x: x[:3])(lines)
Out[11]: 
array(['RL5', 'RL5', 'RL5', 'RL5', 'RL5', 'RL5'], 
      dtype='|S64')

Comments

0

If you're looking for fast and (somewhat more) flexible, try:

lines.view('|S1').reshape(-1, lines.dtype.itemsize)[:, :3].reshape(-1).view('|S3')

Which can be used for more arbitrary slicing and dicing.

Timing info:

import numpy as np
lines = np.array(['RL5\\Stark_223', 'RL5\\Stark_223', 'RL5\\Stark_223', 
'RL5\\Stark_238', 'RL5\\Stark_238', 'RL5\\Stark_238'], dtype='|S27').repeat(100000)

%timeit lines.view(np.chararray).ljust(3)
1 loop, best of 3: 231 ms per loop

%timeit np.vectorize(lambda x: x[:3])(lines)
1 loop, best of 3: 226 ms per loop

%timeit map(lambda s: s[0:3], lines)
1 loop, best of 3: 171 ms per loop

%timeit lines.astype('|S3')
100 loops, best of 3: 3.58 ms per loop

%timeit lines.view('|S1').reshape(-1, lines.dtype.itemsize)[:, :3].reshape(-1).view('|S3')
100 loops, best of 3: 5.16 ms per loop

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.