PySpark:移除与指定日期匹配的DataFrame记录问题求助
问题描述
现有两个PySpark DataFrame:
- 第一个DataFrame(
fdcn_df)包含id和myTimeStamp列,存储带时间戳的业务记录 - 第二个DataFrame(
holidays_df)包含myTimeToRemove列,存储需要排除的日期
需求:移除fdcn_df中日期部分与holidays_df中任意日期匹配的记录(时间部分不影响匹配逻辑)。
尝试以下代码后未得到预期结果:
fdcn_df = fdcn_df.join(holidays_df, fdcn_df['myTimeStamp'].cast('date') != holidays_df['myTimeToRemove'].cast('date'),"inner")
原因分析
原代码的逻辑完全错误:inner join搭配!=条件会生成笛卡尔积式的匹配——只要fdcn_df的某条记录和holidays_df中任意一条日期不匹配,这条记录就会被保留并输出,甚至会因为多个不匹配日期重复输出。这完全违背了“移除所有匹配日期记录”的核心需求。
正确解决方案
方案1:左反连接(推荐,性能最优)
左反连接(left_anti)是PySpark处理这类“排除匹配记录”场景的标准方式,它会保留左表中不存在于右表匹配条件的所有记录:
fdcn_filtered = fdcn_df.join( holidays_df, fdcn_df['myTimeStamp'].cast('date') == holidays_df['myTimeToRemove'].cast('date'), "left_anti" )
方案2:子查询过滤(适合小数据集)
先提取需要排除的日期集合,再对原DataFrame进行过滤:
# 提取并去重所有需要排除的日期 exclude_dates = holidays_df.select( holidays_df['myTimeToRemove'].cast('date').alias('exclude_date') ).distinct() # 过滤掉匹配日期的记录 fdcn_filtered = fdcn_df.filter( ~fdcn_df['myTimeStamp'].cast('date').isin( exclude_dates.rdd.map(lambda x: x[0]).collect() ) )
注意:如果holidays_df数据量较大,collect()会将数据拉取到Driver节点,可能引发内存问题,此时优先用方案1。
内容的提问来源于stack exchange,提问作者JP7
相关产品推荐
相关产品推荐

