【问题标题】:PySpark: filtering a DataFrame by date field in range where date is stringPySpark:在日期为字符串的范围内按日期字段过滤DataFrame
【发布时间】:2016-07-07 01:20:12
【问题描述】:

我的数据框包含一个日期字段,它以字符串格式显示,例如

'2015-07-02T11:22:21.050Z'

我需要过滤日期的 DataFrame 以仅获取上周的记录。 因此,我尝试了一种映射方法,其中我将字符串日期转换为使用 strptime 的日期时间对象:

def map_to_datetime(row):
     format_string = '%Y-%m-%dT%H:%M:%S.%fZ'
     row.date = datetime.strptime(row.date, format_string)

df = df.map(map_to_datetime)

然后我将过滤器应用为

df.filter(lambda row:
    row.date >= (datetime.today() - timedelta(days=7)))

我设法让映射工作,但过滤器失败了

TypeError: 条件应该是字符串或列

有没有办法以一种有效的方式使用过滤,或者我应该改变方法以及如何改变?

【问题讨论】:

    标签: python date datetime dataframe pyspark


    【解决方案1】:

    我想出了一种方法来解决我的问题,方法是使用带有字符串格式日期的 SparkSQL API。

    这是一个例子:

    last_week = (datetime.today() - timedelta(days=7)).strftime(format='%Y-%m-%d')
    
    new_df = df.where(df.date >= last_week)
    

    【讨论】:

    • import datetime last_week = (datetime.datetime.today() - datetime.timedelta(days=7)).strftime(format='%Y-%m-%d')
    【解决方案2】:

    火花 >= 1.5

    您可以使用INTERVAL

    from pyspark.sql.functions import expr, current_date
    
    df_casted.where(col("dt") >= current_date() - expr("INTERVAL 7 days"))
    

    火花

    您可以在不使用工作端 Python 代码和切换到 RDD 的情况下解决此问题。首先,由于您使用 ISO 8601 字符串,您的数据可以直接转换为日期或时间戳:

    from pyspark.sql.functions import col
    
    df = sc.parallelize([
        ('2015-07-02T11:22:21.050Z', ),
        ('2016-03-20T21:00:00.000Z', )
    ]).toDF(("d_str", ))
    
    df_casted = df.select("*",
        col("d_str").cast("date").alias("dt"), 
        col("d_str").cast("timestamp").alias("ts"))
    

    这将节省 JVM 和 Python 之间的一次往返。还有一些方法可以接近第二部分。仅日期:

    from pyspark.sql.functions import current_date, datediff, unix_timestamp
    
    df_casted.where(datediff(current_date(), col("dt")) < 7)
    

    时间戳:

    def days(i: int) -> int:
        return 60 * 60 * 24 * i
    
    df_casted.where(unix_timestamp() - col("ts").cast("long") < days(7))
    

    你也可以看看current_timestampdate_sub

    注意:我会避免使用DataFrame.map。最好改用DataFrame.rdd.map。切换到 2.0+ 时,它将为您节省一些工作

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-23
      • 1970-01-01
      • 1970-01-01
      • 2015-04-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多