如何使用 numpy broadcasting、meshgrid 或其他方法创建字符矩阵
How to create a matrix of characters with numpy broadcasting, meshgrid or other method
假设我有两个 numpy 数组:
a = np.array(['a','b'])
b = np.array(['c','d'])
如何创建如下网格:
ac | ad
-------
bc | bd
我希望能够做到:
a @ b
或
np.meshgrid(a,b)
但都抛出类型异常。
使用矩阵乘积等运算符创建组合的有效方法是什么? Itertools.product 是一种方式,但我更愿意使用 numpy。
使用对象数据类型(而不是默认的U1
),+
是字符串连接:
In [317]: a.astype(object)[:,None]+ b.astype(object)
Out[317]:
array([['ac', 'ad'],
['bc', 'bd']], dtype=object)
由于这是工作对象 dtype 数组,因此速度不如纯数字代码。它甚至可能比列表理解慢。
In [319]: np.array([[i+j for j in b] for i in a])
Out[319]:
array([['ac', 'ad'],
['bc', 'bd']], dtype='<U2')
时间安排:
In [320]: timeit np.array([[i+j for j in b] for i in a])
10.9 µs ± 130 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [321]: timeit a.astype(object)[:,None]+ b.astype(object)
16.7 µs ± 206 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
和纯列表版本:
In [322]: %%timeit A,B=a.tolist(), b.tolist()
...: [[i+j for j in B] for i in A]
1.33 µs ± 13.4 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
char.add
虽然方便,但仍然依赖于字符串方法,所以不是更快:
In [324]: timeit np.char.add(a[:, None], b)
15.6 µs ± 62.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
frompyfunc
和 operator.__add__
比列表理解略好:
In [331]: timeit np.frompyfunc(__add__,2,1)(a[:,None], b)
8.75 µs ± 182 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
np.char.add(a[:, None], b)
array([['ac', 'ad'],
['bc', 'bd']], dtype='<U2')
假设我有两个 numpy 数组:
a = np.array(['a','b'])
b = np.array(['c','d'])
如何创建如下网格:
ac | ad
-------
bc | bd
我希望能够做到:
a @ b
或
np.meshgrid(a,b)
但都抛出类型异常。
使用矩阵乘积等运算符创建组合的有效方法是什么? Itertools.product 是一种方式,但我更愿意使用 numpy。
使用对象数据类型(而不是默认的U1
),+
是字符串连接:
In [317]: a.astype(object)[:,None]+ b.astype(object)
Out[317]:
array([['ac', 'ad'],
['bc', 'bd']], dtype=object)
由于这是工作对象 dtype 数组,因此速度不如纯数字代码。它甚至可能比列表理解慢。
In [319]: np.array([[i+j for j in b] for i in a])
Out[319]:
array([['ac', 'ad'],
['bc', 'bd']], dtype='<U2')
时间安排:
In [320]: timeit np.array([[i+j for j in b] for i in a])
10.9 µs ± 130 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [321]: timeit a.astype(object)[:,None]+ b.astype(object)
16.7 µs ± 206 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
和纯列表版本:
In [322]: %%timeit A,B=a.tolist(), b.tolist()
...: [[i+j for j in B] for i in A]
1.33 µs ± 13.4 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
char.add
虽然方便,但仍然依赖于字符串方法,所以不是更快:
In [324]: timeit np.char.add(a[:, None], b)
15.6 µs ± 62.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
frompyfunc
和 operator.__add__
比列表理解略好:
In [331]: timeit np.frompyfunc(__add__,2,1)(a[:,None], b)
8.75 µs ± 182 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
np.char.add(a[:, None], b)
array([['ac', 'ad'],
['bc', 'bd']], dtype='<U2')