python - 如何评估字符串并将其添加到 numpy 数组元素

标签 python string performance numpy

有我正在尝试优化的这段代码。 它使用列表理解和工作。

series1 = np.asarray(range(10)).astype(float)
series2 = series1[::-1]

ntup = zip(series1,series2)
[['', 't:'+str(series2)][series1 > series2] for series1,series2 in ntup ]
 #['', '', '', '', '', 't:4.0', 't:3.0', 't:2.0', 't:1.0', 't:0.0']

尝试在此处使用 np.where()。有没有 numpy 的解决方案。 (没有消耗系列)

series1 = np.asarray(range(10)).astype(float)
series2 = series1[::-1]  

np.where(series1 >  series2 ,'t:'+ str(series2),'' )

结果是这样的:

array(['', '', '', '', '', 't:[ 9.  8.  7.  6.  5.  4.  3.  2.  1.  0.]',
       't:[ 9.  8.  7.  6.  5.  4.  3.  2.  1.  0.]',
       't:[ 9.  8.  7.  6.  5.  4.  3.  2.  1.  0.]',
       't:[ 9.  8.  7.  6.  5.  4.  3.  2.  1.  0.]',
       't:[ 9.  8.  7.  6.  5.  4.  3.  2.  1.  0.]'], 
      dtype='|S43')

最佳答案

我们可以使用基于

的向量化方法
  • np.core.defchararray.add对于 ':' 的字符串附加有效字符串,以及

  • np.where根据条件语句进行选择并执行附加或仅使用空字符串的默认值。

所以,我们会有这样的实现 -

np.where(series1>series2,np.core.defchararray.add('t:',series2.astype(str)),'')

加油!

我们可以根据 series1>series2 的掩码对有效元素使用 np.core.defchararray.add 的附加,以在初始化后进一步提高性能具有默认空字符串的数组,然后仅将有效值分配给它。

所以,修改后的版本看起来像这样 -

mask = series1>series2
out = np.full(series1.size,'',dtype='U34')
out[mask] = np.core.defchararray.add('t:',series2[mask].astype(str))

运行时测试

作为函数的矢量化版本:

def vectorized_app1(series1,series2):
    mask = series1>series2
    return np.where(mask,np.core.defchararray.add('t:',series2.astype(str)),'')

def vectorized_app2(series1,series2):
    mask = series1>series2
    out = np.full(series1.size,'',dtype='U34')
    out[mask] = np.core.defchararray.add('t:',series2[mask].astype(str))
    return out

更大数据集上的计时 -

In [283]: # Setup input arrays
     ...: series1 = np.asarray(range(10000)).astype(float)
     ...: series2 = series1[::-1]
     ...: 

In [284]: %timeit [['', 't:'+str(s2)][s1 > s2] for s1,s2 in zip(series1, series2)]
10 loops, best of 3: 32.1 ms per loop # OP/@hpaulj's soln

In [285]: %timeit vectorized_app1(series1,series2)
10 loops, best of 3: 20.5 ms per loop

In [286]: %timeit vectorized_app2(series1,series2)
100 loops, best of 3: 10.4 ms per loop

OP in comments 所述,我们可以在追加之前使用 series2 的数据类型。所以,我在那里使用 U32 来保持输出数据类型与 str dtype 相同,即 series2.astype('U32')np.core.defchararray.add 调用。矢量化方法的新时间是 -

In [290]: %timeit vectorized_app1(series1,series2)
10 loops, best of 3: 20.1 ms per loop

In [291]: %timeit vectorized_app2(series1,series2)
100 loops, best of 3: 10.1 ms per loop

所以,那里还有一些边际改进!

关于python - 如何评估字符串并将其添加到 numpy 数组元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39256365/

相关文章:

c - 如何允许使用 scanf 输入空格?

java - 字符串的子字符串部分

python - 使用 networkx 将图形转换为完整图形的最快方法

python - Pandas:过滤每组数据帧,条件至少匹配组中的一项

python - AWS Lambda - time.time() 返回未定义

python - 从 sqlalchemy association_proxy 创建者访问父对象

java - 如何从java中的字符串中提取子字符串

java - 不同屏幕尺寸上的 Sprite 速度

css - 根据计算复杂度选择有效的选择器

python - 定义函数后,为什么不能更改其默认值?