【问题标题】:How to check if a string column in pyspark dataframe is all numeric如何检查pyspark数据框中的字符串列是否都是数字
【发布时间】:2019-05-13 14:29:22
【问题描述】:

我有一个 PySpark Dataframe,其中有一列 strings。如何检查其中的哪些行是数字。我在 PySpark 的 official documentation 中找不到任何函数。

values = [('25q36',),('75647',),('13864',),('8758K',),('07645',)]
df = sqlContext.createDataFrame(values,['ID',])
df.show()
+-----+
|   ID|
+-----+
|25q36|
|75647|
|13864|
|8758K|
|07645|
+-----+

在 Python 中,有一个函数 .isDigit() 返回 TrueFalse,如果 string 仅包含数字。

预期的数据帧:

+-----+-------+
|   ID| Value |
+-----+-------+
|25q36| False |
|75647| True  |
|13864| True  |
|8758K| False |
|07645| True  |
+-----+-------+

我想避免创建UDF

【问题讨论】:

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


    【解决方案1】:

    一个简单的演员就可以完成这项工作:

    from pyspark.sql import functions as F
    
    my_df.select(
      "ID",
      F.col("ID").cast("int").isNotNull().alias("Value ")
    ).show()
    
    +-----+------+
    |   ID|Value |
    +-----+------+
    |25q36| false|
    |75647|  true|
    |13864|  true|
    |8758K| false|
    |07645|  true|
    +-----+------+
    

    【讨论】:

    • 谢谢史蒂文。这绝对有效。我认为这也可能是一些内置功能。如果我没有找到一个,我会点击这个作为答案。
    • 注意!最好使用long而不是int,因为整数范围是-2,147,483,647到+2,147,483,647。
    【解决方案2】:

    使用正则表达式过滤

    确实,我很喜欢 Steven 提供的创造性解决方案,但对于这种情况,我的建议要简单得多:

    df.filter(~df.ID.rlike('\D+')).show()
    

    首先,您选择包含rlike('\D+') 的非数字字符的每一行,然后在过滤器的开头排除那些带有~ 的行。

    【讨论】:

      【解决方案3】:

      我同意@steven 的回答,但有一点修改,因为我希望过滤掉整个表格。光纤通道

      df2.filter(F.col("id").cast("int").isNotNull()).show()
      

      此外,无需创建名为 Values

      的新列

      与上面类似的替代解决方案是-

      display(df2.filter(f"CAST({'id'} as INT) IS NOT NULL")
      

      【讨论】:

        【解决方案4】:

        搜索非数字行的最清晰方法是这样的:

        from pyspark.sql import functions as F
        
        df.select("col_a",F.regexp_replace(col("col_a"), "[^0-9]", "").alias("numeric"))\
            .filter(col("col_a")!=col("numeric"))\
            .distinct()\
            .show()
        

        【讨论】:

          【解决方案5】:

          如果您愿意,您还可以为此目的构建自定义udf

          from pyspark.sql.types import BooleanType
          from pyspark.sql import functions as F
          
          def is_digit(val):
              if val:
                  return val.isdigit()
              else:
                  return False
          
          is_digit_udf = udf(is_digit, BooleanType())
          
          df = df.withColumn('Value', F.when(is_digit_udf(F.col('ID')), F.lit(True)).otherwise(F.lit(False)))
          

          【讨论】:

            【解决方案6】:
            df=spark.read.option("header", "true").csv("source_table.csv")
            df=df.withColumn("is_valid",lit("true"))
            df.withColumn("is_valid",when(col("age").cast("int").isNotNull(),col("is_valid")).otherwise("false")).show()  # this will work 
            #if you want to use rlike this will work
            pattern="^[0-9]*$"
            source_df=df.withColumn("is_valid",
                           when(col("age").rlike(pattern), col("is_valid")).otherwise("false"))
            

            【讨论】:

            • 非常好,因为您避免使用 udf 函数..
            【解决方案7】:

            试试这个,是Scala语言

            spark.udf.register("IsNumeric", (inpColumn: Int) => BigInt(inpColumn).isInstanceOf[BigInt])
            spark.sql(s""" select "ABCD", IsNumeric(1234) as IsNumeric_1  """).show(false)
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-04-09
              • 1970-01-01
              • 1970-01-01
              • 2014-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-09-05
              相关资源
              最近更新 更多