python - 字符串的快速连接
问题描述
我有一个二维 0/1 数组,X
. 每列代表一个特定的字母。对于每一行,我想加入那些X
值为 1 的字母。
例如:
import numpy as np
abc = np.array(['A','B','C','D','E','F'],dtype=str)
X = np.random.randint(0,2,(5,abc.shape[0]))
res = [np.string_.join('',abc[row==1]) for row in X]
这很好,只是这个特定任务是我的代码的瓶颈。因此,我尝试将其移至 cython 没有成功,这主要是由于我对字符串和字符等的理解非常有限。下面的代码供参考,但它很糟糕。这一次,它并没有完全返回我想要的(例如,必须将字符转换为 Python 字符串),更令人担忧的是,我认为代码不稳定。
import numpy as np
cimport numpy as np
cimport cython
from libc.stdlib cimport malloc, free
def join_c(int[:,:] idx, bytes abc):
cdef:
size_t i, j, count
int n = idx.shape[0]
int m = idx.shape[1]
char *arr = <char *>malloc((n*(m+1))*sizeof(char))
count = 0
try:
for i in range(n):
for j in range(m):
if idx[i,j] == 1:
arr[count] = abc[j]
count +=1
arr[count] = ','
count+=1
return [x for x in arr]
finally:
free(arr)
我想看看如何在 cython 中做到这一点,但我对任何其他快速解决方案都很满意。
解决方案
这是一个基于字符串数组的解决方案 -
def join_singlechars(abc, X):
# Get mask
mask = X==1
# Get start, stop indices for splitting the concatenated string later on
idx = np.r_[0,mask.sum(1).cumsum()]
# Get concatenated string
n = idx[-1] #sum of 1s in mask
s = np.broadcast_to(abc, X.shape)[mask].tostring()
# Or np.broadcast_to(abc, X.shape)[mask].view('S'+str(n))[0]
return [s[i:j] for i,j in zip(idx[:-1],idx[1:])] # finally split
样品运行 -
In [229]: abc
Out[229]: array(['A', 'B', 'C', 'D', 'E', 'F'], dtype='|S1')
In [230]: X
Out[230]:
array([[1, 0, 1, 0, 0, 1],
[1, 1, 0, 1, 1, 0],
[1, 0, 1, 1, 0, 0],
[1, 1, 0, 1, 1, 1],
[1, 1, 1, 0, 0, 1]])
In [231]: join_singlechars(abc, X)
Out[231]: ['ACF', 'ABDE', 'ACD', 'ABDEF', 'ABCF']
大型5000 x 5000
阵列案例的计时 -
In [321]: abc = np.array(['A','B','C','D','E','F'],dtype=str)
...: abc = np.resize(abc,5000)
...: np.random.seed(0)
...: X = np.random.randint(0,2,(5000,5000))
In [322]: %timeit [np.string_.join('',abc[row==1]) for row in X]
1 loop, best of 3: 648 ms per loop
In [323]: %timeit join_singlechars(abc, X)
1 loop, best of 3: 209 ms per loop
推荐阅读
- c - abnormal program termination turbo c
- reactjs - 在 webpack 4 中没有 Babel 的 Tree Shaking
- java - JSON条件输出
- svn - SVN在文件内容中搜索?
- nativescript - 如何在nativescript中上传图片
- css - How to identify the navbar colour in CSS
- python - python - 如何从python列表中的索引中打印某个元素之前的2个元素?
- jersey - 如何在 grizzly 服务器控制台上获取 HTTP 请求日志?
- java - Apache poi:只要在段落中插入运行,XWPFFieldRun 就会在段落前面移动
- angular - 数据源更新时保持展开的 mat-table 不会折叠行(Angular Material)