PySpark操作DataFrame常用方法

PYSPARK DataFrame 操作

.na

在 PySpark 中,DataFrame 的 .na 属性用于处理缺失值(NaN、null 或空值)。.na 属性提供了一组方法来处理和操作缺失值。以下是一些常用的方法:

1.drop()

删除包含任何缺失值的行

df.na.drop()
2.drop(subset)

删除指定列中包含缺失值的行。

df.na.drop(subset=["col1", "col2"])
3.fill(value,subset)

使用指定的值填充指定列中的缺失值。

df.na.fill(0, subset=["col1", "col2"])
4.replac(to_replace,value,subset)

将指定列中的特定值替换为给定的新值

df.na.replace("old_value", "new_value", subset=["col1", "col2"])

这些方法都返回一个新的 DataFrame,原始 DataFrame 不会被修改。

以下是一个使用 .na 方法处理缺失值的示例

from pyspark.sql import SparkSession

spark = SparkSession.builder.getOrCreate()

# 创建一个包含缺失值的 DataFrame
data = [("Alice", 25, None), ("Bob", None, 30), ("John", 35, 40)]
df = spark.createDataFrame(data, ["name", "age", "score"])

# 删除包含缺失值的行
df_without_na = df.na.drop()

# 填充缺失值
df_filled = df.na.fill(0, subset=["age"])

# 替换特定值
df_replaced = df.na.replace("Alice", "Lucy", subset=["name"])

# 显示处理后的 DataFrame
df_without_na.show()
df_filled.show()
df_replaced.show()

在上述示例中,我们首先创建了包含缺失值的 DataFrame。然后使用 .na.drop() 方法删除了包含任何缺失值的行,使用 .na.fill() 方法填充了缺失值,并使用 .na.replace() 方法替换了特定值。

最后,我们分别打印出经过处理后的 DataFrame。

col

from pyspark.sql.functions import col

pyspark.sql.functions.col() 是一个函数,用于引用 DataFrame 中的列。它主要用于在 Spark SQL 或 PySpark 中构建复杂的表达式和转换操作。

使用 col() 函数,你可以通过列名获取 DataFrame 中的列,并将其用作其他函数的参数或进行列之间的操作。

以下是一些 col() 函数的常见用法示例:

  1. 选择列:

    df.select(col("column_name"))
    
  2. 进行条件过滤:

    df.filter(col("column_name") > 5)
    
  3. 创建新列:

    df.withColumn("new_column", col("column1") + col("column2"))
    
  4. 嵌套函数调用:

    df.withColumn("new_column", sqrt(col("column1")))
    

通过使用 col() 函数,你可以对 DataFrame 的列执行各种转换和操作,例如选择、过滤、计算等。它提供了一种方便的方式来处理列级别的操作,同时使代码更易读和可维护。

withColumns()

在 PySpark 中,df.withColumn() 方法用于创建一个新的 DataFrame,并添加新的列或替换现有的列。它的语法如下:

df.withColumn(colName, col)

其中:

  • colName:要添加或替换的列的名称。
  • col:使用函数、表达式或已存在的列生成的新列。

withColumn() 方法允许你对现有 DataFrame 进行变换操作,例如添加新的计算列、重命名现有列、替换现有列的值等。它返回一个新的 DataFrame,而不会修改原始 DataFrame。

以下是一些 withColumn() 方法的常见用法示例:

  1. 添加计算列:

    df.withColumn("new_column", df["column1"] + 1)
    
  2. 重命名列:

    df.withColumnRenamed("old_column", "new_column")
    
  3. 替换列的值:

    df.withColumn("column1", when(df["column1"] < 0, 0).otherwise(df["column1"]))
    
  4. 基于现有列创建新列:

    df.withColumn("new_column", concat(df["first_name"], lit(" "), df["last_name"]))
    

通过使用 withColumn() 方法,你可以按照需要对 DataFrame 进行列级别的变换和操作。它提供了一种灵活的方式来构建和转换 DataFrame,以适应特定的数据处理需求。

when() otherwise()

在 PySpark 中,when() 函数用于执行条件逻辑操作。它通常与 otherwise() 方法一起使用来实现基于条件的列操作。

