删除缺少值的行,表示为'?'

时间:2017-04-01 13:32:52

标签: scala apache-spark missing-data

我有一个.csv文件,其中包含缺少值的行。这些值代替null,由字符?表示。

如果?无法工作(因为缺失的值不是df.na.drop()),如何删除包含至少一个值为null的列的行?

数据如下所示(我有35列 - 可以在任何列中找到缺失值)

+-------+--------+------+-------+
| col_1 | col_2  |  ... | col_35|
+-------+--------+------+-------+
| 0.75  |   ?    |  ... |   15  |
|   ?   | Helen  |  ... |   21  |
| -1.2  | George |  ... |    ?  |
|   ?   | Andrew |  ... |   129 |
| 0.12  | Maria  |  ... |   12  |   // Should not be deleted
+-------+--------+------+-------+

这是读取文件的代码。

val df = sparkSession.read
    .format("com.databricks.spark.csv")
    .option("header", "true")
    .option("mode", "DROPMALFORMED")
    .load("data.csv")
    .toDF()

2 个答案:

答案 0 :(得分:5)

如果?表示缺少值,则只需将阅读器配置为识别:

val df = spark.read
  .format("csv")
  .option("nullValue", "?")  // Use "?" as null character
  .option("header", "true")
  .option("mode", "DROPMALFORMED")
  .load("data.csv")
  .toDF()

并使用标准na.drop

df.na.drop

答案 1 :(得分:2)

您可以使用火花数据框中的UDF将?转换为null值。

以下示例代码:

import org.apache.spark.sql.functions.udf

val df = sc.parallelize(
  Seq(("a", "B", "c"), ("D", "e", "?"), ("G", "?", "I"))).toDF("x", "y", "z")
// Function returns the input itself or null if it is a '?'
def replace: (String => String) = { value => if (value == "?") null else value }
// We create a UDF of that function because we want to run this on the entire column
val replaceudf = udf(replace)
Apply the method to all columns of the data frame
df.select(df.columns.map(c => replaceudf(col(c)).alias(c)): _*)

df.show
/* Output
+---+----+----+
|  x|   y|   z|
+---+----+----+
|  a|   B|   c|
|  D|   e|null|
|  G|null|   I|
+---+----+----+
*/

现在,您可以对数据框应用所有NA操作。我希望这会有所帮助。