文章目录

  • pyspark读取数据
  • 参数介绍
  • format
  • schema
  • load
  • table
  • option
  • 读取文件
  • json
  • csv
  • parquet和orc
  • 读取数据表
  • hive
  • jdbc



pyspark读取数据

参数介绍

format

DataFrameReader.format(source)

指定不同格式来读取文件,例如以下为指定json格式读取数据:

df = spark.read.format('json').load('python/test_support/sql/people.json')

针对常用几个文件格式,pyspark也可以直接通过对应的文件格式读取,如:

df = spark.read.json('../datas/data.json')

具体内容见后文。

schema

DataFrameReader.schema(schema)

指定读取的数据的schema列信息,有些数据文件中没有结构信息,需要手动指定。有些文件类型如json可以省略这一步,文件中自带schema信息,不过也需要视具体情况而定。

spark.read.schema("col0 INT, col1 DOUBLE")

load

DataFrameReader.load(path=None, format=None, schema=None, **options)

通过load指定文件路径,也可以在括号内通过key-value的格式指定不同的格式、schema等。示例如下:

df = spark.read.load('../datas/data.json', format="json")

table

DataFrameReader.table(tableName)

从指定数据表中读取数据,并返回一个dataframe,使用如下:

df = spark.read.table('db.table')
df.show(5, False)

可以从指定的hive数据表中读取数据。

option

DataFrameReader.option(key, value)
DataFrameReader.options(**options)

将参数以key-value的形式指定,这部分参数需要依据读取的文件格式来指定不同的参数,可参考源码。

读取文件

json

有以下这么三种方式读取json文件:

# json文件
df = spark.read.format('json').load('../datas/data.json')

df = spark.read.load('../datas/data.json', format="json")

df = spark.read.json('../datas/data.json')

这三种方法本质上都是一致的,都是读取单个json文件,可自行选择。

而如果我们要读取多个格式一致的json文件,可以采用以下方式:

df = spark.read.format('json').load(['../datas/data.json', '../datas/data2.json'])

df = spark.read.format('json').load('../output/data_json/')

当然啦,在实际工作中,我们很有可能碰到需要读取特定目录的文件,这时需要指定通配符来匹配对应的文件目录,例如:

spark.read.json("path/'{%s,%s}'%(day, dat_n)/")

有些情况下,我们并不需要将数据的所有列都读取出来,这时就可以通过指定schema来部分读取自己想要的列,同时也能指定数据的类型,如下所示:

df = spark.read.json('../datas/data.json')
df.printSchema()

df = spark.read.json('../datas/data.json', schema="name string, age int")
df.printSchema()

'''
root
 |-- age: long (nullable = true)
 |-- name: string (nullable = true)

root
 |-- name: string (nullable = true)
 |-- age: integer (nullable = true)
'''

结果显示,当不指定schema信息时,默认读取的name是string类型,age是long类型。而我们指定了age类型指定为int后,spark中其对应类型为integer。官方称这种格式为DDL-formatted string,也可以用spark自己的 pyspark.sql.types.StructType来指定schema。

上述都是在本地进行测试,如果是在实际工作中,如果数据是存储在HDFS文件系统中,读取的方式与上述一样,只不过路径是HDFS中的。

如果数据存储在S3中,我们的读取方式如下:

df = spark.read.json("s3://bucket/dir/")

csv

# csv文件
df = spark.read.format('csv').load('../datas/data.csv')

df = spark.read.csv('../datas/data.csv')

以上两种方式是比较简单的读取csv文件的方法,而打印结果时会发现,并没有将表头当作dataframe的schema信息:

+-----+----+
|  _c0| _c1|
+-----+----+
| name| age|
|alice|  18|
|  bob|  19|
+-----+----+

这个时候就需要指定参数了,如下所示,这样就可以将结果正确的读取到dataframe中了。

df = spark.read.option("header", "true").csv('../datas/data.csv')
df.show()
df.printSchema()

'''
+-----+----+
| name| age|
+-----+----+
|alice|  18|
|  bob|  19|
+-----+----+

root
 |-- name: string (nullable = true)
 |--  age: string (nullable = true)
'''

也可以通过指定schema来读取没有表头的csv文件数据:

df = spark.read.csv('../datas/data.csv', schema="name: string, age: string")

指定age为int时结果读取到的数据是null,因而用string读取数据,具体原因暂未知。不过在指定表头读取的数据结果来看,age也是string类型,或许与文件类型有关。

parquet和orc

这两种格式文件都是采用snappy压缩,snappy是一种高效的文件压缩方式,

读取文件示例如下所示,两种方式读取的数据均能将schema信息读取到。

# parquet
df = spark.read.parquet('../output/data_parquet/')
df.show()

# orc
df = spark.read.orc('../output/data_orc/')
df.show()

'''
+-----+---+
| name|age|
+-----+---+
|alice| 18|
|  bob| 19|
+-----+---+

+-----+---+
| name|age|
+-----+---+
|alice| 18|
|  bob| 19|
+-----+---+
'''

读取数据表

hive

可直接用spark的api接口读取:

df = spark.read.table('db.table')

不过这个方法比较单一,无法灵活的适应各种复杂的情况。复杂的情况可以使用sparksql进行数据表的读取:

df = spark.sql("select * from db.table where ...")

括号内就是普通的sql语句,可以指定选取的列,过滤的条件等。

jdbc

DataFrameReader.jdbc(url, table, column=None, lowerBound=None, upperBound=None, numPartitions=None, predicates=None, properties=None)

示例如下:

url = "jdbc:mysql://IPaddress/database"
driver = "com.mysql.jdbc.Driver"
user = "username"
password = "passwd"
database = "database"
table = "tablename"
df = spark.read.format("jdbc") \
    .options(url=url, driver=driver, user=user, password=password) \
    .load(dbtable="%s.%s" % (database, table))