pandas 集合比较优化

bwleehnv  于 2023-01-11  发布在  其他
关注(0)|答案(2)|浏览(84)

描述

我有两大串集合

A = [ {...}, ..., {...} ]
B = [ {...}, ..., {...} ]

我正在执行一个非常耗费成本的列表解析,它针对A中每个集合中的每个元素检查是否与B的集合中的任何元素匹配,如果匹配,则返回B的相应集合。

[find_sets(i) for i in A]

示例

一个最小的例子如下所示:

import secrets

# create sample data 
def generate_random_strings(num_strings, string_length):
    random_strings = []
    for i in range(num_strings):
        random_strings.append(secrets.token_hex(string_length))
    random_strings = set(random_strings)
    return random_strings

A = [generate_random_strings(5, 1) for i in range(10000)]
B = [generate_random_strings(5, 1) for i in range(10000)]

# set checker 
def find_sets(A):
    matching_sets = []
    for b_set in B:
        if A & b_set:
            matching_sets.append(b_set)
    return matching_sets

result = [find_set(i) for i in A]

多重处理

在我所有的32个CPU核心上,它的速度明显更快:

from tqdm.contrib.concurrent import process_map

pool = multiprocessing.Pool(processes=32)
results = process_map(find_sets, A, chunksize=100)

问题

虽然对于A和B的几千个元素,列表解析在我的机器上运行得相当快,多处理有助于将其扩展到大约50.000个元素,但对于每个列表中的500.000个元素,这是我的实际大小,它变得非常慢。
有没有什么方法可以通过矢量化、散列之前的集合或使用某种优化的数据类型(冻结集合没有帮助)来加速我的函数代码?

lstz6jyr

lstz6jyr1#

在我的测试中,这要快一个数量级:

import collections

reverse_map = collections.defaultdict(set)
for idx, elements in enumerate(B):
    for element in elements:
        reverse_map[element].add(idx)

def find_sets(A):
    union = set()
    emptyset = set()
    for element in A:
        union |= reverse_map.get(element, emptyset)
    return [B[idx] for idx in union]
5vf7fwbs

5vf7fwbs2#

你可以用理解代替find_sets

result = [[b for b in B if a & b] for i in A]

相关问题