Pandas能否从集合创建DataFrame?列表查重慢、保留顺序优化咨询
问题解答
你原代码运行变慢的核心原因是:列表的in运算符时间复杂度为O(n),每新增一个元素都要遍历整个列表判断是否存在,数据量越大执行速度衰减越明显。
问题1:集合转DataFrame相关问题
- 首先你无法将
rel_dict存入集合:Python中字典属于可变不可哈希类型,不能作为集合的元素,直接执行relations = set()后添加字典会直接抛出TypeError: unhashable type: 'dict'报错,该方案从底层逻辑上不可行。 - 就算你用可哈希类型替换字典存入集合,Pandas也不推荐直接传入集合创建DataFrame:集合是无序容器(Python 3.7+的CPython实现虽然保留插入顺序,但属于语言实现细节,非语法标准),传入后生成的DataFrame顺序无法得到稳定保证,无法满足你保留插入顺序的需求。
问题2:OrderedDict方案可行性与最优方案选择
你给出的OrderedDict示例代码同样无法运行,核心原因和集合场景一致:字典不能作为OrderedDict的key,执行relations[rel_dict] = rel_dict时会抛出同样的不可哈希报错,该方案也不可行。
可用优化方案
推荐以下两种经过验证的实现,都能同时满足去重、保留插入顺序、兼容DataFrame创建的需求:
方案1:额外维护去重标记集合(性能最优,适合大数据量场景)
用一个单独的set存储已出现的关系的可哈希标记(将三个固定字段拼接为元组),列表还是存储原始字典,查询复杂度为O(1),完全解决原代码的性能问题:
relations = [] seen_keys = set() ... # 拼接唯一键,可哈希可存入集合 rel_key = (start, end, relationship) if rel_key not in seen_keys: seen_keys.add(rel_key) relations.append({'start': start, 'end': end, 'type': relationship}) rel_df = pd.DataFrame(relations)
方案2:生成DataFrame后统一去重(写法最简洁,适合中小数据量场景)
不需要在插入阶段做去重,所有数据先存入列表,生成DataFrame后调用pandas原生优化过的去重方法,也能保留插入顺序:
relations = [] ... # 无需判断去重直接插入 relations.append({'start': start, 'end': end, 'type': relationship}) # 生成DataFrame后统一去重,keep='first'保留首次插入的顺序 rel_df = pd.DataFrame(relations).drop_duplicates(subset=['start', 'end', 'type'], keep='first').reset_index(drop=True)
内容的提问来源于stack exchange,提问作者marlon
相关产品推荐
相关产品推荐

