Pandas DataFrame中匹配列字符串出现年份及计算年份差值方法
嘿,这个需求我熟,用Pandas处理完全没问题,而且不用费劲手动遍历——Pandas的向量操作既高效又简洁,我给你一步步拆解实现方案:
实现方案
1. 先准备示例数据(方便演示)
首先我们构造一个包含year(年份列)、c1、c2的示例DataFrame,包含你提到的NaN场景:
import pandas as pd import numpy as np # 构造模拟数据 data = { 'year': [2018, 2019, 2020, 2021, 2022, 2023], 'c1': ['apple', 'banana', 'apple', np.nan, 'orange', 'banana'], 'c2': ['banana', np.nan, 'apple', 'orange', 'banana', 'grape'] } df = pd.DataFrame(data) print("原始数据:") print(df)
2. 预处理:提取c1列每个字符串的首次出现年份
先做一步预处理,把c1列里所有非NaN值的首次出现年份存起来,后续直接匹配用:
# 过滤c1的NaN值,按字符串分组取最小年份(即首次出现的年份) c1_first_year = df.dropna(subset=['c1']).groupby('c1')['year'].min() print("\nc1列各字符串首次出现年份:") print(c1_first_year)
3. 核心处理:生成目标结果(推荐用向量操作,效率拉满)
这里不用手动遍历,直接用Pandas的内置方法完成所有逻辑,大数据量下比循环快N倍:
# 第一步:筛选c2非NaN的行,提取字符串和对应年份 result_df = df.dropna(subset=['c2'])[['year', 'c2']].rename(columns={'year': 'c2_year', 'c2': 'string'}) # 第二步:匹配c1列的首次出现年份,不存在则显示NaN result_df['c1_first_year'] = result_df['string'].map(c1_first_year) # 第三步:计算年份差值,自动忽略NaN场景 result_df['year_diff'] = result_df['c2_year'] - result_df['c1_first_year'] print("\n最终处理结果:") print(result_df)
4. 如果你一定要手动遍历(仅作演示,不推荐)
如果因为特殊业务逻辑必须手动遍历,也可以这么写,但强烈建议用上面的向量操作,循环在数据量大时效率极低:
# 手动遍历版本(仅适合小数据量) results = [] for idx, row in df.iterrows(): c2_str = row['c2'] c2_year = row['year'] # 跳过c2的NaN值 if pd.isna(c2_str): continue # 从预处理的结果里取c1首次出现年份,没有则设为NaN c1_first = c1_first_year.get(c2_str, np.nan) # 计算差值,处理NaN情况 year_diff = c2_year - c1_first if not pd.isna(c1_first) else np.nan # 收集结果 results.append({ 'string': c2_str, 'c2_year': c2_year, 'c1_first_year': c1_first, 'year_diff': year_diff }) # 转成DataFrame输出 manual_result = pd.DataFrame(results) print("\n手动遍历结果:") print(manual_result)
关键说明
- 处理NaN时,用
dropna和pd.isna来判断,避免报错 - 优先用Pandas的向量操作(比如
map、groupby),比iterrows循环效率高很多,尤其是数据量超过1万行时差异明显
内容的提问来源于stack exchange,提问作者mapk
相关产品推荐
相关产品推荐

