首页 > 解决方案 > Numpy 数组通过广播对字符串进行条带化

问题描述

我有以下代码

import numpy
s = numpy.array([['210123278414410005', '101232784144610006']], dtype='object')
print(s, type(s), s.shape)
s[0][0] = s[0][0][13:]
s[0][1] = s[0][1][13:]    
print(s, type(s), s.shape)

这给了我想要的输出:

[['210123278414410005' '101232784144610006']] 
[['10005' '10006']]

如您所见,左边的 13 个字符消失了。是否可以广播此操作?

我试过了,

s[0][:] = [[s[0][0]]][0][0][13:]

但这并没有像以前那样给出正确的输出。

[['10005' '10005']] 

标签: pythonnumpyarray-broadcasting

解决方案


In [22]: s = np.array([['210123278414410005', '101232784144610006']], dtype='object')                                                                  
In [23]: s                                                                      
Out[23]: array([['210123278414410005', '101232784144610006']], dtype=object)
In [24]: s.shape                                                                
Out[24]: (1, 2)

由于这是一个对象 dtype 数组,一个好的起点是frompyfunc它还返回一个对象 dtype 数组:

In [25]: np.frompyfunc(lambda s: s[13:],1,1)(s)                                 
Out[25]: array([['10005', '10006']], dtype=object)

s[0,0]是一个 Python 字符串。 s[0,0][13:]是一个字符串操作。

通常,对对象 dtype 数组的操作需要接近 python 级别的迭代,甚至是数学。没有任何内置numpy操作来获取子字符串。 np.char有一堆函数将字符串方法应用于字符串 dtype 数组的元素。但它们并不是特别快,而且它们不包括这个子字符串任务。

或者最后 5 个:

In [33]: np.frompyfunc(lambda s: s[-5:],1,1)(s)                                 
Out[33]: array([['10005', '10006']], dtype=object)

将此与科林的答案进行比较:

In [37]: sbig = np.resize(s, (1000,1000))                                       
In [38]: timeit np.mod(sbig.astype('uint64'),100000).astype('U')                
754 ms ± 9.33 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [39]: timeit np.frompyfunc(lambda s: s[-5:],1,1)(sbig)                       
245 ms ± 428 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)

进一步看,这astype('U')一步似乎是大消费者,将数字转换为字符串。


推荐阅读