Mèh*_*ida 2 apache-spark apache-spark-sql pyspark spark-dataframe pyspark-sql
我有一个用一些空值定义的数据框。一些列是完全空值。
>> df.show()
+---+---+---+----+
| A| B| C| D|
+---+---+---+----+
|1.0|4.0|7.0|null|
|2.0|5.0|7.0|null|
|3.0|6.0|5.0|null|
+---+---+---+----+
Run Code Online (Sandbox Code Playgroud)
就我而言,我想返回一个填充了空值的列名称列表。我的想法是检测常量列(因为整个列包含相同的空值)。
我是这样做的:
nullCoulumns = [c for c, const in df.select([(min(c) == max(c)).alias(c) for c in df.columns]).first().asDict().items() if const]
Run Code Online (Sandbox Code Playgroud)
但这并不将空列视为常量,它仅适用于值。那我该怎么做呢?
小智 5
将条件扩展为
from pyspark.sql.functions import min, max
((min(c).isNull() & max(c).isNull()) | (min(c) == max(c))).alias(c)
Run Code Online (Sandbox Code Playgroud)
或使用eqNullSafe(PySpark 2.3):
(min(c).eqNullSafe(max(c))).alias(c)
Run Code Online (Sandbox Code Playgroud)
一种方法是隐式执行此操作:选择每一列,计算其 NULL 值,然后将其与总数或行数进行比较。根据您的数据,这将是:
spark.version
# u'2.2.0'
from pyspark.sql.functions import col
nullColumns = []
numRows = df.count()
for k in df.columns:
nullRows = df.where(col(k).isNull()).count()
if nullRows == numRows: # i.e. if ALL values are NULL
nullColumns.append(k)
nullColumns
# ['D']
Run Code Online (Sandbox Code Playgroud)
但还有一种更简单的方法:事实证明countDistinct,当该函数应用于包含所有 NULL 值的列时,会返回零 (0):
from pyspark.sql.functions import countDistinct
df.agg(countDistinct(df.D).alias('distinct')).collect()
# [Row(distinct=0)]
Run Code Online (Sandbox Code Playgroud)
所以for现在的循环可以是:
nullColumns = []
for k in df.columns:
if df.agg(countDistinct(df[k])).collect()[0][0] == 0:
nullColumns.append(k)
nullColumns
# ['D']
Run Code Online (Sandbox Code Playgroud)
更新collect(评论后):在第二个解决方案中似乎可以避免;由于df.agg返回一个只有一行的数据帧,因此替换collect为take(1)将安全地完成这项工作:
nullColumns = []
for k in df.columns:
if df.agg(countDistinct(df[k])).take(1)[0][0] == 0:
nullColumns.append(k)
nullColumns
# ['D']
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12294 次 |
| 最近记录: |