pyspark.sql.DataFrame


pyspark中的dataframe的官方定义为:分布式数据集合,其等效于Spark SQL中的关系表,可以使用SparkSession中的各种函数来创建。pyspark.sql.DataFrame和Pandas.DataFrame二者有相似之处,后续会对二者进行比较。

agg()、alias()

agg()表示在没有分组的情况下对整个dataframe进行聚合(还有另一种分组的聚合:df.groupBy.agg()),alias()相当于取了别名。

import pandas as pd
import numpy as np
from pyspark.sql import functions as fn
from pyspark.sql import SparkSession
spark=SparkSession.builder.appName("local").enableHiveSupport().getOrCreate()
pdf=pd.DataFrame(np.arange(20).reshape(4,5),columns=["a","b","c","d","e"])
df=spark.createDataFrame(pdf)
df.agg(fn.count("a").alias("a_count"),fn.countDistinct(df.b),fn.sum("c"),fn.max("d").alias("max"),fn.min("e")).show()
+-------+-----------------+------+---+------+
|a_count|count(DISTINCT b)|sum(c)|max|min(e)|
+-------+-----------------+------+---+------+
|      4|                4|    38| 18|     4|
+-------+-----------------+------+---+------+

colRegex()

以正则表达式选择dataframe的列名

df = spark.createDataFrame([("a", 1), ("b", 2), ("c",  3)], ["Col1", "Col2"])
df.select(df.colRegex("`(col)\d`")).show()
+----+----+
|Col1|Col2|
+----+----+
|   a|   1|
|   b|   2|
|   c|   3|
+----+----+

createGlobalTempView()

使用此DataFrame创建全局临时视图。此临时视图的生命周期与此Spark应用程序相关联。 如果目录中已存在视图名称,则抛出TempTableAlreadyExistsException。

>>> df.createGlobalTempView("people")
>>> df2 = spark.sql("select * from global_temp.people")
>>> sorted(df.collect()) == sorted(df2.collect())
True
>>> df.createGlobalTempView("people")
AnalysisException: u"Temporary table 'people' already exists;"

与此类似的还有createOrReplaceGlobalTempView(),该方法创建同名视图不会程序异常,新的会直接替换旧的。此外,还有createOrReplaceTempView()、createTempView()方法,这两个方法与前面两个方法的区别在于:前者是全局的,后者是本地的。

drop()

返回删除指定列的新DataFrame。 如果原DataFrame不包含给定的列名,则这是一个无操作。

>>> df.drop('age').collect()
[Row(name='Alice'), Row(name='Bob')]
>>> df.join(df2, df.name == df2.name, 'inner').drop(df.name).collect()
[Row(age=5, height=85, name='Bob')]

exceptAll(other)

两个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|
+---+---+

filter()、where()

filter()和where()函数二者功能是相同的,条件过滤。

>>> df.filter(df.age > 3).collect()
[Row(age=5, name='Bob')]
>>> df.where(df.age == 2).collect()
[Row(age=2, name='Alice')]

groupBy()

比较简单,类似于sql中的分组,后面常跟聚合函数agg()

>>> sorted(df.groupBy('name').agg({'age': 'mean'}).collect())
[Row(name='Alice', avg(age)=2.0), Row(name='Bob', avg(age)=5.0)]
>>> sorted(df.groupBy(['name', df.age]).count().collect())
[Row(name='Alice', age=2, count=1), Row(name='Bob', age=5, count=1)]

intersectAll(other)

求两个dataframe的交集

df1 = spark.createDataFrame([(“a”, 1), (“a”, 1), (“b”, 3), (“c”, 4)],[“C1”, “C2”])
df2 = spark.createDataFrame([(“a”, 1), (“a”, 1), (“b”, 3)], [“C1”, “C2”])
df1.intersectAll(df2).sort("C1", "C2").show()
+---+---+
| C1| C2|
+---+---+
|  a|  1|
|  a|  1|
|  b|  3|
+---+---+

join(other, on=None, how=None)

两个datafram链接操作

>>> cond = [df.name == df3.name, df.age == df3.age]
>>> df.join(df3, cond, 'outer').select(df.name, df3.age).collect()
[Row(name='Alice', age=2), Row(name='Bob', age=5)]
>>> df.join(df4, ['name', 'age']).select(df.name, df.age).collect()
[Row(name='Bob', age=5)]

sort()、orderby()

排序操作

>>> df.sort("age", ascending=False).collect()
[Row(age=5, name='Bob'), Row(age=2, name='Alice')]
>>> df.orderBy(["age", "name"], ascending=[0, 1]).collect()
[Row(age=5, name='Bob'), Row(age=2, name='Alice')]

replace(to_replace, value=, subset=None)

将指定值替换为另一个值

  • to_replace表示要被替换掉的值,可以是bool, int, long, float, string, list or dict,如果是dic,则参数value将被忽略。
  • value表示将要替换的值,可以是bool, int, long, float, string, list or None. 如果value是列表,则value应与to_replace具有相同的长度和类型。 如果value是标量且to_replace是序列,则value用作to_replace中每个项的替换。
  • subset表示需要的替换的列的范围。
df4.replace('Alice', None).show()
#或者
df4.replace({'Alice': None}).show()
+----+------+----+
| age|height|name|
+----+------+----+
|  10|    80|null|
|   5|  null| Bob|
|null|  null| Tom|
|null|  null|null|
+----+------+----+
df4.replace(['Alice', 'Bob'], ['A', 'B'], 'name').show()
+----+------+----+
| age|height|name|
+----+------+----+
|  10|    80|   A|
|   5|  null|   B|
|null|  null| Tom|
|null|  null|null|
+----+------+----+

withColumn()

通过添加列或替换具有相同名称的现有列来构造新的DataFrame。列表达式必须是此DataFrame上的表达式; 如果尝试从其他数据框添加列将引发错误。

  • 运用withcolumn()通过现有列,构造新的列
>>> df.withColumn('age2', df.age + 2).collect()
[Row(age=2, name='Alice', age2=4), Row(age=5, name='Bob', age2=7)]
  • 运用withcolumn()修改列字段类型
df=df.withColumn("price",df.price.astype("float"))
# 或者
df=df.withColumn("price",df["price"].cast(FloatType())
  • 运用withcolumn()和自定义函数修改某列或增加新列,其中,update_units是我的自定义函数,关于自定义函数这块后面会专门来讲的,这里暂时先用着。
from pyspark.sql import functions
update_units_udf=functions.udf(update_units,StringType())
df=df.withColumn("quant_first",update_units_udf("quant_first"))
df=df.withColumn("unit_price",df.price/(df.quant_first_int*df.quant_second_int))

withColumnRenamed(existing, new)

修改列名

>>> df.withColumnRenamed('age', 'age2').collect()
[Row(age2=2, name='Alice'), Row(age2=5, name='Bob')]

到这里为止,pyspark.sql.DataFrame的基本常用API就讲完了,当还有一些像show()、describe()、select()等等之类没讲,简单的很,没啥可讲的,基本用法讲完后,后面会陆续更新一些高阶用法。

发布了24 篇原创文章 · 获赞 2 · 访问量 1187

猜你喜欢

转载自blog.csdn.net/qq_40176087/article/details/100045145