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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.