首先,对不起我的英语不太好。在
我想我的问题很容易解释。在
result={}
list_tuple=[(float,float,float),(float,float,float),(float,float,float)...]#200k tuples
threshold=[float,float,float...] #max 1k values
for tuple in list_tuple:
for value in threeshold:
if max(tuple)>value and min(tuple)<value:
if value in result:
result[value].append(tuple)
else:
result[value]=[]
result[value].append(tuple)
列表元组包含大约20万个元组,我必须非常快地执行此操作(在普通pc上最多2/3秒)。在
我的第一个尝试是在cython中使用prange()来实现这一点(这样我就可以从cython优化和并行执行中获得好处),但问题是(一如既往地),GIL:在prange()中,我可以使用cython memviews管理列表和元组,但我不能将结果插入dict
在cython中,我也尝试使用c++std的无序映射,但现在的问题是我不能用c++生成数组的向量(这就是我dict的值)。在
第二个问题类似:
^{pr2}$这里我还有另一个问题,如果要使用prange(),我必须使用一个自定义哈希函数来使用数组作为c++无序映射的键
如你所见,我的代码片段很容易并行运行。在
我想尝试使用numba,但可能会因为GIL而相同,我更喜欢使用cython,因为我需要一个二进制代码(这个库可能是商业软件的一部分,所以只允许使用二进制库)。在
一般来说,我希望避免使用c/c++函数,我希望找到的是一种并行管理dicts/list的方法,它具有cython的性能,尽可能多地保留在Python域中;但是我愿意接受所有的建议。在
谢谢
@a_客人代码:
此代码为
thresh
中的每个项创建一个字典条目。在操作代码,用
^{pr2}$default_dict
(来自collections
)稍微简化了一点:对于符合条件的每个条目,此项更新一次词典条目。在
以及他的样本数据:
^{3}$时间测试:
数组上的迭代比使用列表慢。
tolist()
的时间最短;np.asarray
的时间更长。在对于较大的数据样本,
array
版本更快:编辑
由于这种方法基本上是在数据样本和阈值之间执行外部积,因此它会显著增加所需的内存,这可能是不需要的。An improved approach can be found here.我仍然保留这个答案以备将来参考,因为它是在{a2}中引用的。在
我发现与OP代码相比,性能的提高是
~ 20
的一个因素。在这是一个使用
numpy
的示例。数据和操作都是矢量化的。注意,结果dict包含空列表,而不是OP的示例,因此可能需要额外的清理步骤(如果合适)。在通过使用
numpy
的矢量化功能,可以实现一些性能改进:min
和{list_tuple
)是在纯Python中执行的。此循环可以使用numpy
进行矢量化。在在下面的测试中,我使用了
data.shape == (200000, 3); thresh.shape == (1000,)
,如操作中所示。我还省略了对result
dict
的修改,因为这取决于数据,这可能会使内存迅速溢出。在应用1。
{a}比cda}的性能提高。在
应用1。&;2.
^{pr2}${10}比cda}的性能提高。这种方法的另一个好处是它不包含对列表的增量
append
,这可能会降低程序的速度,因为可能需要重新分配内存。相反,它在一次尝试中创建每个列表(每个阈值)。在相关问题 更多 >
编程相关推荐