【问题标题】:How to create a matrix of characters with numpy broadcasting, meshgrid or other method如何使用 numpy 广播、meshgrid 或其他方法创建字符矩阵
【发布时间】:2019-08-15 20:16:56
【问题描述】:

假设我有两个 numpy 数组:

a = np.array(['a','b'])
b = np.array(['c','d'])

我怎样才能创建一个像这样的网格:

ac | ad
-------
bc | bd

我希望能够做到:

a @ b

np.meshgrid(a,b)

但两者都抛出类型异常。

使用矩阵乘积等运算符创建组合的有效方法是什么? Itertools.product 是一种方法,但我更喜欢使用 numpy。

【问题讨论】:

  • 预期的输出究竟是什么?

标签: python-3.x numpy matrix-multiplication


【解决方案1】:

使用object dtype(而不是默认的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)

【讨论】:

    【解决方案2】:

    这是np.char.add


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

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

    【讨论】:

      猜你喜欢
      • 2015-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多