过去我曾问过有关python pandas库的问题:pandas forward fill Time Stamp columns with specific value (1 second)
但是现在我将在pyspark中进行大量数据处理,因此会在pyspark中寻求另一种解决方案:
我有一个Spark DataFrame:
df = spark.createDataFrame([Row(a=1, b='2018-09-26 04:38:32.544', c='11', d='foo'),
Row(a=2, b='', c='22', d='bar'),
Row(a=3, b='', c='33', d='foo'),
Row(a=4, b='', c='44', d='bar'),
Row(a=5, b='2018-09-26 04:58:32.544', c='55', d='foo'),
Row(a=6, b='', c='66', d='bar')])
df.show(truncate=False)
|a |b |c |d |
+---+-----------------------+---+---+
|1 |2018-09-26 04:38:32.544|11 |foo|
|2 | |22 |bar|
|3 | |33 |foo|
|4 | |44 |bar|
|5 |2018-09-26 04:58:32.544|55 |foo|
|6 | |66 |bar|
+---+-----------------------+---+---+
我想从以前的可用版本中连续向每个NaT添加1秒:
|a |b |c |d |
+---+-----------------------+---+---+
|1 |2018-09-26 04:38:32.544|11 |foo|
|2 |2018-09-26 04:39:32.544|22 |bar|
|3 |2018-09-26 04:40:32.544|33 |foo|
|4 |2018-09-26 04:41:32.544|44 |bar|
|5 |2018-09-26 04:58:32.544|55 |foo|
|6 |2018-09-26 04:59:32.544|66 |bar|
+---+-----------------------+---+---+
我读到应该避免使用 udf ,因为它们会减慢数百万行的处理速度。感谢您的帮助!
答案 0 :(得分:1)
这可能不是最有效的解决方案,因为我们无法根据您的要求对数据帧进行分区。这意味着所有数据都被加载到单个分区并在那里排序。也许有人可以提出更好的解决方案。
下面的代码使用lag窗口函数,该函数返回上一行的值。我们仅在b
的当前值为null时应用此方法,否则我们将保留当前值。当当前值为空时,我们将上一行的值增加一秒钟。我们必须这样做几次,因为在b
列中包含null的行,并且在'b'列中也包含null的前一行将从lag返回空值(即lag不能连续应用,因此我们必须自己做)。
import pyspark.sql.functions as F
from pyspark.sql import Row
from pyspark.sql import Window
df = spark.createDataFrame([Row(a=1, b='2018-09-26 04:38:32.544', c='11', d='foo'),
Row(a=2, b='', c='22', d='bar'),
Row(a=3, b='', c='33', d='foo'),
Row(a=4, b='', c='44', d='bar'),
Row(a=5, b='2018-09-26 04:58:32.544', c='55', d='foo'),
Row(a=6, b='', c='66', d='bar')])
df = df.withColumn('a', df.a.cast("int"))
df = df.withColumn('b', df.b.cast("timestamp"))
w = Window.orderBy('a')
while df.filter(df.b.isNull()).count() != 0:
df = df.withColumn('b', F.when(df.b.isNotNull(), df.b).otherwise(F.lag('b').over(w) + F.expr('INTERVAL 1 SECONDS')))
df.show(truncate=False)
输出:
+---+-----------------------+---+---+
| a | b | c | d |
+---+-----------------------+---+---+
| 1 |2018-09-26 04:38:32.544|11 |foo|
| 2 |2018-09-26 04:38:33.544|22 |bar|
| 3 |2018-09-26 04:38:34.544|33 |foo|
| 4 |2018-09-26 04:38:35.544|44 |bar|
| 5 |2018-09-26 04:58:32.544|55 |foo|
| 6 |2018-09-26 04:58:33.544|66 |bar|
+---+-----------------------+---+---+