如何不使用for循环按分组规则填充Pandas DataFrame指定列值
Pandas高效实现方案
你要的效果可以通过Pandas分组+向前填充的向量化操作实现,完全避免Python层for循环,运算效率高得多,代码也更简洁。
实现代码
import pandas as pd import numpy as np # 构造测试数据 data = {'ID': [1,1,1,1,2,2,3,3,3,3], 'EVENT': [12, 20, 32, 43,1,2,1,12,13,15], 'DATE_ONE': ['3/1/2021','3/5/2021','3/6/2021','3/7/2021','3/3/2021','4/5/2021', '3/1/2021','3 /7/2021','3/9/2021','3/14/2021'], 'DATE_TWO': ['','3/5/2021','','','','','','3/7/2021','','']} df = pd.DataFrame(data) # 1、数据清洗:处理日期列的空格、空值,转为datetime格式 df['DATE_ONE'] = pd.to_datetime(df['DATE_ONE'].str.replace(' ', '')) df['DATE_TWO'] = pd.to_datetime(df['DATE_TWO'].replace('', np.nan)) # (可选)如果有脏数据需要严格校验DATE_TWO >= DATE_ONE的条件,打开下面这行 # df.loc[df['DATE_TWO'] < df['DATE_ONE'], 'DATE_TWO'] = np.nan # 2、核心逻辑:按ID分组,对DATE_TWO做向前填充 df['DATE_TWO'] = df.groupby('ID')['DATE_TWO'].ffill() # 3、可选:把日期转回原格式的字符串 df[['DATE_ONE', 'DATE_TWO']] = df[['DATE_ONE', 'DATE_TWO']].apply( lambda x: x.dt.strftime('%m/%d/%Y').str.lstrip('0').str.replace('/0', '/') ).replace('NaT', '')
效率说明
Pandas的分组、填充都是底层C实现的向量化操作,比Python原生for循环效率高2~3个数量级,数据量越大优势越明显,也符合Python数据处理的惯用写法。
内容的提问来源于stack exchange,提问作者Matthew David Jankowski
相关产品推荐
相关产品推荐

