pyspark dataframe的常用操作

本文介绍 PySpark 中数据处理的多种实用技巧,包括列重命名、删除与选择、使用 UDF 进行复杂运算、聚合操作及数据类型转换等。通过具体示例展示了如何高效管理和分析大规模数据集。

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

1、列重命名:

train_data = train_data.toDF('imei', 'pkgName', 'timestamp')

2、删除某一列:

df = df.drop('col')

3、选取list中指定的列:

df = spark_session.createDataFrame(
    [(1, 1.0, 5), (1, 2.0, 7), (2, 3.0, 9), (2, 5.0, 11), (2, 10.0, 13)],
    ("id", "v", 'c'))
 
df.show(5)


sel_list = ['id', 'c']

df.select(*sel_list).show()

4.1、自定义函数,使用udf,而且有多个输入量:

from pyspark.sql.functions import *
from pyspark.sql.types import *
from pyspark.sql.functions import udf
from pyspark.sql.types import IntegerType,StringType

def get_hours(cur_day, cur_hour):
    return cur_day * 24 + cur_hour

get_hours_udf = udf(get_hours,IntegerType())


train_data2 = train_data2.withColumn('hours',get_hours_udf(train_data2['day'],train_data2["hour"]))

4.2 自定义函数,基于pandas_udf。这里基于的是Pyspark2。需要安装pyarrow==0.14.1(需要指定版本,太高了不一定行)

import pandas as pd
from pyspark.sql.functions import col, pandas_udf
from pyspark.sql.types import LongType
 
df = spark_session.createDataFrame(
    [(1, 1.0), (1, 2.0), (2, 3.0), (2, 5.0), (2, 10.0)],
    ("id", "v"))
 
df.show(5)

@pandas_udf(LongType())     #输入一列。这种是返回Series的方法
def multiply_func1(all_data):
    def helper(input_data):
        return input_data * input_data
    res = [helper(d) for d in all_data]
    return pd.Series(res)
 
@pandas_udf(LongType())   #输入两列。这种是直接搞函数的方法。更加推荐这种写法
def multiply_func2(all_data1, all_data2):
    return all_data1 * all_data2 + 5
 

df = df.withColumn('test1', multiply_func1(col("v"))   )
df.show()
df = df.withColumn("ss2", multiply_func2((col("v")), col("test1")))
df.show()

输出如下:

+---+----+
| id|   v|
+---+----+
|  1| 1.0|
|  1| 2.0|
|  2| 3.0|
|  2| 5.0|
|  2|10.0|
+---+----+

+---+----+----+
| id|   v|test|
+---+----+----+
|  1| 1.0|   1|
|  1| 2.0|   4|
|  2| 3.0|   9|
|  2| 5.0|  25|
|  2|10.0| 100|
+---+----+----+

+---+----+----+----+
| id|   v|test|   t|
+---+----+----+----+
|  1| 1.0|   1|   1|
|  1| 2.0|   4|   8|
|  2| 3.0|   9|  27|
|  2| 5.0|  25| 125|
|  2|10.0| 100|1000|
+---+----+----+----+

注:如果如果输入或者输出包括String类型,似乎只能用返回Series的形式:

import pandas as pd
from pyspark.sql.functions import col, pandas_udf
from pyspark.sql.types import LongType
 
df = spark_session.createDataFrame(
    [(1, 1.0), (1, 2.0), (2, 3.0), (2, 5.0), (2, 10.0)],
    ("id", "v"))
 
df.show(5)

@pandas_udf(StringType())     #输入一列。这种是返回Series的方法
def multiply_func1(all_data):
    return str(all_data * 2)
 

df = df.withColumn('test1', multiply_func1(col("v"))   )
df.show()
# df = df.withColumn("ss2", multiply_func2((col("v")), col("test1")))
# df.show()

#报错
import pandas as pd
from pyspark.sql.functions import col, pandas_udf
from pyspark.sql.types import LongType
 
df = spark_session.createDataFrame(
    [("1", 1.0), ("1", 2.0), ("2", 3.0), ("2", 5.0), ("2", 10.0)],
    ("height", "v"))
 
df.show(5)

