【问题标题】:Element-wise string concatenation in numpynumpy中的元素级字符串连接
【发布时间】:2012-04-15 01:19:48
【问题描述】:

这是一个错误吗?

import numpy as np
a1=np.array(['a','b'])
a2=np.array(['E','F'])

In [20]: add(a1,a2)
Out[20]: NotImplemented

我正在尝试按元素进行字符串连接。我认为 Add() 是在 numpy 中执行此操作的方法,但显然它没有按预期工作。

【问题讨论】:

  • 顾名思义,number就是数字。 Python 本身有很好的字符串操作。为什么不直接使用它? "".join(["a", "b"]) 工作正常。
  • 这很酷。但是:“它们都是基于 Python 标准库中的字符串方法。”。所以如果你只使用标准库,你可以编写不依赖于 numpy 的代码。
  • add 操作与join 的作用不同。 numpy 的 add 对于多维数组或嵌套列表很有用。
  • add 是从哪里来的?

标签: python arrays string numpy elementwise-operations


【解决方案1】:

这可以使用numpy.core.defchararray.add 来完成。这是一个例子:

>>> import numpy as np
>>> a1 = np.array(['a', 'b'])
>>> a2 = np.array(['E', 'F'])
>>> np.core.defchararray.add(a1, a2)
array(['aE', 'bF'], 
      dtype='<U2')

还有其他有用的 string operations 可用于 NumPy 数据类型。

【讨论】:

  • 您链接到的add 字符串操作为python 3.2 下的numpy 1.6.1 提供了NotImplemented(如问题所示)。你知道是从哪个版本实现的吗?
  • @FrancescoMontesano 在 Ubuntu 12.04.2 LTS 上检查该版本组合,我的答案中的示例按预期工作。一般来说,使用np.add 也会在任何版本中引发NotImplemented。确保您使用的是np.core.defchararray.add
  • 现在我在文档中看到了add 的完整签名(我之前错过了)。无论如何,如果 numpy 将 np.core.defchararray.* 包装到相应的数字 ndarray 操作中,那就太好了。我认为np.add.
  • 如模块的文档字符串中所述,“defchararray 的首选别名是numpy.char”,因此您可以直接说np.char.add
  • @MikeT :是否可以定义一个分隔符来获得像 array(['a#E', 'b#F']) 这样的输出?顺便说一句,感谢您提供上述解决方案。使用 map('#'.join, zip(a1, a2)) 我可以但很好奇 numpy 是可能的。
【解决方案2】:

You can use the chararray subclass 用字符串执行数组操作:

a1 = np.char.array(['a', 'b'])
a2 = np.char.array(['E', 'F'])

a1 + a2
#chararray(['aE', 'bF'], dtype='|S2')

另一个很好的例子:

b = np.array([2, 4])
a1*b
#chararray(['aa', 'bbbb'], dtype='|S4')

【讨论】:

    【解决方案3】:

    这可以(并且应该)在纯 Python 中完成,因为 numpy 在内部也使用 Python 字符串操作函数:

    >>> a1 = ['a','b']
    >>> a2 = ['E','F']
    >>> map(''.join, zip(a1, a2))
    ['aE', 'bF']
    

    【讨论】:

    • 好的,所以我使用的 add 函数不在 numpy 的顶层。出于任何原因,其中任何一个更快/更好还是更受欢迎?
    • 这不能回答问题。有时人们可能想在 numpy 中执行此操作,例如处理大型字符串数组时。原始海报给出了一个简单的示例,可以使用纯 Python,但要求提供一个 numpy 解决方案。
    • @Thucydides411 根据我在撰写答案时的理解,numpy 只是使用了内置的 Python 原语,所以我看不出会有什么优势。不知道是不是真的,好像不是。也许我误解了“所有这些都是基于 Python 标准库中的字符串方法”的说法。在文档中
    • @NiklasB。谢谢你,尼克。我一直在寻找完全相同的东西。只是好奇我如何使用 numpy 实现相同的功能。我会挖掘 numpy 文档。
    【解决方案4】:

    另一种解决方案是将字符串数组转换为对象的python数组,以便调用str.add:

    >>> import numpy as np
    >>> a = np.array(['a', 'b', 'c', 'd'], dtype=np.object)   
    >>> print a+a
    array(['aa', 'bb', 'cc', 'dd'], dtype=object)
    

    这并没有那么慢(不到添加整数数组的两倍慢)。

    【讨论】:

      【解决方案5】:

      一个更基本、优雅和快速的解决方案:

      In [11]: np.array([x1 + x2 for x1,x2 in zip(a1,a2)])
      Out[11]: array(['aE', 'bF'], dtype='<U2')
      

      对于较小的数组来说非常快。

      In [12]: %timeit np.array([x1 + x2 for x1,x2 in zip(a1,a2)])
      3.67 µs ± 136 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
      
      In [13]: %timeit np.core.defchararray.add(a1, a2)
      6.27 µs ± 28.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
      
      In [14]: %timeit np.char.array(a1) + np.char.array(a2)
      22.1 µs ± 319 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
      

      对于较大的数组,时间差不大。

      In [15]: b1 = np.full(10000,'a')    
      In [16]: b2 = np.full(10000,'b')    
      
      In [189]: %timeit np.array([x1 + x2 for x1,x2 in zip(b1,b2)])
      6.74 ms ± 66.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
      
      In [188]: %timeit np.core.defchararray.add(b1, b2)
      7.03 ms ± 419 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
      
      In [187]: %timeit np.char.array(b1) + np.char.array(b2)
      6.97 ms ± 284 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
      

      【讨论】:

        猜你喜欢
        • 2013-12-21
        • 1970-01-01
        • 2013-02-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多