PySpark:是不是有可能根据非 Null 值创建动态数量的 DataFrame

Posted

技术标签:

【中文标题】PySpark:是不是有可能根据非 Null 值创建动态数量的 DataFrame【英文标题】:PySpark: Is there any possibility of creating dynamic number of DataFrame based on the Non Null valuesPySpark:是否有可能根据非 Null 值创建动态数量的 DataFrame 【发布时间】:2021-02-15 10:16:49 【问题描述】:

我有一个 PySpark 数据框:

name age username password
joe 34 Null Null
alice 21 Null Null
Null Null user1 pass1
Null Null user2 pass2

从上面的 DataFrame 中,我想通过某种方式找到 Null 值列来创建 2 个这样的 DataFrame:

name age
joe 34
alica 21
username password
user1 pass1
user2 pass2

有什么办法可以做到吗?

“源”目录下的示例 JSON 文件:


 "name": "joe",
 "age": 31



 "name": "alica",
 "age": 21



 "username": "user1",
 "password": "pass1"



 "username": "user2",
 "password": "pass2

代码:

conf = SparkConf().setMaster("local").setAppName("Test")
spark = SparkSession \
        .builder \
        .config(conf=conf) \
        .getOrCreate()

json_data = spark.read.json("source") 

【问题讨论】:

问题陈述是,单个目录位置有多个 JSON 文件,其架构无法预测。因此,想找到一种方法来创建单独的 DataFrame,以便可以将其保存到各自的位置。 您能否添加一个文件示例 (JSON) 示例以及您目前拥有的代码?这可能有助于回答您的问题,因为到目前为止,我不清楚您希望在哪些列上空组合来区分创建新数据框的决定。 @AlexOrtner,我已经指定了 JSON 和代码 sn-p(编辑帖子),我想完成上面指定的用例 【参考方案1】:

如果您始终拥有相同的固定数量的列,我将涵盖所有情况

import pyspark.sql.functions as f


df2=df.where(f.col("name").isNotNull() & f.col("age").isNotNull() & f.col("username").isNotNull() & f.col("password").isNull())

df3=df.where(f.col("name").isNotNull() & f.col("age").isNotNull() & f.col("username").isNull() & f.col("password").isNull())

df3=df.where(f.col("name").isNotNull() & f.col("age").isNull() & f.col("username").isNull() & f.col("password").isNull())

df4=df.where(f.col("name").isNull() & f.col("age").isNotNull() & f.col("username").isNotNull() & f.col("password").isNotNull())

df5=df.where(f.col("name").isNull() & f.col("age").isNull() & f.col("username").isNotNull() & f.col("password").isNotNull())

... and so on

【讨论】:

是的,这是可行的,但是如果模式(列)未知,是否有可能创建这样的 DataFrame? 您可以使用 inferschema=True。例如对于 csv 文件 spark.read.format("csv").options(header="true", inferschema=True,sep=";").load("test.csv") header=True:使用列名称或 JSON 属性 inferschema=True 告诉 Spark 尝试自动查找数据类型。如果只有 Null,则不起作用【参考方案2】:

您可以简单地使用select + dropna()

df1 = df.select("name", "age").dropna()

df1.show()
#+-----+---+
#| name|age|
#+-----+---+
#|  joe| 34|
#|alice| 21|
#+-----+---+

df2 = df.select("username", "password").dropna()

df2.show()
#+--------+--------+
#|username|password|
#+--------+--------+
#|   user1|   pass1|
#|   user2|   pass2|
#+--------+--------+

【讨论】:

以上是关于PySpark:是不是有可能根据非 Null 值创建动态数量的 DataFrame的主要内容,如果未能解决你的问题,请参考以下文章

Pyspark 计数非空值之间的空值

如何使用类体内的键/值创建一次映射(不是每次调用类中的函数)

Pyspark根据其他列值添加新列

Pyspark:如果具有特定 id 的任何行包含 null,如何根据另一列派生新列的值?

Pyspark:根据每行空值的数量过滤数据框

PySpark:数据框:Numeric + Null 列值导致 NULL 而不是数值