【问题标题】:Remove letters from Integer Column PySpark从整数列 PySpark 中删除字母
【发布时间】:2021-06-07 11:31:18
【问题描述】:

我有一个非常大的表格,代表积分(>3000 万积分)。 它可以有两个或树列代表 x,y,z

不幸的是,其中一些列可以包含字符串('nan'、'nulo'、'vazio'等) 它们可以在文件之间更改,但在表中是不变的

我需要一种方法来删除这些字符串并将它们替换为空值或删除行

我所做的是在图片和下面的代码中,有更好的原因吗?更灵活?(此代码仅适用于 3d)

def import_file(self,file_path:str,sep:str=',',null_values:str=''):  
 
 #read table
 table =  self.spark.read.load(path=file_path, \
 format='csv', \
 sep=sep, \
 header=False).toDF('x','y','z')
 
 #change the letters to ''
 table.withColumn('x',regexp_replace('x','[a-z]',''))
 table.withColumn('y',regexp_replace('z','[a-z]',''))
 table.withColumn('z',regexp_replace('z','[a-z]',''))

 #replace '' for nulls or TODO:remove columns
 table.replace('',None)

 return table

【问题讨论】:

  • 字母本质上是指字符串,对吗?
  • 你应该发布代码而不是图像
  • @Vaebhav 是的,这里有点晚了,感谢您的更正

标签: python pyspark


【解决方案1】:

另一种方法是使用 UDF 来标记字符串,并且进一步基于您想要删除的列中的任何行组合,您可以轻松地做到这一点

import pyspark.sql.functions as F
import pandas as pd
import numpy as np

@F.udf(returnType=BooleanType())
def mark_strings(inp):

  #### Check if inp is string or not , assuming here you can have numeric rows as well which are to be returned as is

  if isinstance(inp,str) and not pd.isnull(inp):
    if inp.isalpha():
       return True
  
  return False


@F.udf(returnType=StringType())
def replace_strings(inp):

  #### Check if inp is string or not , assuming here you can have numeric rows as well which are to be returned as is

  if isinstance(inp,str) and not pd.isnull(inp):
    if inp.isalpha():
       return np.nan
  
  return inp

删除数据行

table = table.withColumn('x_str_bool',mark_strings(F.col('x')))
table = table.withColumn('y_str_bool',mark_strings(F.col('y')))
table = table.withColumn('z_str_bool',mark_strings(F.col('z')))

##### Assuming if you only want to remove string data rows based on a combination of x and y.

table_filter = table.filter((F.col('x_str_bool') == False) &
(F.col('y_str_bool') == False))

替换数据行

table = table.withColumn('x',replace_strings(F.col('x')))
table = table.withColumn('y',replace_strings(F.col('y')))
table = table.withColumn('z',replace_strings(F.col('z')))

【讨论】:

  • 我希望 UDF(尤其是用 Python 编写时)总是比像 regexp_replace 这样的内置 SQL 函数慢。
  • @werner - 我完全同意,regex_replace 更胜一筹。 ans 不是更多关于优化而不是使用 udf 的另一种方法
  • @werner 为什么?也许我错了,我真的是 hadoop 和 spark 的菜鸟,但是使用 map reduce 的 spark 为什么你可以假设 udf 更慢而 sql 函数?
  • @VvT 请查看this answer。我认为这可能会有所帮助
【解决方案2】:

您可以使用此处的答案来删除无法转换为整数的行。这样你就不需要使用 UDF。 how to check if a string column in pyspark dataframe is all numeric

应该是这样的:

table = table.filter(col(“x”).cast(“int”).isNotNull())

【讨论】:

    【解决方案3】:

    如果您的期望只是数字(假设我们在这里只讨论点的位置),那么您可以将整列转换为整数/双精度,不是数字的就是None

    def import_file(self,file_path:str,sep:str=',',null_values:str=''):  
     
      #read table
      #...
     
      for c in table.columns:
        table = table.withColumn(c, F.col(c).cast('integer')) # or double
    
      return table
    

    【讨论】:

      猜你喜欢
      • 2022-09-23
      • 2017-04-30
      • 1970-01-01
      • 1970-01-01
      • 2012-11-15
      • 1970-01-01
      • 1970-01-01
      • 2016-04-03
      相关资源
      最近更新 更多