when() 函数接受一个条件表达式和一个要返回的值作为参数。它会根据条件表达式的结果决定返回的值。

以下是一个示例代码,展示了如何使用 when() 函数:

from pyspark.sql import SparkSession
from pyspark.sql.functions import col, when

spark = SparkSession.builder.getOrCreate()

# 创建一个包含数字列的 DataFrame
data = [(1,), (2,), (3,), (4,)]
df = spark.createDataFrame(data, ["number"])

# 使用 when 函数进行条件判断
df_updated = df.withColumn("new_number", when(col("number") < 3, "Low").otherwise("High"))

df_updated.show()

输出结果为:

+------+----------+
|number|new_number|
+------+----------+
|     1|       Low|
|     2|       Low|
|     3|      High|
|     4|      High|
+------+----------+

在上述示例中,我们创建了一个包含数字列的 DataFrame,并使用 when() 函数对 “number” 列进行条件判断。当数字小于 3 时,将 “new_number” 列设置为 “Low”;否则,设置为 “High”。

通过在 when() 函数中指定条件和相应的返回值,你可以根据特定条件对列进行处理和转换。这为数据操作提供了灵活性和可扩展性。

replace(str, search, replace)

pyspark.sql.functions.replace() 函数用于替换字符串中的特定子字符串。它的语法如下:

replace(str, search, replace)

其中:

  • str:要进行替换操作的字符串列或表达式。
  • search:要搜索并替换的子字符串。
  • replace:用于替换匹配项的新字符串。

这个函数将在给定的字符串列或表达式中查找所有匹配 search 的子字符串,并用 replace 进行替换。

以下是一个示例,展示了如何使用 replace() 函数:

from pyspark.sql import SparkSession
from pyspark.sql.functions import col, replace

spark = SparkSession.builder.getOrCreate()

# 创建一个包含字符串的 DataFrame
data = [("Alice", "Hello, Alice!"), ("Bob", "Hello, Bob!"), ("John", "Hi, John!")]
df = spark.createDataFrame(data, ["name", "message"])

# 使用 replace() 替换字符串中的子字符串
df_replaced = df.withColumn("new_message", replace(col("message"), "Hello", "Hi"))

df_replaced.show(truncate=False)

输出结果为:

+----+--------------+-------------------+
|name|message       |new_message        |
+----+--------------+-------------------+
|Alice|Hello, Alice! |Hi, Alice!         |
|Bob  |Hello, Bob!   |Hi, Bob!           |
|John |Hi, John!     |Hi, John!          |
+----+--------------+-------------------+

在上述示例中,我们创建了一个包含名字和消息的 DataFrame。然后,使用 replace() 函数将消息中的 “Hello” 替换为 “Hi”,并将结果保存在新列 “new_message” 中。

通过使用 replace() 函数,你可以对字符串列中的特定子字符串进行替换操作,使得数据处理更加灵活和方便。

Row对象

在 PySpark RDD 中,每一行数据通常不是 Row 对象,而是普通的 Python 对象(例如元组、列表等)或其他用户自定义的对象。

当使用 Spark 读取数据源创建 RDD 时,每一行会被解析为一个 Python 对象,通常是元组。例如,使用 sparkContext.parallelize() 方法创建 RDD,可以将元组作为每个元素,其中元组的每个元素表示一行数据的字段。

以下是一个示例代码,展示了如何创建包含元组的 RDD:

from pyspark.sql import SparkSession

spark = SparkSession.builder.getOrCreate()

# 创建一个 RDD 包含元组作为每一行数据
rdd = spark.sparkContext.parallelize([(1, "Alice"), (2, "Bob"), (3, "Charlie")])

# 输出每一行数据
for row in rdd.collect():
    print(row)

输出结果为:

(1, 'Alice')
(2, 'Bob')
(3, 'Charlie')

在上述示例中,我们使用 parallelize() 方法创建了一个 RDD,其中每个元素都是一个元组,表示一行数据的字段。

注意,如果你使用 DataFrame 或 Dataset API 来操作数据,那么每一行数据将会以 Row 对象的形式存在。但是,在 RDD 中,每一行数据通常是用普通的 Python 对象来表示的。

