如何统计多1D数组中重复共现的数字组合及其出现次数?
找出Pandas Series中数组的共现数字组合及出现次数
预处理数据
首先过滤掉空数组或长度不足2的无效数组,同时将每个有效数组转为排序后的元组——这样能保证(2,3)和(3,2)被视为同一组合,且元组可哈希,能作为字典的键:
import numpy as np import pandas as pd from itertools import combinations from collections import defaultdict # 示例数据 a = np.array([1,2,3]) b = np.array([]) c = np.array([2,3,4,5,6]) d = np.array([2,3,4,5,6,9,15]) e = np.array([5,6]) s = pd.Series([a,b,c,d,e]) # 预处理流程 valid_arrays = [tuple(sorted(arr)) for arr in s if len(arr) >= 2]
统计共现组合(基础版)
通过生成每个有效数组的所有长度≥2的子集,统计每个子集在多少个数组中出现:
count_dict = defaultdict(int) for arr_tuple in valid_arrays: # 生成当前数组所有长度2到自身长度的子集 for k in range(2, len(arr_tuple)+1): for combo in combinations(arr_tuple, k): count_dict[combo] += 1 # 筛选出在多个数组中出现的组合(出现次数≥2) result = {combo: cnt for combo, cnt in count_dict.items() if cnt >= 2} print(result)
运行结果(包含所有符合条件的组合):
{(2, 3): 3, (2, 4): 2, (2, 5): 2, (2, 6): 2, (3, 4): 2, (3, 5): 2, (3, 6): 2, (4, 5): 2, (4, 6): 2, (5, 6): 3, (2, 3, 4): 2, (2, 3, 5): 2, (2, 3, 6): 2, (2, 4, 5): 2, (2, 4, 6): 2, (2, 5, 6): 2, (3, 4, 5): 2, (3, 4, 6): 2, (3, 5, 6): 2, (4, 5, 6): 2, (2, 3, 4, 5): 2, (2, 3, 4, 6): 2, (2, 3, 5, 6): 2, (2, 4, 5, 6): 2, (3, 4, 5, 6): 2, (2, 3, 4, 5, 6): 2}
性能优化(大规模数据适用)
如果数组元素较多,生成所有子集的开销会很大,推荐用Apriori算法挖掘频繁项集(即出现次数达标的组合),借助mlxtend库实现:
from mlxtend.frequent_patterns import apriori from mlxtend.preprocessing import TransactionEncoder # 将有效数组转为事务格式 te = TransactionEncoder() te_ary = te.fit(valid_arrays).transform(valid_arrays) df = pd.DataFrame(te_ary, columns=te.columns_) # 挖掘频繁项集:min_support为最小支持度(出现次数/总有效数组数) # 示例中总共有4个有效数组,要出现至少2次,支持度=2/4=0.5 frequent_itemsets = apriori(df, min_support=0.5, use_colnames=True) # 计算实际出现次数 frequent_itemsets['count'] = frequent_itemsets['support'] * len(valid_arrays) # 筛选出长度≥2的项集并转为字典 result_dict = {tuple(sorted(itemset)): int(count) for itemset, count in zip(frequent_itemsets['itemsets'], frequent_itemsets['count']) if len(itemset)>=2} print(result_dict)
该方法在处理大规模数据时性能远高于基础版,结果与基础版一致。
批量处理200多个Series
将逻辑封装为函数,循环处理所有Series即可:
def get_cooccurrence_combinations(s): valid_arrays = [tuple(sorted(arr)) for arr in s if len(arr) >= 2] if not valid_arrays: return {} count_dict = defaultdict(int) for arr_tuple in valid_arrays: for k in range(2, len(arr_tuple)+1): for combo in combinations(arr_tuple, k): count_dict[combo] += 1 return {combo: cnt for combo, cnt in count_dict.items() if cnt >= 2} # 假设series_list是你的200多个Series组成的列表 series_list = [s, ...] # 替换为实际数据 all_results = [get_cooccurrence_combinations(series) for series in series_list]
内容的提问来源于stack exchange,提问作者dimitris
相关产品推荐
相关产品推荐

