基于另一groupby DataFrame筛选分组后DataFrame的非进站圈数据
如何过滤DataFrame中每位车手的进站圈
你提到有两个包含driverId和lap列的DataFrame(AUS_2016和df_pitLaps),想要从AUS_2016中移除每个车手对应的进站圈,但用自定义函数时遇到了DeprecationWarning,而且得到的结果不符合预期——这其实是因为你原来的groupby+lambda元素比较逻辑没处理好,导致配对错误触发了警告。
我给你提供一个更简洁高效的方案,不需要依赖groupby,直接通过DataFrame合并来实现需求:
最终解决方案代码
def no_pitlaps(df, df_pitLaps): """Returns a dataframe that excludes the pit laps of each driver""" # 左连接主DataFrame和进站圈数据,匹配driverId和lap列 data_pitlaps_mapped = pd.merge( df, df_pitLaps[['driverId', 'stop', 'lap']], how='left', left_on=['driverId','lap'], right_on=['driverId','lap'] ) # 排除掉有进站记录(stop列非空)的行 return data_pitlaps_mapped.loc[~data_pitlaps_mapped.index.isin( data_pitlaps_mapped.dropna(subset=['stop']).index )]
代码逻辑解释
- 合并数据:用
pd.merge做左连接,把df_pitLaps中每个车手的进站圈信息(driverId、lap、stop)关联到主DataFramedf里。这样所有进站圈对应的行都会填充stop值,非进站圈的行stop列会是NaN。 - 过滤进站圈:通过
dropna(subset=['stop'])找到所有进站圈的行,然后用~取反,排除这些行的索引,剩下的就是不含进站圈的DataFrame。
为什么原来的代码会报错?
你原来的clean_laps_no_pitlaps函数里,itertools.izip(x, data)的配对逻辑是错误的——groupby后的x和data并不是按车手对应的进站圈和圈数一一配对的,导致元素级别的!=比较失败,触发了DeprecationWarning,而且最终得到的全是True值的结果也无法用于筛选。
调用这个新函数的方式很简单:
filtered_df = no_pitlaps(AUS_2016, df_pitLaps)
内容的提问来源于stack exchange,提问作者doyz
相关产品推荐
相关产品推荐

