如何使用Pandas筛选内部两两存在连接的cells_subset细胞子集?
用Pandas实现全连接细胞子集的获取方案
嘿,你要解决的其实是找**完全子图(Clique)**的问题——也就是从cells里挑出一个子集,子集里任意两个cell在connections里都有对应的连接。下面给你两种实现思路,按需选择:
方法一:Pandas + NetworkX(推荐,高效处理大数据)
Pandas擅长表格操作,但找完全子图是图论问题,搭配NetworkX这个专业图库会高效很多,步骤如下:
1. 准备示例数据(替换成你的真实数据即可)
import pandas as pd import networkx as nx # 你的cells数据集 cells_df = pd.DataFrame({'id': [1, 2, 3, 4, 5]}) # 你的connections数据集 connections_df = pd.DataFrame({ 'id1': [1, 1, 1, 2, 2, 3], 'id2': [2, 3, 4, 3, 5, 4] })
2. 预处理连接数据,统一无向边格式
因为连接是无向的(比如(id1=1, id2=2)和(id1=2, id2=1)是同一个连接),我们先把每对连接按id从小到大排序,避免重复计算:
# 生成无向连接的标准化元组 connections_df['pair'] = connections_df.apply( lambda row: tuple(sorted((row['id1'], row['id2']))), axis=1 ) # 去重(如果有重复的连接记录) connections_df = connections_df.drop_duplicates(subset='pair')
3. 构建图并找出所有最大完全子图
最大完全子图指的是无法再添加任何cell进去还满足全连接条件的子集,它的所有子集也自然符合你的要求:
# 构建无向图 cell_graph = nx.Graph() cell_graph.add_nodes_from(cells_df['id']) cell_graph.add_edges_from(connections_df['pair']) # 找出所有最大完全子图 max_cliques = list(nx.find_cliques(cell_graph)) # 转成Pandas DataFrame展示结果 cliques_result = pd.DataFrame({'cells_subset': max_cliques}) print(cliques_result)
运行后你会得到类似这样的结果:
cells_subset 0 [1, 2, 3] 1 [1, 3, 4] 2 [2, 5]
比如[1,2,3]这个子集里,1和2、1和3、2和3都在connections里有对应连接,完全符合要求。
方法二:纯Pandas实现(适合小数据集)
如果不想引入额外库,纯Pandas也能实现,但只适合cells数量较少的场景(否则组合数会爆炸,效率极低):
1. 准备数据(同上)
import pandas as pd from itertools import combinations cells_df = pd.DataFrame({'id': [1, 2, 3, 4, 5]}) connections_df = pd.DataFrame({ 'id1': [1, 1, 1, 2, 2, 3], 'id2': [2, 3, 4, 3, 5, 4] })
2. 生成所有可能的细胞对并匹配连接
# 标准化连接对 connections_df['pair'] = connections_df.apply( lambda row: tuple(sorted((row['id1'], row['id2']))), axis=1 ) valid_pairs = set(connections_df['pair']) # 生成cells的所有两两组合 all_possible_pairs = list(combinations(cells_df['id'], 2))
3. 遍历筛选符合条件的子集
# 初始化所有单元素子集(单元素肯定满足条件) valid_subsets = [[cell] for cell in cells_df['id']] # 逐步扩展子集,检查所有内部对是否都在有效连接里 for subset_size in range(2, len(cells_df['id']) + 1): # 生成所有当前子集大小的候选组合 candidate_subsets = list(combinations(cells_df['id'], subset_size)) for candidate in candidate_subsets: # 检查该子集的所有两两对是否都在有效连接中 all_pairs_valid = all(tuple(sorted(p)) in valid_pairs for p in combinations(candidate, 2)) if all_pairs_valid: valid_subsets.append(list(candidate)) # 去重并转成DataFrame unique_subsets = list(set(tuple(sorted(s)) for s in valid_subsets)) unique_subsets = [list(s) for s in unique_subsets] result_df = pd.DataFrame({'cells_subset': unique_subsets}) print(result_df)
这个方法会列出所有符合条件的子集,包括单元素、双元素直到最大的完全子图,但数据量大的时候会非常慢,所以更推荐第一种方法。
内容的提问来源于stack exchange,提问作者sreved
相关产品推荐
相关产品推荐