from pyspark.sql import SparkSession
spark = SparkSession.builder.getOrCreate()
data = [("Alice", 25, None), ("Bob", None, 30), ("John", 35, 40)]
df = spark.createDataFrame(data, ["name", "age", "score"])
df.show()
+-----+----+-----+
| name| age|score|
+-----+----+-----+
|Alice|  25| null|
|  Bob|null|   30|
| John|  35|   40|
print(type(df.rdd))
print(df.rdd.collect())
》》 <class 'pyspark.rdd.RDD'>
》》 [Row(name='Alice', age=25, score=None), Row(name='Bob', age=None, score=30), Row(name='John', age=35, score=40)]

# 便利每一行dataframe
z=df.rdd.map(lambda x: print(type(x))).collect()
print(z)

》》 <class 'pyspark.sql.types.Row'>
》》 <class 'pyspark.sql.types.Row'>
》》 <class 'pyspark.sql.types.Row'>
》》 [None, None, None]

StructType,StructField,数据类型

StructType

在 PySpark 中,pyspark.sql.types.StructType 是用于定义 DataFrame 的结构或模式的类。它用于指定每个字段的名称和数据类型,并且可以嵌套定义复杂的结构。

以下是一个示例代码,展示了如何使用 StructType 定义一个包含多个字段的结构:

from pyspark.sql import SparkSession
from pyspark.sql.types import StructType, StructField, StringType, IntegerType

spark = SparkSession.builder.getOrCreate()

# 定义结构(模式)
schema = StructType([
    StructField("name", StringType(), nullable=False),
    StructField("age", IntegerType(), nullable=True),
    StructField("city", StringType(), nullable=True)
])

# 创建 DataFrame 使用定义的结构
data = [("Alice", 30, "New York"), ("Bob", 35, "San Francisco"), ("Charlie", None, None)]
df = spark.createDataFrame(data, schema=schema)

df.show()

输出结果为:

+-------+----+-------------+
|   name| age|         city|
+-------+----+-------------+
|  Alice|  30|     New York|
|    Bob|  35|San Francisco|
|Charlie|null|         null|
+-------+----+-------------+

在上述示例中,我们导入了 StructType 和相关的类。然后,通过创建一个包含多个 StructField 的列表,定义了一个结构(模式)schema。每个 StructField 都需要指定字段名、字段类型和可选的 nullable 参数。

最后,我们使用 createDataFrame() 方法将数据和定义的结构传递给 SparkSession 来创建 DataFrame。

StructType定义DataFrame优点

使用 StructType 来定义 DataFrame 的模式(schema)有以下几个好处:

  1. 指定字段的名称和数据类型:通过使用 StructType,你可以明确指定每个字段的名称和数据类型。这对于确保数据按照预期的方式进行解析和处理非常重要。如果数据源文件或输入数据的结构发生变化,使用结构化模式可以提前捕捉到这些变化,并在读取数据时进行验证和处理。
  2. 提供类型安全性:定义一个结构化模式可以为 DataFrame 提供类型安全性。根据字段的数据类型,PySpark 在查询和操作期间可以进行类型检查,并提供更好的错误提示。这可以避免由于类型不匹配而导致的运行时错误,提高代码的可维护性和稳定性。
  3. 优化执行计划:指定准确的模式可以帮助 PySpark 优化执行计划。根据字段的数据类型,PySpark 可以选择最佳的执行策略,并应用相关的优化技术。这可以提高查询性能和整体数据处理效率。
  4. 数据一致性:使用结构化模式可以确保 DataFrame 中的数据与实际数据的结构相匹配。这可以防止数据中的格式错误、缺失值或其他异常情况影响数据处理的准确性。通过强制执行模式,你可以确保 DataFrame 数据的一致性和完整性。
  5. 元数据描述:结构化模式提供了有关 DataFrame 的元数据描述。通过查看模式,你可以了解 DataFrame 中每个字段的名称、数据类型、是否可为空等详细信息。这对于数据文档、数据质量控制和数据分析非常有用。

总而言之,使用 StructType 来定义 DataFrame 的模式可以提供更好的代码健壮性、类型安全性以及查询性能优化。它确保数据按照预期的方式进行处理,并提供了额外的元数据信息,有助于数据处理的准确性和可维护性。

