【问题标题】:pyspark replace all values in dataframe with another valuespyspark 用另一个值替换数据框中的所有值
【发布时间】:2020-02-14 22:30:37
【问题描述】:

我的 pyspark 数据框中有 500 列...有些是字符串类型,有些是 int 和一些 boolean(100 个布尔列)。 现在,所有布尔列都有两个不同的级别 - 是和否,我想将它们转换为 1/0

对于字符串,我有三个值——通过、失败和空。 如何用 0 替换那些空值? fillna(0) 仅适用于整数

 c1| c2 |    c3 |c4|c5..... |c500
yes| yes|passed |45....
No | Yes|failed |452....
Yes|No  |None   |32............

当我这样做时

df.replace(yes,1)

我收到以下错误:

ValueError: Mixed type replacements are not supported

【问题讨论】:

    标签: python pyspark pyspark-sql


    【解决方案1】:

    对于字符串,我有三个值——通过、失败和空。如何用 0 替换那些空值? fillna(0) 仅适用于整数

    首先,导入 whenlit

    from pyspark.sql.functions import when, lit
    

    假设你的 DataFrame 有这些列

    # Reconstructing my DataFrame based on your assumptions
    # cols are Columns in the DataFrame
    cols = ['name', 'age', 'col_with_string']
    
    # Similarly the values
    vals = [
         ('James', 18, 'passed'),
         ('Smith', 15, 'passed'),
         ('Albie', 32, 'failed'),
         ('Stacy', 33, None),
         ('Morgan', 11, None),
         ('Dwight', 12, None),
         ('Steve', 16, 'passed'), 
         ('Shroud', 22, 'passed'),
         ('Faze', 11,'failed'),
         ('Simple', 13, None)
    ]
    
    # This will create a DataFrame using 'cols' and 'vals'
    # spark is an object of SparkSession
    df = spark.createDataFrame(vals, cols)
    
    # We have the following DataFrame
    df.show()
    
    +------+---+---------------+
    |  name|age|col_with_string|
    +------+---+---------------+
    | James| 18|         passed|
    | Smith| 15|         passed|
    | Albie| 32|         failed|
    | Stacy| 33|           null|
    |Morgan| 11|           null|
    |Dwight| 12|           null|
    | Steve| 16|         passed|
    |Shroud| 22|         passed|
    |  Faze| 11|         failed|
    |Simple| 13|           null|
    +------+---+---------------+
    

    你可以使用:

    • withColumn() - 指定要使用的列。
    • isNull() - 一个过滤器,评估结果为 true iff 属性评估为 null
    • lit() - 为文字创建一列
    • when(), otherwise() - 用于检查列的条件

    我可以用 0 替换具有 null 的值

    df = df.withColumn('col_with_string', when(df.col_with_string.isNull(), 
    lit('0')).otherwise(df.col_with_string))
    
    # We have replaced nulls with a '0'
    df.show()
    
    +------+---+---------------+
    |  name|age|col_with_string|
    +------+---+---------------+
    | James| 18|         passed|
    | Smith| 15|         passed|
    | Albie| 32|         failed|
    | Stacy| 33|              0|
    |Morgan| 11|              0|
    |Dwight| 12|              0|
    | Steve| 16|         passed|
    |Shroud| 22|         passed|
    |  Faze| 11|         failed|
    |Simple| 13|              0|
    +------+---+---------------+
    

    您问题的第 1 部分:是/否布尔值 - 您提到,布尔值有 100 列。为此,我通常使用更新的值重建表或创建一个 UDF,返回 1 或 0 表示是或否。

    我正在向 DataFrame (df) 添加另外两列 can_vote 和 can_lotto

    df = df.withColumn("can_vote", col('Age') >= 18)
    df = df.withColumn("can_lotto", col('Age') > 16) 
    
    # Updated DataFrame will be
    df.show()
    
    +------+---+---------------+--------+---------+
    |  name|age|col_with_string|can_vote|can_lotto|
    +------+---+---------------+--------+---------+
    | James| 18|         passed|    true|     true|
    | Smith| 15|         passed|   false|    false|
    | Albie| 32|         failed|    true|     true|
    | Stacy| 33|              0|    true|     true|
    |Morgan| 11|              0|   false|    false|
    |Dwight| 12|              0|   false|    false|
    | Steve| 16|         passed|   false|    false|
    |Shroud| 22|         passed|    true|     true|
    |  Faze| 11|         failed|   false|    false|
    |Simple| 13|              0|   false|    false|
    +------+---+---------------+--------+---------+
    

    假设您有与 can_vote 和 can_lotto 相似的列(布尔值为是/否)

    您可以使用以下代码行来获取 DataFrame 中具有布尔类型的列

    col_with_bool = [item[0] for item in df.dtypes if item[1].startswith('boolean')]
    

    这会返回一个列表

    ['can_vote', 'can_lotto']
    

    您可以为此类列表中的每一列创建 UDF 并迭代,使用 1(是)或 0(否)点亮每一列。

    参考参考以下链接

    【讨论】:

      【解决方案2】:

      我尝试使用以下数据复制您的问题:

      df_test=pd.DataFrame([['yes','pass',1.2],['No','pass',34],['yes',None,0.4],[0,1,'No'],['No',1,True],['NO','YES',1]])
      

      那我就用:

      df_test.replace('yes',1)
      

      【讨论】:

      • 我没有收到任何错误,但没有收到输出。我正在使用 pyspark
      • 我认为您没有看到输出,因为没有 collect()show();最后尝试上面的任何一个,或者只做df2 = df_test.replace('yes', 1)然后df2.show()
      【解决方案3】:

      您应该尝试使用df.na.fill(),但要区分函数填充参数中的列。

      你会有类似的东西:

      df_test.na.fill({"value":"","c4":0}).show()
      

      【讨论】:

        【解决方案4】:

        您可以在 Spark 中使用 Koalas 进行类似 Pandas 的操作。但是,您需要尊重给定数据框的架构。使用考拉,您可以执行以下操作:

        df = df.replace('yes','1')
        

        将所有字符串替换为数字后,您可以将该列转换为 int。如果您想用 NaN 替换某些空值,我建议您执行以下操作:

        df = df .replace(['?'], None) 
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-07-07
          • 2016-08-27
          • 2019-06-30
          • 1970-01-01
          • 1970-01-01
          • 2022-01-23
          • 2021-02-27
          相关资源
          最近更新 更多