【问题标题】:Replace NaN with null when using CreateDataFrame with pandas data使用带有熊猫数据的 CreateDataFrame 时将 NaN 替换为 null
【发布时间】:2021-08-18 10:43:24
【问题描述】:

我正在读取 csv,将其转换为 Spark 数据帧,然后进行一些聚合。原始 csv 有缺失数据,通过 Pandas 读取时表示为NaN。转换为 PySpark 后,NaN 值将保留,而不是被 null 替换。这导致我的 .avg() 聚合具有 NaN 值。

df = pd.read_csv('data.csv', index_col = False)

spark_schema = StructType([
    StructField("id",StringType(),True),
    StructField("segment", StringType(), True),
    StructField("score",DoubleType(),True),
    StructField("sales", IntegerType(), True)
  ])

spark_df = spark.createDataFrame(data=df,schema=spark_schema).cache()

segment_avg = (
    spark_df
    .groupBy('segment')
    .agg(
        sf.avg('score').alias('score')
    )
)

+----------+------+
|segment   |score |
+----------+------+
|Gold      |NaN   |
|Platinum  |NaN   |
|Silver    |NaN   |
+----------+------+

我尝试像这样替换spark_df 中的所有NaN

spark_df = spark_df.replace(float('nan'), None)

但它出错了:

ValueError:如果 to_replace 不是 dict,则 value 应该是 float、int、long、string、list 或 tuple。得到

spark_df.select('score').show(10,False)

+-----+
|score|
+-----+
|75.0 |
|34.0 |
|NaN  |
|NaN  |
|NaN  |
|76.0 |
|65.0 |
|43.0 |
|78.0 |
|88.0 |
+-----+

如何将这些 Nan 值替换为 null,以便在聚合时忽略它们?

【问题讨论】:

    标签: pyspark apache-spark-sql


    【解决方案1】:

    使用isnan函数将列中的NaN替换为null

    from pyspark.sql.functions import isnan, col, when, lit
    
    spark_df = spark_df.withColumn('score', when(isnan(col('score')), lit(None)).otherwise(col('score')))
    

    要替换整个数据框中的所有 NaN,请使用 .replace

    spark_df = spark_df.replace(float('nan'), None)
    

    【讨论】:

    • 有没有办法针对数据框中的每个 NaN 而不是单个列?
    猜你喜欢
    • 2022-01-03
    • 2015-08-04
    • 2014-07-07
    • 2018-03-25
    • 1970-01-01
    • 2015-10-12
    • 2017-01-02
    • 2021-12-08
    • 2020-10-12
    相关资源
    最近更新 更多