考虑一个字符串数组的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_'
<U4
和.str_
类型之间有什么区别?np.char.**
如何解析显示的字符串?
答案 0 :(得分:1)
首先,np.char
函数应在chararrays
上工作,该函数应使用np.char.array
或np.char.asarray
构造(请参见docs)。 / p>
因此,您给定的代码将像这样工作:
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]
为完整起见,关于<U4
与S5
的附属问题:
带有numpy
的{{1}} dtype
表示一个unicode字符串,即recommended way of representing strings。另一方面,U
代表以空值结尾的字节数组。
我的怀疑是,字符串方法是在Python对象上执行的,因此,您需要一个类似Python字符串的类型(知道其自身的长度等),而不是一个“笨拙的” C字符串类型的字节数组。 >
答案 1 :(得分:1)
参数中的字符串类型必须与数组中的类型匹配:
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
使用起来有点尴尬,因为结果是带有分割字符串列表的对象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')
我可以通过提供np.vectorize
(甚至是dtypes的混合!)来将拆包和astype与otypes
结合起来:
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'))
通常frompyfunc
比vectorize
快。
如果拆分创建了不同的长度列表,则此拆包将不起作用:
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,如果需要一个字符串数组,建议使用dtype
object_
,string_
或unicode_
,并使用免费功能 在numpy.char
模块中进行快速矢量化字符串操作。