StructField

StructField 是 PySpark 中用于定义结构化数据模式的类之一。它用于描述 DataFrame 或表的字段,并指定每个字段的名称、数据类型和是否可为空。

StructField 的构造函数如下:

StructField(name, dataType, nullable=True)

参数说明:

  • name: 字段名称,为字符串类型。
  • dataType: 字段的数据类型,可以使用 pyspark.sql.types 中提供的数据类型,例如 StringType()IntegerType() 等。
  • nullable: 指定该字段是否可以为空,默认为 True

通过使用 StructField,你可以在 StructType 中定义多个字段,从而构建复杂的数据模式。这样做有助于确保 DataFrame 或表的结构与实际数据的结构相匹配,并提供了类型安全性和数据一致性。

pyspark.sql.types中的数据类型

pyspark.sql.types 模块提供了多种数据类型类,用于在 PySpark 中定义字段或列的数据类型。以下是一些常用的数据类型及其作用:

  • StringType: 表示字符串类型的数据。
  • IntegerType: 表示整数类型的数据。
  • FloatType: 表示浮点数类型的数据。
  • DoubleType: 表示双精度浮点数类型的数据。
  • BooleanType: 表示布尔类型的数据,取值为 True 或 False。
  • DateType: 表示日期类型的数据。
  • TimestampType: 表示时间戳类型的数据。
  • ArrayType: 表示数组类型的数据,可以包含不同类型的元素。
  • StructType: 表示结构类型的数据,类似于关系型数据库的表结构。
  • MapType: 表示键值对类型的数据,其中键和值可以具有不同的数据类型。
from pyspark.sql.types import IntegerType

# 定义一个整数类型的字段
age_field = StructField("age", IntegerType(), nullable=True)

CAST()

在 PySpark 中,cast 函数用于将 DataFrame 或列中的数据类型转换为所需的数据类型。它可以用于将某个列的数据类型更改为其他类型,或者在查询中对特定表达式进行类型转换。

使用 cast 函数的一般语法如下:

df.withColumn("new_column", df["existing_column"].cast(StringType()))

其中,df 是一个 DataFrame,“new_column” 是新列的名称,“existing_column” 是现有列的名称,StringType() 是要转换为的目标数据类型。

例如,将一个整数列转换为浮点数列可以使用以下代码:

from pyspark.sql.functions import col

df = df.withColumn("new_column", col("existing_column").cast("float"))

类型最好使用pyspark.sql.types中的数据类型

此代码将 DataFrame df 中的名为 “existing_column” 的列的数据类型转换为浮点数,并将结果存储在名为 “new_column” 的新列中。

需要注意的是,cast 函数只返回一个新的 DataFrame,它不会修改原始的 DataFrame。如果需要在原始 DataFrame 上进行更改,可以重新分配变量。

另外,cast 函数还可用于在查询中对表达式进行类型转换,而不仅仅限于列。例如:

from pyspark.sql.functions import expr

df = df.withColumn("new_column", expr("CAST(existing_column AS float)"))

以上代码将 existing_column 表达式的数据类型转换为浮点数,并将结果存储在 “new_column” 列中。

groupBy()

在 PySpark 中,groupBy 函数返回的是一个 GroupedData 对象,它代表了对 DataFrame 进行分组后的结果。要展示 GroupedData 的内容,你可以使用一些聚合函数(如 count()sum()avg())或转换操作(如 agg()pivot())来计算和转换数据。

以下是几种常见的方法来展示 GroupedData 的内容:

  1. 使用聚合函数:可以直接应用聚合函数来计算每个分组的结果,并通过调用 show() 方法展示结果。
from pyspark.sql.functions import count,sum, avg

spark = SparkSession.builder.getOrCreate()
data = [("Alice", 25, 'cn'), ("Bob", None, 'cn'), ("John", 35, 'cn'),
        ("TOM", 25, 'am'), ("JOKER", None, 'am'), ("SILE", 35, 'am'),
        ("APPLE", 25, None), ("HABY", None, None), ("TINES", 35, 'yd')]
