填充 numpy 数组的向量方式
Vector way of populating numpy array
我有一些二进制字符串 s
,例如 001010
。我想将其转换为 numpy 数组 a
,其中 a[i] = np.array([[1], [0]])
如果 s[i] == '0'
,否则为 np.array([[0], [1]])
。
所以我写了这样的代码:
a = np.empty([len(s), 2, 1])
for i, char in enumerate(s):
if char == '0':
a[i] = np.array([[1], [0]])
elif char == '1':
a[i] = np.array([[0], [1]])
能否以更麻木的方式将其重写为没有 for 循环的矢量化形式?
我的预期输出如下:
array([[[1.],
[0.]],
[[1.],
[0.]],
[[0.],
[1.]],
[[1.],
[0.]],
[[0.],
[1.]],
[[1.],
[0.]]])
一个简单的方法是从字符串创建一个 list
,然后通过指定 dtype=int
:[=19= 将此列表转换为整数的 np.array
]
s = '001010'
a = np.array(list(s), dtype=int)
# array([0, 0, 1, 0, 1, 0])
然后用np.where
根据a
中的值在np.array([[1], [0]])
或np.array([[0], [1]])
中select:
np.where(a==0, np.array([[1], [0]]), np.array([[0], [1]])).T[:,:,None]
array([[[1],
[0]],
[[1],
[0]],
[[0],
[1]],
[[1],
[0]],
[[0],
[1]],
[[1],
[0]]])
方法 #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
我有一些二进制字符串 s
,例如 001010
。我想将其转换为 numpy 数组 a
,其中 a[i] = np.array([[1], [0]])
如果 s[i] == '0'
,否则为 np.array([[0], [1]])
。
所以我写了这样的代码:
a = np.empty([len(s), 2, 1])
for i, char in enumerate(s):
if char == '0':
a[i] = np.array([[1], [0]])
elif char == '1':
a[i] = np.array([[0], [1]])
能否以更麻木的方式将其重写为没有 for 循环的矢量化形式?
我的预期输出如下:
array([[[1.],
[0.]],
[[1.],
[0.]],
[[0.],
[1.]],
[[1.],
[0.]],
[[0.],
[1.]],
[[1.],
[0.]]])
一个简单的方法是从字符串创建一个 list
,然后通过指定 dtype=int
:[=19= 将此列表转换为整数的 np.array
]
s = '001010'
a = np.array(list(s), dtype=int)
# array([0, 0, 1, 0, 1, 0])
然后用np.where
根据a
中的值在np.array([[1], [0]])
或np.array([[0], [1]])
中select:
np.where(a==0, np.array([[1], [0]]), np.array([[0], [1]])).T[:,:,None]
array([[[1],
[0]],
[[1],
[0]],
[[0],
[1]],
[[1],
[0]],
[[0],
[1]],
[[1],
[0]]])
方法 #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