如何修复pandas列格式错误,正确筛选指定年份对应活动的DataFrame?
解决方案
前置处理:日期格式转换
首先你需要先把Date列转换为pandas的datetime类型,否则无法直接提取年份属性:
import pandas as pd # 注意原始日期为日/月/年格式,添加dayfirst=True避免解析错误 df1['Date'] = pd.to_datetime(df1['Date'], dayfirst=True)
最优实现:向量化布尔索引(推荐)
完全不需要用循环遍历行,pandas内置的向量化查询性能更高,代码也更简洁,直接按条件过滤即可得到保留表头的结构化DataFrame:
# 筛选2015年、activity 1的数据,保留ID、Date两列 answer1 = df1.loc[ (df1['Date'].dt.year == 2015) & (df1['ACTIVITY'] == 'activity 1'), ['ID', 'Date'] ].reset_index(drop=True) # 筛选2015年、activity 2的数据,保留ID、Date两列 answer2 = df1.loc[ (df1['Date'].dt.year == 2015) & (df1['ACTIVITY'] == 'activity 2'), ['ID', 'Date'] ].reset_index(drop=True)
reset_index(drop=True)的作用是清理过滤后残留的原始行索引,得到连续的新索引。
原代码错误原因
- 未提前转换
Date列格式:原始Date是字符串类型,没有year属性,直接取rows['Date'].year会直接报错。 - 遍历
iterrows的方式本身效率极低,仅适合极小数据集使用。 - 取
rows['ID','Date']得到的是一维Series,直接追加时会被识别为单列数据,导致结构错乱;同时pandas 2.0+已经彻底移除了DataFrame.append()方法,该写法本身不兼容新版本。
循环写法修正版(不推荐,仅作参考)
如果你坚持要用循环实现,可按如下方式修改:
# 提前初始化指定列名的空DataFrame answer1 = pd.DataFrame(columns=['ID', 'Date']) answer2 = pd.DataFrame(columns=['ID', 'Date']) for index, rows in df1.iterrows(): if rows['Date'].year == 2015 : if rows['ACTIVITY'] == 'activity 1' : # 将一维Series转为单行DataFrame后再拼接 data1 = rows[['ID','Date']].to_frame().T answer1 = pd.concat([answer1, data1], ignore_index=True) if rows['ACTIVITY'] == 'activity 2' : data2 = rows[['ID','Date']].to_frame().T answer2 = pd.concat([answer2, data2], ignore_index=True)
内容的提问来源于stack exchange,提问作者Saksham Jain
相关产品推荐
相关产品推荐

