Подход № 1: Вот пример с массивом символов NumPy -
sa = np.frombuffer(s,dtype='S1')
out = np.where(sa[:,None,None]=='0',[[1],[0]],[[0],[1]])
Подход № 2: Еще один однострочный -
((np.frombuffer(s,dtype=np.uint8)[:,None]==[48,49])[...,None]).astype(float)
Подход № 3: Финальный, полностью сфокусированный на производительности -
a = np.zeros([len(s), 2, 1])
idx = np.frombuffer(s,dtype=np.uint8)-48
a[np.arange(len(idx)),idx] = 1
Синхронизация строки 100000
символов -
In [2]: np.random.seed(0)
In [3]: s = ''.join(map(str,np.random.randint(0,2,(100000)).tolist()))
# @yatu's soln
In [4]: %%timeit
...: a = np.array(list(s), dtype=int)
...: np.where(a==0, np.array([[1], [0]]), np.array([[0], [1]])).T[:,:,None]
10 loops, best of 3: 36.3 ms per loop
# App#1 from this post
In [5]: %%timeit
...: sa = np.frombuffer(s,dtype='S1')
...: out = np.where(sa[:,None,None]=='0',[[1],[0]],[[0],[1]])
100 loops, best of 3: 3.56 ms per loop
# App#2 from this post
In [6]: %timeit ((np.frombuffer(s,dtype=np.uint8)[:,None]==[48,49])[...,None]).astype(float)
1000 loops, best of 3: 1.81 ms per loop
# App#3 from this post
In [7]: %%timeit
...: a = np.zeros([len(s), 2, 1])
...: idx = np.frombuffer(s,dtype=np.uint8)-48
...: a[np.arange(len(idx)),idx] = 1
1000 loops, best of 3: 1.81 ms per loop