如何高效筛选Pandas DataFrame中符合指定位条件的行并生成新DataFrame
问题描述
我用Python处理日志文件,逐行处理后存入DataFrame再导出为CSV。后续加载CSV的代码如下:
df = pd.read_csv(path) # -> 加载已有文件到DataFrame df = df.dropna(subset=['Telegram_Header']) # -> 删除所有没有Telegram Header的行 df.reset_index()
已经把Telegram_Header列的8字节十六进制值(比如0C00071A01651118)转换成了二进制字符串(比如0000110000000000000001110001101000000001011001010001000100011000),现在需要筛选出该列中特定位已设置的行,复制到新DataFrame df2。
我尝试循环遍历Telegram_Header列:
for header in df['Header']: tmp = int(header, 2) & 15 if tmp == 15: print(header)
但遇到三个问题:
- 不知道怎么把匹配的行复制到
df2; - 循环效率太低(数据量很大);
- 输出结果不符合预期。
示例DataFrame:
import pandas as pd import numpy as np df = pd.DataFrame({'S': ['I', 'M', 'M', 'M', 'M'], 'Header': [np.nan, '10101111', '10111011', '10111011', '11001111'], 'Data': ['Other Info', 'More & longer string with bit pattern', 'More & longer string with bit pattern', 'More & longer string with bit pattern', 'More & longer string with bit pattern'] }) df = df.dropna(subset=['Header'])
期望得到的df2结果:
S Header Data 0 M 10101111 More & longer string with bit pattern 1 M 11001111 More & longer string with bit pattern
请问最优实现方法是什么?
最优实现方案
核心思路:用Pandas向量化操作替代循环,高效筛选符合位条件的行
从示例和代码来看,你要筛选的是二进制字符串最后4位全为1的行(&15对应二进制最后4位,等于15即1111)。Pandas的向量化操作能大幅提升效率,同时直接完成筛选赋值。
基础实现代码
import pandas as pd import numpy as np # 加载并预处理数据,优化reset_index避免生成冗余列 df = pd.read_csv(path) df = df.dropna(subset=['Telegram_Header']).reset_index(drop=True) # 用布尔索引直接筛选符合条件的行 df2 = df[df['Telegram_Header'].apply(lambda x: int(x, 2) & 15 == 15)].reset_index(drop=True)
针对示例DataFrame的验证
替换列名后直接运行即可得到预期结果:
df = pd.DataFrame({'S': ['I', 'M', 'M', 'M', 'M'], 'Header': [np.nan, '10101111', '10111011', '10111011', '11001111'], 'Data': ['Other Info', 'More & longer string with bit pattern', 'More & longer string with bit pattern', 'More & longer string with bit pattern', 'More & longer string with bit pattern'] }) df = df.dropna(subset=['Header']) df2 = df[df['Header'].apply(lambda x: int(x,2) &15 ==15)].reset_index(drop=True) print(df2)
输出结果完全匹配预期。
超大数据量进阶优化
如果数据量极大,可以把二进制转整数的操作批量拆分,进一步提升性能:
# 批量转换二进制字符串为整数 header_ints = df['Telegram_Header'].apply(lambda x: int(x, 2)) # 基于整数数组做位运算筛选 df2 = df[header_ints & 15 == 15].reset_index(drop=True)
方案优势
- 效率高:向量化操作比Python循环快数倍到数十倍,数据量越大优势越明显;
- 代码简洁:一行布尔索引直接完成筛选,无需手动处理行复制逻辑;
- 结果准确:避免循环中可能出现的索引错位问题,筛选逻辑清晰可追溯。
内容的提问来源于stack exchange,提问作者Phil94
相关产品推荐
相关产品推荐