@pandas_udf(IntegerType())     #输入一列。这种是返回Series的方法
def multiply_func1(all_data):
    return int(all_data)
 
df.withColumn('v', multiply_func1(col("height"))).show()  #不报错
df.withColumn('test1', multiply_func1(col("height"))).show()  #报错

5、groupby聚合并拼接:

from pyspark.sql.functions import window, column, desc, col,collect_list

u1 = train_data2.groupBy(['user','hour','day']).agg(collect_list(train_data2["pkgName"])).alias('pkgName_list')   

#还有collect_set

6、列数据类型转换:


data_df = data_df.withColumn("APP_HOBY_CASH_LOAN", data_df["APP_HOBY_CASH_LOAN"].cast(StringType()))

7、从pyspark dataframe中抽取符合某条件的对象

train_data2= train_data.filter(train_data.day == "2020-05-04")

8、pyspark DataFrame存入hive的某个分区中

spark_df = spark_df.withColumn("day", F.lit("2021-11-11"))
spark_df.write.saveAsTable("DB.table", format="hive", mode="overwrite", partitionBy="day")
#DB.table为预期保存在数仓的位置和名称,day为分区。这样即可做到把2021-11-11的数据存在了指定分区

9、pyspark DataFrame将用分隔符分割的列表转换为vector(形如将1*3*5*8*6*2变成1,3,5,8,6,2的vector)

from pyspark.ml.linalg import VectorUDT, Vectors

from pyspark.sql.functions import udf, col
from pyspark.sql.types import ArrayType, DoubleType,FloatType


#这里假定data_df的user_vector中每一列是形如1*3*5*8*6*2的string

def get_vector(user_vector_string):
    res = []
    u1 = user_vector_string.split("*")
    for u in u1:
        res.append(float(u))
        
    return res



get_vector_udf = udf(get_vector, ArrayType(FloatType()))
data_df2 = data_df.withColumn("vector", get_vector_udf(data_df['user_vector']))


list_to_vector_udf = udf(lambda l: Vectors.dense(l), VectorUDT())
data_df3= data_df2.withColumn("features",  list_to_vector_udf(data_df2['vector']))

#之后就可以对features中的值进行操作,比如kmeans聚类等

10、pyspark DataFrame,列名批量重新命名

res_col_list = [...,...,...,] #需要的列名

data_df = data_df.toDF(*res_col_list)

11、pyspark DataFrame,在udf中输入参数

from pyspark.sql import functions as F

#此函数的含义为用fill_data替换-7。
def nan_data_process_udf(fill_data):
    def nan_data_process(col_data, fill_data):
        if int(col_data) == -7:
            return fill_data
        else:
            return col_data

    return F.udf(lambda x: nan_data_process(x, fill_data))

#然后:
data_df = data_df.withColumn(cur_col, nan_data_process_udf(cur_avg)(F.col(cur_col)))
#其中cur_avg就是输入的入参

12、pyspark,选取某个list中的列

columns = ['home','house','office','work']

#select the list of columns
df_tables_full.select('time_event','kind','schema','table',*columns).show()

df_tables_full = df_tables_full.select('time_event','kind','schema','table',*columns)

Pyspark 3 专用的

1、使用apply处理,且在原来的基础上增加一列

import pyspark.pandas as ps

def func(s) -> str:
    return str(s) + "100"




df = ps.DataFrame({'A': range(10)})


#注意这里的df,是<class 'pyspark.pandas.frame.DataFrame'>,而传统的从csv读取的dataFrame,是##<class 'pyspark.sql.dataframe.DataFrame'>。因此对于后者,需要调用.to_pandas_on_spark() 方#法进行转换。

print(df.head(5))
res = df.A.apply(func)
# print(res)
# print(type(res))
res.name = "func"  #重命名结果列
df = df.join(res)
print(df.head(5))


# 输出:
#    A
# 0  0
# 1  1
# 2  2
# 3  3
# 4  4
#    A  func
# 0  0  0100
# 1  1  1100
# 3  3  3100
# 2  2  2100
# 5  5  5100

<think>好的,我现在需要帮助用户了解如何使用PySpark创建和操作DataFrame。首先,我得回忆一下PySpark的基本知识。用户可能已经知道PySparkPython的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() ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值