df = spark.createDataFrame(data, ["name", "age", "city"])
df.show()
》》
+-----+----+----+
| name| age|city|
+-----+----+----+
|Alice|  25|  cn|
|  Bob|null|  cn|
| John|  35|  cn|
|  TOM|  25|  am|
|JOKER|null|  am|
| SILE|  35|  am|
|APPLE|  25|null|
| HABY|null|null|
|TINES|  35|  yd|
+-----+----+----+

print(df.groupBy('city'))
print(type(df.groupBy('city')))
# 聚合后类型变换为GroupedData
<pyspark.sql.group.GroupedData object at 0x7f018e34f8d0> 
<class 'pyspark.sql.group.GroupedData'>

result = df.groupBy('city').agg(count("city"),sum('age'))
print(type(result))
result.show()

<class 'pyspark.sql.dataframe.DataFrame'>
+----+-----------+--------+
|city|count(city)|sum(age)|
+----+-----------+--------+
|  cn|          3|      60|
|null|          0|      25|
|  am|          3|      60|
|  yd|          1|      35|
+----+-----------+--------+

agg()

在 PySpark 中,agg(aggregate)函数用于对 DataFrame 进行聚合操作。它允许你在一个或多个列上应用一个或多个聚合函数,并返回计算后的结果。

agg 函数常与 groupBy 结合使用,以按照指定的分组条件对数据进行聚合。它可以用于计算各种统计量,如总和、平均值、最大值、最小值等。

以下是 agg 函数的示例用法:

from pyspark.sql.functions import sum, avg, max

df.groupBy("groupColumn").agg(sum("col1"), avg("col2"), max("col3")).show()

在上述代码中,我们首先使用 groupBy 对 DataFrame 进行分组,按照 “groupColumn” 列的值进行分组。然后,通过 agg 函数对每个组进行聚合操作,传递了三个聚合函数:sumavgmax,分别应用于 “col1”、“col2” 和 “col3” 列。最后,使用 show 方法展示聚合结果。

通过 agg 函数,你可以根据需求选择不同的聚合函数,并在多个列上同时应用它们。还可以使用其他支持的聚合函数,如 countmincollect_list 等。此外,你还可以自定义聚合操作,通过定义自己的聚合函数来实现更灵活的聚合操作。

总之,agg 函数在 PySpark 中用于对 DataFrame 进行聚合操作,可以在一个或多个列上应用一个或多个聚合函数,并返回计算后的结果。

collect_list()

collect_list 函数是 PySpark 中用于将指定列的值收集到一个列表中的聚合函数。

该函数常与 groupBy 结合使用,以按照指定的分组条件对数据进行聚合,并将每个组内指定列的值收集到一个列表中。这在需要将某一列的多个值作为一个整体进行处理时非常有用。

只能选一列数据收集到列表中,列表中元素非row对象(选中的列每行数据都数据)

以下是 collect_list 函数的示例用法:

from pyspark.sql.functions import collect_list
from pyspark.sql import SparkSession
from pyspark.sql.functions import col,count,sum,struct,collect_list
#样例
df.groupBy("groupColumn").agg(collect_list("valueColumn").alias("listValues")).show()

#实际
spark = SparkSession.builder.getOrCreate()
data = [("Alice", 25, 'cn','2023'), ("Bob", None, 'cn','2023'), ("John", 35, 'cn','2023'),
        ("TOM", 25, 'am','2023'), ("JOKER", None, 'am','2023'), ("SILE", 35, 'am','2023'),
        ("APPLE", 25, None,'2023'), ("HABY", None, None,'2023'), ("TINES", 35, 'yd','2023')]
df = spark.createDataFrame(data, ["name", "age", "city",'data_date'])

df2 = df.groupBy("city").agg(collect_list('name').alias("ldsx"))
df2.rdd.map(lambda x:print(x)).collect()

Row(city='yd', ldsx=['TINES'])
Row(city=None, ldsx=['APPLE', 'HABY'])
Row(city='am', ldsx=['TOM', 'JOKER', 'SILE'])
Row(city='cn', ldsx=['Alice', 'Bob', 'John'])

df2.show()
+----+------------------+
|city|              ldsx|
+----+------------------+
|  cn|[Alice, Bob, John]|
|null|     [APPLE, HABY]|
|  am|[TOM, JOKER, SILE]|
|  yd|           [TINES]|
+----+------------------+

