Numpy 数组通过广播对字符串进行条带化

Numpy array striping strings via broadcasting

我有以下代码

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']] 

使用理解

import numpy
s = numpy.array([['210123278414410005', '101232784144610006']], dtype='object')
s = np.asarray([[i[13:] for e in s for i in e]])
print(s, type(s), s.shape)

结果:

[['10005' '10006']] <class 'numpy.ndarray'> (1, 2)

您可以将数组项转换为数字,trim 它们,然后再转换回字符串:

WIDTH = 5
MOD = 10 ** WIDTH
numpy.char.zfill((s.astype(numpy.int64) % MOD).astype('str'), WIDTH)
#array([['10005', '10006']], dtype='<U5')

一种笨拙的方法是将您的 'number string' 转换为整数,对所需长度执行模运算,然后再转换回字符串:

s = numpy.mod(s[0,].astype(numpy.uint64),100000).astype('U')

给出了想要的结果。

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 这也是 returns 一个对象 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 数组上的一般操作需要 near-python 级迭代,甚至数学。没有任何内置的 numpy 操作来获取子字符串。 np.char 有一堆函数可以将字符串方法应用于字符串 dtype 数组的元素。但是他们不是特别快,而且他们不包括这个子串任务。

或最后 5 个:

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

将此与 Colin 的回答进行比较:

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') 这一步似乎是耗时最多的步骤,将数字转换为字符串。