在 Pyspark 中使用 dropna 清理数据

Posted

技术标签:

【中文标题】在 Pyspark 中使用 dropna 清理数据【英文标题】:cleaning data with dropna in Pyspark 【发布时间】:2017-09-03 21:41:10 【问题描述】:

我对 Pyspark 还是比较陌生。我使用版本 2.1.0。 我正在尝试清理更大数据集上的一些数据。 我已经成功使用了多种技术,例如“dropDuplicates”以及子集和 sql 函数(distinct、count 等)。

然后我遇到了 dropna,我认为这可能会简化问题。但我不明白为什么使用 dropna 后第 3 行和第 6 行仍然存在。 例如:

df = spark.createDataFrame([(1, 'Peter', 1.79, 28,'M', 'Tiler'),
                            (2, 'Fritz', 1.78, 45,'M', None),
                            (3, 'Florence', 1.75, None, None, None),
                            (4, 'Nicola',1.6, 33,'F', 'Dancer'),
                            (5, 'Gregory', 1.8, 54,'M', 'Teacher'),
                            (6, 'Steven', 1.82, None, 'M', None),
                            (7, 'Dagmar', 1.7, 42,'F', 'Nurse'),]
                           , ['id', 'Name', 'Height', 'Age', 'Gender', 'Occupation'])

df.show()

df.dropna(thresh=2)

df.show()

输出:

+---+--------+------+----+------+----------+
| id|    Name|Height| Age|Gender|Occupation|
+---+--------+------+----+------+----------+
|  1|   Peter|  1.79|  28|     M|     Tiler|
|  2|   Fritz|  1.78|  45|     M|      null|
|  3|Florence|  1.75|null|  null|      null|
|  4|  Nicola|   1.6|  33|     F|    Dancer|
|  5| Gregory|   1.8|  54|     M|   Teacher|
|  6|  Steven|  1.82|null|     M|      null|
|  7|  Dagmar|   1.7|  42|     F|     Nurse|
+---+--------+------+----+------+----------+

+---+--------+------+----+------+----------+
| id|    Name|Height| Age|Gender|Occupation|
+---+--------+------+----+------+----------+
|  1|   Peter|  1.79|  28|     M|     Tiler|
|  2|   Fritz|  1.78|  45|     M|      null|
|  3|Florence|  1.75|null|  null|      null|
|  4|  Nicola|   1.6|  33|     F|    Dancer|
|  5| Gregory|   1.8|  54|     M|   Teacher|
|  6|  Steven|  1.82|null|     M|      null|
|  7|  Dagmar|   1.7|  42|     F|     Nurse|
+---+--------+------+----+------+----------+

有人可以建议为什么不删除这些行吗?

pyspark examples 根据我假设的用法显示正确的计数。

# threshold
        self.assertEqual(self.spark.createDataFrame(
            [(u'Alice', None, 80.1)], schema).dropna(thresh=2).count(),
            1)
        self.assertEqual(self.spark.createDataFrame(
            [(u'Alice', None, None)], schema).dropna(thresh=2).count(),
            0)

【问题讨论】:

【参考方案1】:

首先,na 创建了一个新数据框,因此将其分配给新的 df 名称,第二,指定子集以检查哪些列要检查空值

df2 = df.dropna(thresh=2,subset=('Age','Gender','Occupation'))

df2.show()

输出:

+---+-------+------+---+------+----------+
| id|   Name|Height|Age|Gender|Occupation|
+---+-------+------+---+------+----------+
|  1|  Peter|  1.79| 28|     M|     Tiler|
|  2|  Fritz|  1.78| 45|     M|      null|
|  4| Nicola|   1.6| 33|     F|    Dancer|
|  5|Gregory|   1.8| 54|     M|   Teacher|
|  7| Dagmar|   1.7| 42|     F|     Nurse|
+---+-------+------+---+------+----------+

编辑:顺便说一下,thresh=2 单独不起作用,因为 thresh 意味着删除具有小于 thresh 的行(在这种情况下为 2)非空值,但第 3 行具有 id、name 和 height 即总共 3 个非-nulls 和第 6 行有 4 个非空值,因此它们不满足 thresh=2 标准。你可以试试thresh=5

【讨论】:

有没有更闪亮的方法来使用 UDF 来利用 sparks 内部优化?【参考方案2】:

你可以试试这个:

df.dropna(how='any').show()

【讨论】:

【参考方案3】:
df.dropna(how='all', inplace=True)

df.show()

【讨论】:

以上是关于在 Pyspark 中使用 dropna 清理数据的主要内容,如果未能解决你的问题,请参考以下文章

使用较低的函数将pyspark数据框中单列中的值转换为文本清理中的小写[重复]

删除空列的快速方法 [PySpark]

Pyspark SQL:在数据透视表中保留只有空值的条目

在pyspark中旋转一行的值

在 Pyspark 中按顺序应用多个正则表达式进行文本清理的最快方法

pyspark dataframe api速览