【问题标题】:What numpy structures are expected as inputs to use numpy.char functions?使用 numpy.char 函数需要哪些 numpy 结构作为输入?
【发布时间】:2019-04-28 12:30:58
【问题描述】:

考虑一个 numpy 字符串数组(至少我最接近如何做到这一点):

ff = np.array([['a:bc','d:ef'],['g:hi','j:kl']])
print(ff.dtype)
<U4

但是这些显然不能与numpy.char 方法一起使用.. ?

ffc = ff.astype('S5')
fff = np.char.split(ffc,':')[1]


Traceback (most recent call last):
  File "<input>", line 3, in <module>
  File "/usr/local/lib/python3.7/site-packages/numpy/core/defchararray.py", line 1447, in split
    a, object_, 'split', [sep] + _clean_args(maxsplit))
TypeError: a bytes-like object is required, not 'numpy.str_'

&lt;U4.str_ 类型有什么区别,np.char.** 怎么解析显示的字符串?

【问题讨论】:

  • 如果 dtype 是 U 使用 unicode 参数。如果 bytestring dtype S 使用 bytestring 参数,b':'

标签: python string numpy numpy-ndarray


【解决方案1】:

首先,np.char 函数适用于 chararrays,应使用 np.char.arraynp.char.asarray 构造(请参阅 docs)。

因此,您给定的代码将像这样工作:

ff = np.array([['a:bc','d:ef'],['g:hi','j:kl']])
ffc = np.char.asarray(ff)
fff = np.char.split(ffc, ':')[1]

print(fff)

输出:

[list(['g', 'hi']) list(['j', 'kl'])]

这种转换是隐式执行的,所以事实上这也可以:

ff = np.array([['a:bc','d:ef'],['g:hi','j:kl']])
fff = np.char.split(ff, ':')[1]

为了完整起见,您关于 &lt;U4S5 的附属问题:

numpy dtypeU 表示一个 unicode 字符串,即 recommended way of representing strings。另一方面,S 表示一个以 null 结尾的字节数组。

我怀疑字符串方法是在 Python 对象上执行的,因此您需要一个类似 Python 字符串的类型(知道它自己的长度等),而不是一个“哑”的 C 字符串状字节数组。

【讨论】:

  • 嗯,我以为我已经开始直接使用np.array(没有调用astype('S5'),并且收到了与OP中所示相同的错误。但是代码(如您的第三个 sn-p 所示)确实有效。
  • @javadba 可能是 numpy 版本问题,或陈旧的变量。你会碰巧在 Jupyter notebook 或类似的笔记本上工作吗?
  • 不,我正在使用pycharm
  • 查看np.char 中关于np.chararrays 的当前使用情况的说明。
【解决方案2】:

参数中的字符串类型必须与数组中的类型匹配:

In [44]: ff = np.array([['a:bc','d:ef'],['g:hi','j:kl']])                            
In [45]: ff                                                                          
Out[45]: 
array([['a:bc', 'd:ef'],
       ['g:hi', 'j:kl']], dtype='<U4')
In [46]: np.char.split(ff,':')                                                       
Out[46]: 
array([[list(['a', 'bc']), list(['d', 'ef'])],
       [list(['g', 'hi']), list(['j', 'kl'])]], dtype=object)
In [47]: np.char.split(ff.astype('S5'),b':')                                         
Out[47]: 
array([[list([b'a', b'bc']), list([b'd', b'ef'])],
       [list([b'g', b'hi']), list([b'j', b'kl'])]], dtype=object)

'U4' 是 unicode,Py3 的默认字符串类型。 'S4' 是字节串,Py2 的默认类型。 b':' 是字节串,u':' 是 unicode。

这个np.char.split 使用起来有点尴尬,因为结果是object dtype,带有拆分字符串的列表。

要获得 2 个单独的数组,我会使用 frompyfunc 来应用解包:

In [50]: np.frompyfunc(lambda alist: tuple(alist), 1,2)(_46)                         
Out[50]: 
(array([['a', 'd'],
        ['g', 'j']], dtype=object), array([['bc', 'ef'],
        ['hi', 'kl']], dtype=object))
In [51]: np.frompyfunc(lambda alist: tuple(alist), 1,2)(_47)                         
Out[51]: 
(array([[b'a', b'd'],
        [b'g', b'j']], dtype=object), array([[b'bc', b'ef'],
        [b'hi', b'kl']], dtype=object))

虽然要获得字符串 dtype 数组,但我仍然可以使用 astype:

In [52]: _50[0].astype('U4')                                                         
Out[52]: 
array([['a', 'd'],
       ['g', 'j']], dtype='<U4')

我可以通过提供otypes(甚至是dtypes的混合!)将解包和astype与np.vectorize结合起来:

In [53]: np.vectorize(lambda alist:tuple(alist), otypes=['U4','S4'])(_46)            
Out[53]: 
(array([['a', 'd'],
        ['g', 'j']], dtype='<U1'), array([[b'bc', b'ef'],
        [b'hi', b'kl']], dtype='|S2'))

通常frompyfuncvectorize 快。

如果拆分创建不同长度的列表,则此解包将不起作用:

In [54]: ff = np.array([['a:bc','d:ef'],['g:hi','j:kl:xyz']])                        
In [55]: np.char.split(ff,':')                                                       
Out[55]: 
array([[list(['a', 'bc']), list(['d', 'ef'])],
       [list(['g', 'hi']), list(['j', 'kl', 'xyz'])]], dtype=object)

===

使用chararray,所有这些np.char 函数都可以作为方法使用。

In [59]: np.char.asarray(ff)                                                         
Out[59]: 
chararray([['a:bc', 'd:ef'],
           ['g:hi', 'j:kl:xyz']], dtype='<U8')
In [60]: np.char.asarray(ff).split(':')                                              
Out[60]: 
array([[list(['a', 'bc']), list(['d', 'ef'])],
       [list(['g', 'hi']), list(['j', 'kl', 'xyz'])]], dtype=object)

请参阅np.char 文档中的说明:

chararray 类的存在是为了向后兼容 Numarray,不建议用于新开发。从 numpy 开始 1.4,如果需要字符串数组,建议使用数组 dtypeobject_string_unicode_,并使用免费功能 在numpy.char 模块中进行快速向量化字符串操作。

【讨论】:

  • 重型论文。当我不在枪下正确吸收时,我会回到这个问题
猜你喜欢
  • 1970-01-01
  • 2017-12-17
  • 1970-01-01
  • 2013-01-14
  • 1970-01-01
  • 1970-01-01
  • 2020-06-23
  • 1970-01-01
  • 2021-03-04
相关资源
最近更新 更多