如何快速将像"001100"这样的字符串转换为numpy.array([0,0,1,1,0,0])?

sti*_*gmj 5 python format types numpy type-conversion

我有一个由0和1组成的字符串,就像'00101'.我想将它转换为numpy数组numpy.array([0,0,1,0,1].

我正在使用for循环:

import numpy as np
X = np.zeros((1,5),int)
S = '00101'
for i in xrange(5):
    X[0][i] = int(S[i])
Run Code Online (Sandbox Code Playgroud)

但由于我有很多字符串,每个字符串的长度是1024,这种方式非常慢.有没有更好的方法来做到这一点?

Pad*_*ham 8

map应该比list comp快一点:

import  numpy as np

arr = np.array(map(int,'00101'))
Run Code Online (Sandbox Code Playgroud)

一些时间显示它是一串1024个字符:

In [12]: timeit np.array([int(c) for c in s])
1000 loops, best of 3: 422 µs per loop

In [13]: timeit np.array(map(int,s))
1000 loops, best of 3: 389 µs per loop
Run Code Online (Sandbox Code Playgroud)

只需在s中调用list并使用dtype = int就更快了:

In [20]: timeit np.array(list(s), dtype=int)
1000 loops, best of 3: 329 µs per loop
Run Code Online (Sandbox Code Playgroud)

使用fromiter 和传递dtype=int再次更快:

In [21]: timeit  np.fromiter(s,dtype=int)
1000 loops, best of 3: 289 µs per loop
Run Code Online (Sandbox Code Playgroud)

借用这个答案,使用fromstring和uint8作为dtype是最快的:

In [54]: timeit  np.fromstring(s, 'int8') - 48
100000 loops, best of 3: 4.54 µs per loop
Run Code Online (Sandbox Code Playgroud)

甚至重新绑定名称和更改dtype仍然是最快的:

In [71]: %%timeit
   ....: arr = np.fromstring(s, 'int8') - 48
   ....: arr = arr.astype(int)
   ....: 
100000 loops, best of 3: 6.23 µs per loop
Run Code Online (Sandbox Code Playgroud)

甚至比Ashwini的加入要快得多:

In [76]: timeit  np.fromstring(' '.join(s), sep=' ', dtype=int)
10000 loops, best of 3: 62.6 µs per loop
Run Code Online (Sandbox Code Playgroud)

正如@Unutbu所述,np.fromstring(s, 'int8') - 48 不仅限于1和0,而是适用于由ASCII数字组成的所有字符串.


Ana*_*mar 2

我认为列表理解会比正常的 for 循环方法更快 -

\n\n
import numpy as np\n\ns = '00101'\n\nnp.array([int(c) for c in s])\narray([0, 0, 1, 0, 1])\n
Run Code Online (Sandbox Code Playgroud)\n\n

Timeit 与您的方法的比较(长度为 1024 的字符串)-

\n\n
In [41]: S = '0' * 512 + '1' * 512\n\nIn [43]: %%timeit\n   ....: X = np.zeros((1,len(S)),int)\n   ....: for i in range(len(S)):\n   ....:     X[0][i] = int(S[i])\n   ....:\n1000 loops, best of 3: 854 \xc2\xb5s per loop\n\nIn [45]: %%timeit\n   ....: Y = np.array([int(c) for c in S]).reshape((1,len(S)))\n   ....:\n1000 loops, best of 3: 339 \xc2\xb5s per loop\n
Run Code Online (Sandbox Code Playgroud)\n\n

我进行了重塑,只是为了使两个数组具有相同的形状,但我认为您并不真正需要重塑,通过列表理解,您得到的数组的形状是(<length of string> ,)

\n