如何检查pyspark数据框中的字符串列是否全部为数字
How to check if a string column in pyspark dataframe is all numeric
我有一个 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()
returns True
or False
如果string
只包含数字或不包含.
预期数据帧:
+-----+-------+
| ID| Value |
+-----+-------+
|25q36| False |
|75647| True |
|13864| True |
|8758K| False |
|07645| True |
+-----+-------+
我想避免创建 UDF
。
一个简单的演员就可以完成这项工作:
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|
+-----+------+
如果需要,您还可以为此目的构建自定义 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)))
试试这个,是Scala语言
spark.udf.register("IsNumeric", (inpColumn: Int) => BigInt(inpColumn).isInstanceOf[BigInt])
spark.sql(s""" select "ABCD", IsNumeric(1234) as IsNumeric_1 """).show(false)
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"))
我同意@steven 的回答,但有一点修改,因为我希望过滤掉整个 table。 PFB
df2.filter(F.col("id").cast("int").isNotNull()).show()
也不需要创建名为 Values
的新列
与上述类似的替代解决方案是 -
display(df2.filter(f"CAST({'id'} as INT) IS NOT NULL")
搜索非数字行的最清晰的方法是这样的:
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()
使用正则表达式过滤
事实上,我很喜欢 Steven 提供的创造性解决方案,但对于这种情况,我有更简单的建议:
df.filter(~df.ID.rlike('\D+')).show()
首先,您 select 包含带 rlike('\D+')
的非数字字符的每一行,然后排除过滤器开头带 ~
的那些行。
我有一个 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()
returns True
or False
如果string
只包含数字或不包含.
预期数据帧:
+-----+-------+
| ID| Value |
+-----+-------+
|25q36| False |
|75647| True |
|13864| True |
|8758K| False |
|07645| True |
+-----+-------+
我想避免创建 UDF
。
一个简单的演员就可以完成这项工作:
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|
+-----+------+
如果需要,您还可以为此目的构建自定义 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)))
试试这个,是Scala语言
spark.udf.register("IsNumeric", (inpColumn: Int) => BigInt(inpColumn).isInstanceOf[BigInt])
spark.sql(s""" select "ABCD", IsNumeric(1234) as IsNumeric_1 """).show(false)
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"))
我同意@steven 的回答,但有一点修改,因为我希望过滤掉整个 table。 PFB
df2.filter(F.col("id").cast("int").isNotNull()).show()
也不需要创建名为 Values
的新列与上述类似的替代解决方案是 -
display(df2.filter(f"CAST({'id'} as INT) IS NOT NULL")
搜索非数字行的最清晰的方法是这样的:
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()
使用正则表达式过滤
事实上,我很喜欢 Steven 提供的创造性解决方案,但对于这种情况,我有更简单的建议:
df.filter(~df.ID.rlike('\D+')).show()
首先,您 select 包含带 rlike('\D+')
的非数字字符的每一行,然后排除过滤器开头带 ~
的那些行。