PySpark-DataFrame条件筛选

本文介绍了PySparkDataFrame中的条件筛选方法,包括使用.where(),.filter()进行条件过滤,利用.isin()进行包含过滤,以及如何用funcs.when()按条件给数据分等级。示例展示了各种操作的语法和实际应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文是对PySpark的DataFrame中进行条件筛选操作的一个回顾总结。  

目录

示例 DataFrame 

.where 条件筛选 

.filter 过滤

.isin 过滤

funcs.when()

示例 DataFrame 

# 创建一个SparkDataFrame
rdd = sc.parallelize([("Sam", 28, 88.52, "M"),
                      ("Flora", 28, 90.55, "F"),
                      ("Run", 25, 89.55, "F"),
                      ("Peter", None, 100.0, "F"),
                      ("Mei", 23, 70.4, "F")])
test_exp_data = rdd.toDF(["name", "age", "score", "sex"])
test_exp_data.show()
+-----+----+-----+---+
| name| age|score|sex|
+-----+----+-----+---+
|  Sam|  28|88.52|  M|
|Flora|  28|90.55|  F|
|  Run|  25|89.55|  F|
|Peter|null|100.0|  F|
|  Mei|  23| 70.4|  F|
+-----+----+-----+---+

.where 条件筛选 

方式1 用df['col']去比较条件,本质上是对布尔表达式的选择。 # 多个条件中的每个条件注意用()括起来,链接注意用& 而不是and 

test_exp_data.where((test_exp_data['score'] == 100) | (test_exp_data['name']== 'Run')).show()

输出: 

+-----+----+-----+---+
| name| age|score|sex|
+-----+----+-----+---+
|  Run|  25|89.55|  F|
|Peter|null|100.0|  F|
+-----+----+-----+---+

方式2 :where(conditionExpr: String):SQL语言中where关键字后的条件
传入筛选条件表达式,可以用andor。得到DataFrame类型的返回结果,
示例:

test_exp_data.where("score = 100 or name = 'Run'").show()

输出: 

同上面方式1 一模一样

.filter 过滤

.filter过滤数据,其实作用和where一样。方式1 用df['col']去比较条件,本质上是对布尔表达式的选择。# 多个条件中的每个条件注意用()括起来,链接注意用& 而不是and 

test_exp_data.filter(test_exp_data['age']>24).show()
test_exp_data.filter((test_exp_data['age']>24) & (test_exp_data['score']>90)).show() # 多个条件中的每个条件注意用()括起来,链接注意用& 而不是and 

输出: 

+-----+---+-----+---+
| name|age|score|sex|
+-----+---+-----+---+
|  Sam| 28|88.52|  M|
|Flora| 28|90.55|  F|
|  Run| 25|89.55|  F|
+-----+---+-----+---+
+-----+---+-----+---+
| name|age|score|sex|
+-----+---+-----+---+
|Flora| 28|90.55|  F|
+-----+---+-----+---+
 
# 注意filter里面本质上是筛选bool表达式,多个条件时不能用and,如果用了会报错如” test_exp_data.filter((test_exp_data['age']>24) and (test_exp_data['score']>90)).show()“ 

报错: 提示 Cannot convert column into bool: please use '&' for 'and', '|' for 'or', '~' for 'not' when building DataFrame boolean expressions.

方式2 : 里面嵌套sql 表达式的字段

test_exp_data.filter("age>24").show()
test_exp_data.filter("age>24 and score >90").show()

输出结果同上面方式1一模一样。 

对null数据进行过滤:筛选出某个字段为null的行(定义时为None,转换为dataframe可能就变成了null)。

两种方式

# 创建一个SparkDataFrame
rdd = sc.parallelize([("Sam", 28, 88.52, "M"),
                      ("Flora", 28, 90.55, "F"),
                      ("Run", 25, 89.55, "F"),
                      ("Peter", None, 100.0, "F"),
                      ("Mei", 23, 70.4, "F")])
test_exp_data = rdd.toDF(["name", "age", "score", "sex"])
test_exp_data.show()
# 方式1 
from pyspark.sql import functions as funcs
test_exp_data.filter(funcs.isnull("age")).show()
# 方式2 
test_exp_data.filter('age is null').show()

均输出: 

