【问题标题】:Pyspark increase all dataframe values by 1Pyspark 将所有数据帧值增加 1
【发布时间】:2019-09-06 05:32:43
【问题描述】:

我正在尝试将数据框中的所有值都增加 1,但 ID 列除外。

例子:

结果:

这是我目前所拥有的,但是当我有很多列要做(例如 50 个)时,它会变得有点长。

df_add = df.select(
  'Id',
  (df['col_a'] + 1).alias('col_a'),
  ..
  ..
)

有没有更 Pythonic 的方式来实现相同的结果?

【问题讨论】:

    标签: python python-3.x pyspark apache-spark-sql


    【解决方案1】:

    编辑(基于@Daniel 评论): 可以直接使用lit函数

    from pyspark.sql.functions import col, lit
    
    for column in plus_one_cols:
        df = df.withColumn(column, col(column) + lit(1))
    

    以前的答案:

    向列添加“1”是一种列操作,更适合pandas_udf

    from pyspark.sql.functions import col, pandas_udf, PandasUDFType
    
    @pandas_udf('double', PandasUDFType.SCALAR)
    def plus_one(v):
        return v + 1
    
    plus_one_cols = [x for x in df.columns if x != "Id"]
    
    for column in plus_one_cols:
        df = df.withColumn(column, plus_one(col(column)))
    

    这将比逐行操作快得多。也可以参考Introducing Pandas UDF for PySpark - Databricks

    【讨论】:

    • 哦,哇,我完全忘记了将它与 withColumn 函数一起使用。对我来说真的是一个菜鸟错误。谢谢!
    • 这种方法不是一个好的解决方案。在链接文章之后引用: > 计算 v + 1 是一个简单的示例,用于演示逐行 UDF 和标量 Pandas UDF 之间的差异。请注意,在这种情况下,内置的列运算符可以执行得更快。使用lit 的其他答案将具有更好的性能(并且更简单)
    • @Daniel 我已经更新了我的答案。我知道用lit 添加会更好。现在它是一个完整的答案,所以你也可以投票:P
    【解决方案2】:

    如果有很多列,可以使用下面的单行,

    from pyspark.sql.functions import lit,col
    
    df.select('Id', *[(col(i) + lit(1)) for i in df.columns if i != 'Id']).toDF(*df.columns).show()
    

    输出:

    +---+-----+-----+-----+
    | Id|col_a|col_b|col_c|
    +---+-----+-----+-----+
    |  1|    4|   21|    6|
    |  5|    6|    1|    1|
    |  6|   10|    2|    1|
    +---+-----+-----+-----+
    

    【讨论】:

      【解决方案3】:

      您可以使用withColumn 方法,然后按如下方式遍历列:

      df_add = df
      
      for column in ["col_a", "col_b", "col_c"]:
          df_add = df_add.withColumn(column, expr(f"{column} +1").cast("integer"))
      
      

      【讨论】:

        【解决方案4】:

        使用pyspark.sql.functions.lit 向列添加值 例如:

        from pyspark.sql import functions as psf
        df = spark.sql("""select 1 as test""")
        df.show()
        
        # +----+
        # |test|
        # +----+
        # |   1|
        # +----+
        
        
        
        df_add = df.select(
          'test',
          (df['test'] + psf.lit(1)).alias('col_a'),
        )
        df_add.show()
        
        
        # +----+-----+
        # |test|col_a|
        # +----+-----+
        # |   1|    2|
        # +----+-----+
        
        ###
        # If you want to do it for all columns then:
        ###
        list_of_columns = ["col1", "col2", ...]
        
        df_add = df.select(
          [(df[col] + psf.lit(1)).alias(col) for col in list_of_columns]
        )
        df_add.show()
        
        
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-07-25
          相关资源
          最近更新 更多