如何在Pandas中预过滤列表列内容后再展开,提升处理效率?
优化含列表列的Pandas数据过滤与展开效率
场景与问题
现有带列表类型列group_ids的Pandas DataFrame:
import pandas as pd df_have = pd.DataFrame({'user': ['emp_1', 'emp_2', 'emp_3', 'admin'], 'group_ids': [[5, 3], [4, 2, 3], [1, 4], [1, 2, 3, 4, 5]]})
输出结果:
df_have
user group_ids
0 emp_1 [5, 3]
1 emp_2 [4, 2, 3]
2 emp_3 [1, 4]
3 admin [1, 2, 3, 4, 5]
当前采用先展开再过滤的方式获取目标数据:
df_have = df_have.explode('group_ids') selected_ids = [2, 3] df_want = df_have[df_have['group_ids'].isin(selected_ids)]
输出结果:
df_want
user group_ids
0 emp_1 3
1 emp_2 2
1 emp_2 3
3 admin 2
3 admin 3
该方法结果正确,但当group_ids列包含大量元素(超过100个)时,速度会显著下降——而实际业务中selected_ids通常仅包含不到5个分组ID。
优化方案:先过滤列表元素,再展开
核心思路是先对每个group_ids列表预过滤,仅保留属于selected_ids的元素,再对过滤后的列表执行展开操作,避免处理大量无关元素,大幅提升效率。
具体实现步骤
- 将
selected_ids转换为集合:集合的成员查询操作是O(1)时间复杂度,远快于列表的O(n),进一步提升过滤速度。 - 过滤每个
group_ids列表:仅保留在selected_ids中的元素。 - 过滤掉过滤后列表为空的行(可选,根据业务需求决定是否保留)。
- 对过滤后的列表执行
explode操作,并重命名列名恢复原格式。
代码示例
import pandas as pd df_have = pd.DataFrame({'user': ['emp_1', 'emp_2', 'emp_3', 'admin'], 'group_ids': [[5, 3], [4, 2, 3], [1, 4], [1, 2, 3, 4, 5]]}) selected_ids = {2, 3} # 转集合提升查询效率 # 预过滤每个group_ids列表,仅保留目标ID df_have['filtered_groups'] = [ [id for id in lst if id in selected_ids] for lst in df_have['group_ids'] ] # 移除过滤后无有效元素的行(可选) df_have = df_have[df_have['filtered_groups'].str.len() > 0] # 展开过滤后的列表,并恢复列名 df_want = df_have.explode('filtered_groups').rename(columns={'filtered_groups': 'group_ids'}) # 可选:删除原group_ids列 df_want = df_want.drop(columns=['group_ids'])
执行后得到的df_want与原方法结果完全一致,但效率提升明显——尤其是当group_ids包含大量元素时,仅展开少量目标元素,避免了不必要的计算开销。
性能优化补充
如果DataFrame行数极大,推荐使用列表推导式(如上示例)而非apply方法,因为列表推导式的执行效率远高于apply,能进一步减少处理时间。
内容的提问来源于stack exchange,提问作者Grizzly2501
相关产品推荐
相关产品推荐