在上述代码中,我们首先使用 groupBy 对 DataFrame 进行分组,按照 “groupColumn” 列的值进行分组。然后,通过 agg 函数对每个组进行聚合操作,使用 collect_list 函数来收集 “valueColumn” 列的值到一个列表中。最后,使用 alias 方法给聚合结果的列表列起名为 “listValues”,并通过 show 方法展示聚合结果。

使用 collect_list 函数可以将同一组内的多个值收集到一个列表中,方便进一步对列表进行处理或者存储。你也可以结合其他聚合函数一起使用,如 sumavg 等,来完成更复杂的聚合操作。

总之,collect_list 函数在 PySpark 中用于将指定列的值收集到一个列表中,并适用于对数据进行分组和聚合的场景。

Struct

struct 函数在 PySpark 中的作用是将多个列组合成一个复杂类型(StructType)的单列。它可以用于创建结构化的数据,方便对多个相关列进行处理和操作。

具体而言,struct 函数将传入的列作为参数,并返回一个新的复杂类型列,其中包含了传入的列名和对应的值。这个新的列可以用于进一步的计算、聚合或者存储。

多列融合为一列,聚合后的列数据变成row对象(相当一行数据,选中的几列融合到一起,融合后的列 就是这一行的列不涉及其余行)

以下是 struct 函数的一个示例:

from pyspark.sql.functions import struct
from pyspark.sql import SparkSession
from pyspark.sql.functions import col,count,sum,struct

spark = SparkSession.builder.getOrCreate()
data = [("Alice", 25, 'cn'), ("Bob", None, 'cn'), ("John", 35, 'cn'),
        ("TOM", 25, 'am'), ("JOKER", None, 'am'), ("SILE", 35, 'am'),
        ("APPLE", 25, None), ("HABY", None, None), ("TINES", 35, 'yd')]
df = spark.createDataFrame(data, ["name", "age", "city"])
df.show()

df.select(struct("name", "age", "city").alias("combined")).show()
+---------------+
|       combined|
+---------------+
|[Alice, 25, cn]|
|     [Bob,, cn]|
| [John, 35, cn]|
|  [TOM, 25, am]|
|   [JOKER,, am]|
| [SILE, 35, am]|
|   [APPLE, 25,]|
|       [HABY,,]|
|[TINES, 35, yd]|

df.rdd.map(lambda x:print(x)).collect()

Row(combined=Row(name='Alice', age=25, city='cn'))
Row(combined=Row(name='TOM', age=25, city='am'))
Row(combined=Row(name='John', age=35, city='cn'))
Row(combined=Row(name='APPLE', age=25, city=None))
Row(combined=Row(name='HABY', age=None, city=None))
Row(combined=Row(name='SILE', age=35, city='am'))
Row(combined=Row(name='Bob', age=None, city='cn'))
Row(combined=Row(name='TINES', age=35, city='yd'))
Row(combined=Row(name='JOKER', age=None, city='am'))

在上述代码中,我们使用 struct 函数将 “col1”、“col2” 和 “col3” 列组合成一个名为 “combined” 的复杂类型列。通过 select 函数选择该复杂类型列,并设置别名为 “combined”。最后,通过 show 方法展示结果。

这样可以将多个相关的列组合在一起,方便进行后续的分析和处理。例如,你可以对该复杂类型列进行进一步的查询或者将其用于 groupBy 操作来进行数据聚合等。

总之,struct 函数在 PySpark 中提供了一种简洁和灵活的方式来组合多个列,并将它们封装为一个复杂类型的单列。这有助于在处理数据时更好地表示和操作相关信息。

# struct所有列聚合成一列,collect_list按照聚合列把每一行的数据收集到一个列表中
odps_df = df.groupBy("city").agg(
        collect_list(struct(*df.columns)).alias("ldsx")
    )

