百万级数据集下Pandas条件标记的高效实现方法问询
百万级DataFrame的高效分类标记实现
问题背景
现有如下结构的DataFrame df(含百万条ID记录):
| ID | 1F_col | 2F_col | 3F_col | 4G_col |
|---|---|---|---|---|
| 1 | 0 | 1 | 1 | 1 |
| 2 | 0 | 1 | 0 | 0 |
| 3 | 1 | 1 | 0 | 1 |
| 4 | 0 | 0 | 0 | 1 |
| 5 | 0 | 0 | 0 | 0 |
| 6 | 1 | 1 | 1 | 1 |
需要完成以下3项操作:
- 生成
F_Type和G_Type列:若至少一个含F的列值为1,则F_Type标记为1;若至少一个含G的列值为1,则G_Type标记为1。 - 生成
Comm1列:当F_Type和G_Type均为1时返回"Good";F_Type为1、G_Type为0时返回"4G";其余情况返回"1F"。 - 生成
Comm2列:当F_Type和G_Type均为0时返回"Hard";若Comm1为"Good"则返回"Good";其余情况返回"Soft"。
最终目标得到如下结果:
| ID | F_Type | G_Type | Comm1 | Comm2 |
|---|---|---|---|---|
| 1 | 1 | 1 | Good | Good |
| 2 | 1 | 0 | 4G | Soft |
| 3 | 1 | 1 | Good | Good |
| 4 | 0 | 1 | 1F | Soft |
| 5 | 0 | 0 | 1F | Hard |
| 6 | 1 | 1 | Good | Good |
高效实现方案
针对百万级数据,必须优先使用Pandas矢量化操作(避免循环或apply,这类方法在大数据量下效率极低),具体代码如下:
步骤1:生成F_Type和G_Type
利用filter筛选目标列,再用any方法判断每行是否存在1,最后转为整数类型:
# 筛选含F的列,判断每行是否至少有一个1,转int得到F_Type df['F_Type'] = df.filter(like='F').any(axis=1).astype(int) # 筛选含G的列,同理得到G_Type df['G_Type'] = df.filter(like='G').any(axis=1).astype(int)
步骤2:生成Comm1列
使用numpy.select(比链式条件判断或apply更快),定义条件与对应结果:
import numpy as np # 定义Comm1的条件列表和结果列表 conditions_comm1 = [ (df['F_Type'] == 1) & (df['G_Type'] == 1), (df['F_Type'] == 1) & (df['G_Type'] == 0) ] results_comm1 = ['Good', '4G'] # 其余情况返回'1F' df['Comm1'] = np.select(conditions_comm1, results_comm1, default='1F')
步骤3:生成Comm2列
同样用numpy.select,基于已有列的条件生成结果:
conditions_comm2 = [ (df['F_Type'] == 0) & (df['G_Type'] == 0), df['Comm1'] == 'Good' ] results_comm2 = ['Hard', 'Good'] # 其余情况返回'Soft' df['Comm2'] = np.select(conditions_comm2, results_comm2, default='Soft')
提取最终结果(可选)
若仅需要目标列,直接筛选即可:
final_df = df[['ID', 'F_Type', 'G_Type', 'Comm1', 'Comm2']]
效率说明
- 所有操作均为矢量化运算,Pandas/Numpy底层基于C实现,百万级数据处理时间通常在毫秒级。
- 绝对避免使用
df.apply(lambda x: ...)这类逐行处理方法,其时间复杂度高且常数项极大,百万级数据会慢几十到上百倍。
内容的提问来源于stack exchange,提问作者Scope
相关产品推荐
相关产品推荐

