【问题标题】:Pyspark : How to lead from specific column value in DataframePyspark:如何从 Dataframe 中的特定列值引导
【发布时间】:2020-08-07 09:57:06
【问题描述】:

数据框已经按日期排序,

col1 ==1 值是唯一的,

只有 0 有重复。

我有一个看起来像这样的数据框,称之为 df

+--------+----+----+
    date |col1|col2|
+--------+----+----+
2020-08-01| 5|  -1|
2020-08-02| 4|  -1|
2020-08-03| 3|   3|
2020-08-04| 2|   2|
2020-08-05| 1|   4|
2020-08-06| 0|   1|
2020-08-07| 0|   2|
2020-08-08| 0|   3|
2020-08-09| 0|  -1|
+--------+----+----+

条件是当 col1 == 1 时,我们从 col2 ==4 开始向后添加,(例如 4,5,6,7,8,...) 而后 col2 == 4 一路返回 0(例如 4,0,0,0,0...)

所以,我的结果 df 看起来像这样。

    +--------+----+----+----+
        date |col1|col2|want
    +--------+----+----+----+
    2020-08-01| 5|  -1|  8 |
    2020-08-02| 4|  -1|  7 |
    2020-08-03| 3|   3|  6 |
    2020-08-04| 2|   2|  5 |
    2020-08-05| 1|   4|  4 |
    2020-08-06| 0|   1|  0 |
    2020-08-07| 0|   2|  0 |
    2020-08-08| 0|   3|  0 |
    2020-08-09| 0|  -1|  0 |
   +---------+----+----+----+  

增强: 我想在 col1 == 1 行时添加额外的条件 col2 == -1,并且 -1 连续,然后我想计算连续的 -1,然后添加下一个 col2 == ?价值。所以这里有一个例子来清除。

    +--------+----+----+----+
        date |col1|col2|want
    +--------+----+----+----+
    2020-08-01| 5|  -1|  11|
    2020-08-02| 4|  -1|  10|
    2020-08-03| 3|   3|  9 |
    2020-08-04| 2|   2|  8 |
    2020-08-05| 1|  -1|  7 |
    2020-08-06| 0|  -1|  0 |
    2020-08-07| 0|  -1|  0 |
    2020-08-08| 0|   4|  0 |
    2020-08-09| 0|  -1|  0 |
   +---------+----+----+----+   

所以,我们看到 3 个连续的 -1,(我们只关心第一个连续的 -1)并且在连续之后我们有 4 个,那么我们将在 col1 = 处有 4+ 3 =7 =1 行。有可能吗?

【问题讨论】:

  • 任何帮助或如何开始这种方法将不胜感激!
  • 如果col1 有多个1 值会怎样?我已经可以看到 0 的重复项,其他值是否也存在重复项?在这种情况下,正确的排序是什么?
  • col1 中的值 1 将是唯一的。通过 1 后它将为 0。在这种情况下,唯一的重复项是 0。
  • 在排序方面,我们无法对其进行排序,不幸的是它们取决于我未包含在此数据框中的日期..
  • 你能用所有相关信息更新问题吗?使用排序和排名可以 100% 解决上述问题,但如果无法使用排序,也许还有其他方法可以提供帮助

标签: python apache-spark pyspark apache-spark-sql


【解决方案1】:

这是我的尝试:

from pyspark.sql.functions import sum, when, col, rank, desc
from pyspark.sql import Window

w1 = Window.orderBy(desc('date'))
w2 = Window.partitionBy('case').orderBy(desc('date'))

df.withColumn('case', sum(when(col('col1') == 1, col('col2')).otherwise(0)).over(w1)) \
  .withColumn('rank', when(col('case') != 0, rank().over(w2) - 1).otherwise(0)) \
  .withColumn('want', col('case') + col('rank')) \
  .orderBy('date') \
  .show(10, False)

+----------+----+----+----+----+----+
|date      |col1|col2|case|rank|want|
+----------+----+----+----+----+----+
|2020-08-01|5   |-1  |4   |4   |8   |
|2020-08-02|4   |-1  |4   |3   |7   |
|2020-08-03|3   |3   |4   |2   |6   |
|2020-08-04|2   |2   |4   |1   |5   |
|2020-08-05|1   |4   |4   |0   |4   |
|2020-08-06|0   |1   |0   |0   |0   |
|2020-08-07|0   |2   |0   |0   |0   |
|2020-08-08|0   |3   |0   |0   |0   |
|2020-08-09|0   |-1  |0   |0   |0   |
+----------+----+----+----+----+----+

【讨论】:

  • 谢谢您,先生,您能检查一下我所做的增强吗?有可能解决吗?
  • w2 是什么?
  • 知道它是 w2 =Window.partitionBy('case').orderBy('col1')
猜你喜欢
  • 2022-01-06
  • 2023-01-13
  • 1970-01-01
  • 2021-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-19
  • 1970-01-01
相关资源
最近更新 更多