+----+--------------------+
|city|                ldsx|
+----+--------------------+
|  cn|[[Alice, 25, cn, ...|
|null|[[APPLE, 25,, 202...|
|  am|[[TOM, 25, am, 20...|
|  yd|[[TINES, 35, yd, ...|
+----+--------------------+

Row(city='yd', ldsx=[Row(name='TINES', age=35, city='yd', data_date='2023')])

Row(city='cn', ldsx=[Row(name='Alice', age=25, city='cn', data_date='2023'), Row(name='Bob', age=None, city='cn', data_date='2023'), Row(name='John', age=35, city='cn', data_date='2023')])

Row(city='am', ldsx=[Row(name='TOM', age=25, city='am', data_date='2023'), Row(name='JOKER', age=None, city='am', data_date='2023'), Row(name='SILE', age=35, city='am', data_date='2023')])

Row(city=None, ldsx=[Row(name='APPLE', age=25, city=None, data_date='2023'), Row(name='HABY', age=None, city=None, data_date='2023')])

DataFrame.columns

df = spark.createDataFrame(
...     [(14, "Tom"), (23, "Alice"), (16, "Bob")], ["age", "name"])
>>> df.columns
['age', 'name']

DataFrame.cov 协方差

df = spark.createDataFrame([(1, 12), (10, 1), (19, 8)], ["c1", "c2"])
df.cov("c1", "c2")
-18.0
df = spark.createDataFrame([(11, 12), (10, 11), (9, 10)], ["small", "bigger"])
df.cov("small", "bigger")
1.0

DataFrame.createTempView

df = spark.createDataFrame([(2, "Alice"), (5, "Bob")], schema=["age", "name"])
df.createTempView("people")
df2 = spark.sql("SELECT * FROM people")
sorted(df.collect()) == sorted(df2.collect())
True
Throw an exception if the table already exists.

df.createTempView("people")  
Traceback (most recent call last):
...
AnalysisException: "Temporary table 'people' already exists;"
spark.catalog.dropTempView("people")
True

DataFrame.createOrReplaceTempView

df = spark.createDataFrame([(2, "Alice"), (5, "Bob")], schema=["age", "name"])
df.createOrReplaceTempView("people")

df2 = df.filter(df.age > 3)
df2.createOrReplaceTempView("people")
df3 = spark.sql("SELECT * FROM people")
sorted(df3.collect()) == sorted(df2.collect())

createOrReplaceTempView 方法可以用于创建或替换临时视图,而 createTempView 方法只能用于创建新的临时视图。

DataFrame.createGlobalTempView

DataFrame.createGlobalTempView 是 PySpark 中 DataFrame 对象的方法之一。它用于创建一个全局临时视图。

具体来说,createGlobalTempView 方法将当前 DataFrame 对象注册为一个全局临时视图。全局临时视图是一个在整个 Spark 应用程序中可见的、命名的逻辑表,可以基于该视图执行 SQL 查询。

这个方法的作用是将 DataFrame 转换为一个全局可见的虚拟表。通过创建全局临时视图,你可以在整个 Spark 应用程序的不同会话中使用相同的视图名称对 DataFrame 进行查询和操作。

以下是一个示例:

from pyspark.sql import SparkSession

# 创建一个 SparkSession
spark = SparkSession.builder.getOrCreate()

# 创建一个 DataFrame
df = spark.read.csv("data.csv", header=True, inferSchema=True)

# 将 DataFrame 注册为一个全局临时视图
df.createGlobalTempView("my_global_temp_view")

在上述代码中,createGlobalTempView 方法将 DataFrame df 注册为名为 “my_global_temp_view” 的全局临时视图。接下来,你可以在其他 Spark 应用程序的不同会话中使用相同的视图名称对该全局临时视图进行查询和操作,例如:

spark.newSession().sql("SELECT * FROM global_temp.my_global_temp_view").show()

createGlobalTempView 方法的作用是创建一个全局临时视图,使得该视图在整个 Spark 应用程序的不同会话中都是可见的。通过使用全局临时视图,可以实现跨会话的数据共享和查询操作。

DataFrame.createOrReplaceGlobalTempView

可直接覆盖替换 同createTempView 与createOrReplaceTempView

DataFrame.distinct

去重完全相同的数据 不能加参数

df = spark.createDataFrame(
...     [(14, "Tom"), (23, "Alice"), (23, "Alice")], ["age", "name"])
>>> df.distinct().count()
2

DataFrame.dropDuplicates

drop_duplicates() is an alias for dropDuplicates() 别名

DataFrame.``dropDuplicates(subset: Optional[List[str]] = None)

不加指定列等价于distinct

>>> from pyspark.sql import Row
>>> df = spark.createDataFrame([
...     Row(name='Alice', age=5, height=80),
...     Row(name='Alice', age=5, height=80),
...     Row(name='Alice', age=10, height=80)
... ])
>>> df.dropDuplicates().show()
+-----+---+------+
| name|age|height|
+-----+---+------+
|Alice|  5|    80|
|Alice| 10|    80|
+-----+---+------+

指定列去重

>>> df.dropDuplicates(['name', 'height']).show()
+-----+---+------+
| name|age|height|
+-----+---+------+
|Alice|  5|    80|
+-----+---+------+

DataFrame.drop

删除选中的列drop(col1,col2),drop(*cols),可多选择列删除

from pyspark.sql import Row
>>> df = spark.createDataFrame(
...     [(14, "Tom"), (23, "Alice"), (16, "Bob")], ["age", "name"])
>>> df2 = spark.createDataFrame([Row(height=80, name="Tom"), Row(height=85, name="Bob")])
>>> df.drop('age').show()
+-----+
| name|
+-----+
|  Tom|
|Alice|
|  Bob|
+-----+
>>> df.drop(df.age).show()
+-----+
| name|
+-----+
|  Tom|
|Alice|
|  Bob|
+-----+
>>> df.join(df2, df.name == df2.name, 'inner').drop('name').sort('age').show()
+---+------+
|age|height|
+---+------+
| 14|    80|
| 16|    85|
+---+------+

DataFrame.dropna

DataFrameNaFunctions.drop别名

df.na.drop()DataFrameNaFunctions类的一个方法,允许您处理包含空值的列

DataFrame.dropna() and DataFrameNaFunctions.drop() are aliases of each other.别名

from pyspark.sql import Row
>>> df = spark.createDataFrame([
...     Row(age=10, height=80, name="Alice"),
...     Row(age=5, height=None, name="Bob"),
...     Row(age=None, height=None, name="Tom"),
...     Row(age=None, height=None, name=None),
... ])
>>> df.na.drop().show()
+---+------+-----+
|age|height| name|
+---+------+-----+
| 10|    80|Alice|
+---+------+-----+

在 PySpark 中,df.na.drop()df.dropna() 都是 DataFrame 对象的方法,用于处理缺失值。它们之间的区别如下:

  1. df.na.drop(**{subset:[col,col]}):这个方法用于删除包含任何缺失值(null 或 NaN)的行。默认情况下,该方法会删除包含任何缺失值的整行数据。你可以通过传递额外的参数来指定其他条件,例如只删除某一列中包含缺失值的行。
  2. df.dropna():这个方法用于删除包含缺失值的行或列。默认情况下,该方法会删除包含任何缺失值的行。然而,**你也可以通过指定 how 参数来操作列上的缺失值,以控制删除行还是列。如果 how='all',则只有当整列都是缺失值时才会删除该列。**参数为:any,all

DataFrame.dtypes

返回字段类型

df = spark.createDataFrame(
...     [(14, "Tom"), (23, "Alice"), (16, "Bob")], ["age", "name"])
>>> df.dtypes
[('age', 'bigint'), ('name', 'string')]

DataFrame.exceptAll

返回一个新的DataFrame,其中包含此DataFrame 中的行,但不包含另一個DataFrame 中的行,同時保留重复项。

总结起来,exceptAll 方法用于计算两个 DataFrame 之间的差集,返回第一个 DataFrame 中存在但在第二个 DataFrame 中不存在的所有行,包括重复的行。差集且不去重

df1 = spark.createDataFrame(
...         [("a", 1), ("a", 1), ("a", 1), ("a", 2), ("b",  3), ("c", 4)], ["C1", "C2"])
>>> df2 = spark.createDataFrame([("a", 1), ("b", 3)], ["C1", "C2"])
>>> df1.exceptAll(df2).show()
+---+---+
| C1| C2|
+---+---+
|  a|  1|
|  a|  1|
|  a|  2|
|  c|  4|
+---+---+
  • 33
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值