【问题标题】:Groupby fill missing values in dataframe based on average of previous values available and next value availableGroupby 根据以前可用值和下一个可用值的平均值填充数据框中的缺失值
【发布时间】:2020-11-15 15:23:14
【问题描述】:

我的数据框有一些组,我想根据得分列的上一个可用和下一个可用平均值填充缺失值,即(上一个值+下一个值)/2。

我想按州、学校、班级、学科分组,然后填写值。

如果分数列中的第一个值不可用,则用下一个可用的值填充该值,或者 如果最后一个值不可用,则用以前可用的值填充该值 对于每个组,都需要遵循这一点。

这是数据插补复杂问题。我在网上搜索,发现熊猫有一些功能,即 pandas.core.groupby.DataFrameGroupBy.ffill 但不知道在这种情况下如何使用。

我正在考虑用 python、pyspark、SQL 解决!

我的数据框是这样的

【问题讨论】:

  • 德州新月学校的所有记录的数学分数应该是 46 吗?
  • 不,你错过了班级群!!
  • 你只想这样填写吗?分组后如何插值?
  • 如果我可以分组和插值,那将解决我的问题。我面临的问题是如何分组和填写信息@Pygirl

标签: python sql machine-learning pyspark missing-data


【解决方案1】:

也许这有帮助 -

加载测试数据

df2.show(false)
    df2.printSchema()
    /**
      * +-----+-----+
      * |class|score|
      * +-----+-----+
      * |A    |null |
      * |A    |46   |
      * |A    |null |
      * |A    |null |
      * |A    |35   |
      * |A    |null |
      * |A    |null |
      * |A    |null |
      * |A    |46   |
      * |A    |null |
      * |A    |null |
      * |B    |78   |
      * |B    |null |
      * |B    |null |
      * |B    |null |
      * |B    |null |
      * |B    |null |
      * |B    |56   |
      * |B    |null |
      * +-----+-----+
      *
      * root
      * |-- class: string (nullable = true)
      * |-- score: integer (nullable = true)
      */

从分数列输入 Null 值(检查 new_score 列)


    val w1 = Window.partitionBy("class").rowsBetween(Window.unboundedPreceding, Window.currentRow)
    val w2 = Window.partitionBy("class").rowsBetween(Window.currentRow, Window.unboundedFollowing)
    df2.withColumn("previous", last("score", ignoreNulls = true).over(w1))
      .withColumn("next", first("score", ignoreNulls = true).over(w2))
      .withColumn("new_score", (coalesce($"previous", $"next") + coalesce($"next", $"previous")) / 2)
      .drop("next", "previous")
      .show(false)

    /**
      * +-----+-----+---------+
      * |class|score|new_score|
      * +-----+-----+---------+
      * |A    |null |46.0     |
      * |A    |46   |46.0     |
      * |A    |null |40.5     |
      * |A    |null |40.5     |
      * |A    |35   |35.0     |
      * |A    |null |40.5     |
      * |A    |null |40.5     |
      * |A    |null |40.5     |
      * |A    |46   |46.0     |
      * |A    |null |46.0     |
      * |A    |null |46.0     |
      * |B    |78   |78.0     |
      * |B    |null |67.0     |
      * |B    |null |67.0     |
      * |B    |null |67.0     |
      * |B    |null |67.0     |
      * |B    |null |67.0     |
      * |B    |56   |56.0     |
      * |B    |null |56.0     |
      * +-----+-----+---------+
      */

【讨论】:

  • 获取每行的最后一个可用值作为先前忽略空值。同样获取下一个值,然后计算平均值previous + next/2
  • 谢谢,我没有在我的 pyspark 代码中使用 $,想确认这是 pyspark 还是 scala 代码?
  • 这是 scala,但可以在 pyspark 中以同样的方式实现,只需极少的更改。将 $".." 替换为 F.col(...)
  • df.withColumn("previous", last("score", ignoreNulls = true).over(w1)).withColumn("next", first("score", ignoreNulls = true)。 over(w2)).withColumn("new_score", (coalesce(F.col("previous"), F.col("next") + coalesce(F.col("next"), F.col("previous》) ")) / 2))).drop("next", "previous").show(false)
  • 我已经接受并投了赞成票。发现它很有用!但是我可能需要更改上面的代码才能达到预期的结果
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-30
  • 2021-10-25
  • 2020-05-30
  • 1970-01-01
  • 2020-04-13
  • 1970-01-01
相关资源
最近更新 更多