Python/Numpy:将行元素与条件的组合矢量化
有没有一种方法可以在特定条件下对行元素的组合进行矢量化 条件:Python/Numpy:将行元素与条件的组合矢量化,python,performance,numpy,multidimensional-array,vectorization,Python,Performance,Numpy,Multidimensional Array,Vectorization,有没有一种方法可以在特定条件下对行元素的组合进行矢量化 条件: 空元素被删除 包含多个非空元素的行由“\n”分隔 注意 a) 我的数组有可变数量的行和列,并且会变得相当大,因此我对这里的矢量化感兴趣 b) 每个非空字符串元素都以“$”字符开头 arr = np.array([ ['', '', '$c'], ['', '$b', '' ], ['', '$b', '$c'], ['$a', '', '' ],
arr = np.array([
['', '', '$c'],
['', '$b', '' ],
['', '$b', '$c'],
['$a', '', '' ],
['$a', '', '$c'],
['$a', '$b', '' ],
['$a', '$b', '$c']
], dtype='U1')
预期结果:
res = [
['$c'], # <-- reduce to single char element
['$b'], # <-- reduce to single char element
['$b\n$c'], # <-- combine char elements with '\n' delimiter
['$a'], # <-- reduce to single char element
['$a\n$c'], # <-- combine char elements with '\n' delimiter
['$a\n$b'], # <-- combine char elements with '\n' delimiter
['$a\n$b\n$c'] # <-- combine char elements with '\n' delimiter
]
res=[
['$c'],#即使在您最新的情况下,我也不推荐基于numpy的解决方案,而是使用
arr=arr.tolist()
空_removed=[[el代表行中el,如果el!='']代表arr中的行]
结果=[“\n”。为空\u中的行加入(行)已删除]
即使对于您的小示例,您也可以在注释中看到与您的解决方案相比的显著速度差异:
#阵列解决方案
timeit.timeit(“['\\n'.join(sub[sub!='')表示arr中的sub]”,“从主导入arr”)
#时间:13.1772538999982
#列表解决方案(初始转换为列表)
timeit.timeit(“['\\n.join(row)for row in[[el for el in row if el!='']for row in arr.tolist()]”,“from _umain_uuu导入arr”)
#时间:1.938735900000117
#列出解决方案(如果可以避免开头的数组)
timeit.timeit(“['\\n'.加入(行)中的行[[el代表行中的el,如果el!='']代表列中的行]],“从主列导入列中”)
#时间1.408489999922
如果您想在以后将其转换为numpy数组以使用np.tile
和np.repeat
,这当然可以做到。但是,我会测试这是否不会导致管道中出现类似的减速
旧答案,供参考
我建议您不要使用NumPy数组,而是切换到简单明了的列表理解:
arr=arr.tolist()#如果可以避免创建数组,那就更好了
结果=['\n.在['''.在arr]中为sub加入(sub)['.在arr中为sub加入(sub)]]
#或者,如果需要包含单个元素的列表
结果2=['\n.join(sub)]表示在['''.join(sub)表示在arr中的sub]]
原因有点复杂。其要点是numpy不能像在dtype=np.number
上那样加速dtype=object
上的数组操作。你可以得到与奇特索引相同的便利性(我想现在的名称是高级索引)和基于元组的索引,但实际性能无法比较。您可以在这里获得一些直觉:这是否回答了您的问题?感谢您提供的信息性答案!我使用numpy的原因是因为我在脚本中稍后使用np.tile和np.repeat扩展数组,这比迭代构建数组快得多。我可以使用列表在这里,然后转换为numpy数组。我为没有包含在问题中而道歉(将更新)数据类型是根据最长字符串的长度动态分配的:从“U1”到“U100”的任意位置我如何调整它以处理超过1个字符的数组元素?我刚刚在我的用例中测试了这一点,并在每个元素的每个字符之间插入“\n”(将问题修改为包含长度超过1个字符的数组元素)这里是:result3=['\n'.join(sub[sub!='')for sub in arr]
@CraigNathan我更新了我的答案以回应您的评论和更新的问题。