+-----+----+-----+---+
| name| age|score|sex|
+-----+----+-----+---+
|Peter|null|100.0|  F|
+-----+----+-----+---+

如果想保留不为null 的即为下面,注意方式1中 非需要用~ 而不是别的。这里本质上也是bool表达式

# 方式1 
from pyspark.sql import functions as funcs
test_exp_data.filter(~funcs.isnull("age")).show() #注意非需要用~ 而不是别的。这里本质上也是bool表达式
#方式2 
test_exp_data.filter("age is not null").show() # 非空的

结果均为: 

+-----+---+-----+---+
| name|age|score|sex|
+-----+---+-----+---+
|  Sam| 28|88.52|  M|
|Flora| 28|90.55|  F|
|  Run| 25|89.55|  F|
|  Mei| 23| 70.4|  F|
+-----+---+-----+---+

.isin 过滤

基于包含另一个数据框的列的内容过滤数据

test_exp_data[test_exp_data.name.isin('Sam','Run')].show()
输出: 

+----+---+-----+---+
|name|age|score|sex|
+----+---+-----+---+
| Sam| 28|88.52|  M|
| Run| 25|89.55|  F|
+----+---+-----+---+

也可以是 

test_exp_data[test_exp_data.name.isin(df2.column2)].show() 的形式; 筛选出test_exp_data中的name取值在df2中字段2的取值中出现过的 test_exp_data的各行数据,返回是一个DataFrame; 

其他实践: 

有两个数据集,从data_1中抽取出data_2中的相同的元素

可行的方式:
df_ori_part = df_ori[df_ori['user_pin'].isin(list(df_1['user_pin']))]
df_ori_part = df_ori.filter(df_ori['user_pin'].isin(list(df_1['user_pin'])) == True )

不可行:
df_ori_part = df_ori.filter(~df_ori['user_pin'].isin(list(df_1['user_pin'])) )

此处参考: PySpark︱DataFrame操作指南:增/删/改/查/合并/统计与数据处理_悟乙己的博客-优快云博客

funcs.when()

按条件筛选 when(condition, value1).otherwise(value2)联合使用:那么:当满足条件condition的指赋值为values1,不满足条件的则赋值为values2.
otherwise表示,不满足条件的情况下,应该赋值为啥。

示例:多个when串联,对不同成绩分等级

test_exp_data.select('score',funcs.when(test_exp_data.score>90,'A').when(test_exp_data.score>80,'B').otherwise('C').alias('score_level')).show()

输出: 

