如何用pyspark数据框中的ID用另一行中的值替换空值?

时间:2019-05-07 17:49:18

标签: pyspark apache-spark-sql

我有这个数据框。

+------+-----------+---------------+--------+---------+------------------+----+------------------+------+-----+-----------+
|prodid|       snbr|              A|       B|        C|                 D|   E|                 F|     G|    H|          I|
+------+-----------+---------------+--------+---------+------------------+----+------------------+------+-----+-----------+
| 10510|          0|           null|    null|      750|              null|null|              null| 48.72| 3.15|Napa Valley|
| 10510|          1|     California|       1|     null|Cabernet Sauvignon| Red|Cabernet Sauvignon|  null| null|       null|
| 26619|          0|      Australia|       1|      750|Cabernet Sauvignon| Red|Cabernet Sauvignon| 2.695| 2.95|       null|
| 26619|          1|           null|    null|     null|            Shiraz|null|    Syrah / Shiraz|  null| null|       null|
+------+-----------+---------------+--------+---------+------------------+----+------------------+------+-----+-----------+

我想要这个数据框

+------+-----------+---------------+--------+---------+------------------+----+------------------+------+-----+-----------+
|prodid|       snbr|              A|       B|        C|                 D|   E|                 F|     G|    H|          I|
+------+-----------+---------------+--------+---------+------------------+----+------------------+------+-----+-----------+
| 10510|          0|     California|       1|      750|Cabernet Sauvignon| Red|Cabernet Sauvignon| 48.72| 3.15|Napa Valley|
| 10510|          1|     California|       1|      750|Cabernet Sauvignon| Red|Cabernet Sauvignon| 48.72| 3.15|Napa Valley|
| 26619|          0|      Australia|       1|      750|Cabernet Sauvignon| Red|Cabernet Sauvignon| 2.695| 2.95|       null|
| 26619|          1|      Australia|       1|      750|            Shiraz| Red|    Syrah / Shiraz| 2.695| 2.95|       null|
+------+-----------+---------------+--------+---------+------------------+----+------------------+------+-----+-----------+

我想以动态方式将无空行从一行复制到另一行。不使用特定的列名。使用prodid和snbr可以。

TBH Im迷路了。我想我可能已经重新考虑了我如何到达这里。抱歉,我没有任何代码。

1 个答案:

答案 0 :(得分:0)

这是解决方案,我只用了三个列A,B,F来解决diff情况,但这将适用于任何列数和行数。基本上找到最大值可得出每组“ prodid”中的非零值,并与“ prodid”和“ snbr”结合可得到所需的输出。

但是,如果在一个col的组中存在多个不同值并且还存在null值,则此方法不起作用。您可以根据自己的要求调整此解决方案。

import pyspark.sql.functions as F

df = spark.createDataFrame(
    [(10510, 0, 'California', None,None),(10510, 1, None,1,'Cabernet Sauvignon'),(10510, 2, None,None,None),
     (26619, 1, None,1,'Cabernet Sauvignon'),(26619, 2, 'Australia',None,'Cabernet Sauvignon'),(26619, 3, 'Australia',1,'Syrah / Shiraz')
    ], ["prodid", "snbr", "A","B","F"])

df_not_nulls = df.groupBy(
    F.col("prodid")
).agg(  *(F.max(c).alias(c)
      for c in df.columns if c!= 'prodid')
)

df.join(df_not_nulls,"prodid").select(*[F.coalesce(df[c],df_not_nulls[c]).alias(c) for c in df.columns]).show()

结果

+------+----+----------+---+------------------+
|prodid|snbr|         A|  B|                 F|
+------+----+----------+---+------------------+
| 10510|   0|California|  1|Cabernet Sauvignon|
| 10510|   1|California|  1|Cabernet Sauvignon|
| 10510|   2|California|  1|Cabernet Sauvignon|
| 26619|   1| Australia|  1|Cabernet Sauvignon|
| 26619|   2| Australia|  1|Cabernet Sauvignon|
| 26619|   3| Australia|  1|    Syrah / Shiraz|
+------+----+----------+---+------------------+