我正在使用pyspark 2.3.0版本。 我正在过滤时间戳列上的数据帧。
|-requestTs:时间戳记(nullable = true)
当我在日间时间范围内进行过滤时,效果很好。 当我在2天范围内覆盖过滤器时,它不会返回所有记录。 我尝试了几种方法:
df1 = df.filter(df["requestts"] >= sqlf.lit(startDatestr)) \
.filter(df["requestts"] <= sqlf.lit(endDatestr))
或
dates = (startDatestr, endDatestr)
q1 = "unix_timestamp(requestts) BETWEEN unix_timestamp('{0}', 'yyyy-MM-dd HH:mm:ss') AND unix_timestamp('{1}', 'yyyy-MM-dd HH:mm:ss')".format(
*dates)
df1 = df.where(q1)
其中
startDatestr: 2018-06-26 07:00:00
endDatestr: 2018-06-26 21:40:00
当我计算返回的记录时
after date filter, count is :1168940768
如果我扩大搜索范围(因此希望有更多或相等的记录数),如:
startDatestr: 2018-06-25 11:00:00
endDatestr: 2018-06-26 21:40:00
我得到的记录数量要少得多。
我很困惑这可能是什么原因,以及按时间戳进行过滤的最佳方法是什么。 以及我如何考虑时区。
答案 0 :(得分:0)
您的查询应该可以使用。我只是在pyspark shell上尝试过。
>>> from datetime import datetime
>>> import pyspark.sql.functions as F
>>> columns = ['id', 'ts']
>>> vals = [
... (1, datetime(2018, 6, 26)),
... (2, datetime(2018, 6, 27)),
... (3, datetime(2018, 6, 28)),
... (4, datetime(2018, 6, 29)),
... (5, datetime(2018, 6, 30))
... ]
>>> df = spark.createDataFrame(vals, columns)
>>> df.show()
+---+-------------------+
| id| ts|
+---+-------------------+
| 1|2018-06-26 00:00:00|
| 2|2018-06-27 00:00:00|
| 3|2018-06-28 00:00:00|
| 4|2018-06-29 00:00:00|
| 5|2018-06-30 00:00:00|
+---+-------------------+
>>> df.printSchema()
root
|-- id: long (nullable = true)
|-- ts: timestamp (nullable = true)
以下是与您类似的查询:
>>> df.filter(df['ts'] >= F.lit('2018-06-27 00:00:00')) \
... .filter(df['ts'] < F.lit('2018-06-29 00:00:00')).show()
+---+-------------------+
| id| ts|
+---+-------------------+
| 2|2018-06-27 00:00:00|
| 3|2018-06-28 00:00:00|
+---+-------------------+
您还可以使用逻辑运算符一次执行两个过滤器:
>>> df.filter((df['ts'] >= F.lit('2018-06-27 00:00:00'))
... & (df['ts'] < F.lit('2018-06-29 00:00:00'))).show()
+---+-------------------+
| id| ts|
+---+-------------------+
| 2|2018-06-27 00:00:00|
| 3|2018-06-28 00:00:00|
+---+-------------------+
最后,您实际上并不需要lit
函数。所以你可以只使用字符串:
>>> df.filter((df['ts'] >= '2018-06-27 00:00:00')
... & (df['ts'] < '2018-06-29 00:00:00')).show()
+---+-------------------+
| id| ts|
+---+-------------------+
| 2|2018-06-27 00:00:00|
| 3|2018-06-28 00:00:00|
+---+-------------------+
对于时区,您可以查看from_unixtime function的pyspark文档。 我还粘贴了以下示例,以方便参考:
>>> spark.conf.set("spark.sql.session.timeZone", "America/Los_Angeles")
>>> time_df = spark.createDataFrame([(1428476400,)], ['unix_time'])
>>> time_df.select(from_unixtime('unix_time').alias('ts')).collect()
[Row(ts='2015-04-08 00:00:00')]
>>> spark.conf.unset("spark.sql.session.timeZone")