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