如何使用 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)

frompyfuncoperator.__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


np.char.add(a[:, None], b)

array([['ac', 'ad'],
       ['bc', 'bd']], dtype='<U2')