+-----+-----------+
|score|score_level|
+-----+-----------+
|88.52|          B|
|90.55|          A|
|89.55|          B|
|100.0|          A|
| 70.4|          C|
+-----+-----------+
<think>好的,我现在需要帮助用户了解如何使用PySpark创建和操作DataFrame。首先,我得回忆一下PySpark的基本知识。用户可能已经知道PySpark是Python的Spark接口,但可能需要从基础开始讲解。 根据用户的问题,他们想了解如何创建和操作DataFrame。根据引用中的信息,比如引用3提到了从CSV文件、pandas DataFrame以及Spark表创建DataFrame的方法,这些应该是重点。首先,我需要分步骤说明不同的创建方式,比如从CSV、现有RDD、pandas DataFrame等。 接下来是操作DataFrame的部分。用户可能需要进行数据筛选、聚合、添加列等操作。引用1中提到DataFrame适合处理结构化数据,所以示例应包括常见的SQL-like操作,比如select、filter、groupBy等。此外,引用4提到转换为pandas DataFrame的注意事项,这里需要提醒用户小心内存问题。 然后,性能优化部分也很重要。引用2提到PySpark支持多种功能,比如Spark SQL,可以结合这些特性来展示优化技巧,比如缓存、避免shuffle等。同时,引用1中的性能优化可能涉及分区或执行计划调整,需要简单提及。 用户可能对实际代码示例感兴趣,所以每个步骤都需要提供代码片段。例如,创建DataFrame的不同方法,展示如何读取CSV,转换pandas DataFrame,以及执行操作后的输出。同时,需要注意代码格式是否正确,如使用正确的SparkSession初始化。 还需要考虑用户可能的后续问题,比如数据写入、处理大型数据集时的注意事项,或者与RDD的区别。但根据当前问题,重点放在创建和基本操作上。 最后,确保回答结构清晰,分点说明,并附上相关问题。检查是否有遗漏的创建方式或常见操作,确保覆盖主要的使用场景。同时,引用相关的引用来源,比如引用3中的示例代码,引用4的转换注意事项,以增强可信度。</think>### 使用 PySpark 创建和操作 DataFrame 的步骤 #### 一、创建 DataFrame 的常用方法 1. **从结构化文件(CSV/JSON/Parquet)读取** 使用`spark.read`模块加载结构化数据文件,支持自动推断数据类型(需谨慎使用`inferSchema`): ```python from pyspark.sql import SparkSession spark = SparkSession.builder.appName("DataFrame Demo").getOrCreate() # 从 CSV 文件创建(引用[3]) df_csv = spark.read.csv("path/to/file.csv", header=True, inferSchema=True) # 从 Parquet 文件创建 df_parquet = spark.read.parquet("path/to/file.parquet") ``` 2. **通过 Python 集合或 Pandas DataFrame 转换** 若数据量较小,可直接从列表或 Pandas DataFrame 转换: ```python import pandas as pd data = [("Alice", 34), ("Bob", 45)] # 从列表创建(需指定列名) df_spark = spark.createDataFrame(data, ["Name", "Age"]) # 从 Pandas DataFrame 转换(引用[4]) pd_df = pd.DataFrame(data, columns=["Name", "Age"]) spark_df = spark.createDataFrame(pd_df) ``` 3. **通过 SQL 查询生成** 将临时表注册到 Spark 元数据目录后,可通过 SQL 操作: ```python df_csv.createOrReplaceTempView("people") df_sql = spark.sql("SELECT Name, Age FROM people WHERE Age > 30") # 引用[3] ``` --- #### 二、DataFrame 核心操作 1. **数据查看与结构分析** ```python df_csv.show(5) # 显示前5行 df_csv.printSchema() # 打印表结构 df_csv.describe().show()# 统计摘要 ``` 2. **列操作与条件过滤** ```python from pyspark.sql.functions import col # 选择特定列 df_select = df_csv.select("Name", "Age") # 添加新列 df_with_column = df_csv.withColumn("AgePlus10", col("Age") + 10) # 条件过滤 df_filtered = df_csv.filter(col("Age") > 30) ``` 3. **聚合与分组** ```python from pyspark.sql.functions import avg df_grouped = df_csv.groupBy("Department").agg(avg("Salary").alias("AvgSalary")) ``` 4. **数据类型转换** ```python from pyspark.sql.types import IntegerType df_converted = df_csv.withColumn("AgeInt", col("Age").cast(IntegerType())) ``` --- #### 三、性能优化技巧(引用[1][2]) 1. **避免`inferSchema`开销** 对大型 CSV 文件手动指定 Schema 可提升读取速度: ```python from pyspark.sql.types import StructType, StructField, StringType, IntegerType schema = StructType([ StructField("Name", StringType(), True), StructField("Age", IntegerType(), True) ]) df = spark.read.csv("data.csv", header=True, schema=schema) ``` 2. **缓存高频访问数据** ```python df.cache() # 将 DataFrame 缓存到内存 ``` 3. **控制分区数** 通过`repartition`优化数据分布: ```python df = df.repartition(4) # 按指定分区数重新分布 ``` --- #### 四、与其他数据格式交互 1. **写入外部存储** ```python df.write.parquet("output.parquet", mode="overwrite") df.write.csv("output.csv", header=True) ``` 2. **与 Pandas 互转的注意事项(引用[4])** ```python # Spark -> Pandas(小数据集适用) pd_df = df.toPandas() # Pandas -> Spark(需注意Driver内存限制) spark_df = spark.createDataFrame(pd_df) ``` --- ### 示例完整代码 ```python # 初始化 Spark 会话 from pyspark.sql import SparkSession spark = SparkSession.builder.appName("DataFrame Tutorial").getOrCreate() # 创建 DataFrame data = [("Sales", 50000), ("Engineering", 80000)] columns = ["Department", "Budget"] df = spark.createDataFrame(data, columns) # 执行操作 df_filtered = df.filter(col("Budget") > 60000) df_filtered.show() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值