DataFrameReader.format(source)
指定不同格式来读取文件,例如以下为指定json格式读取数据:
df = spark.read.format('json').load('python/test_support/sql/people.json')
针对常用几个文件格式,pyspark也可以直接通过对应的文件格式读取,如:
df = spark.read.json('../datas/data.json')
具体内容见后文。
DataFrameReader.schema(schema)
指定读取的数据的schema列信息,有些数据文件中没有结构信息,需要手动指定。有些文件类型如json可以省略这一步,文件中自带schema信息,不过也需要视具体情况而定。
spark.read.schema("col0 INT, col1 DOUBLE")
DataFrameReader.load(path=None, format=None, schema=None, **options)
通过load指定文件路径,也可以在括号内通过key-value的格式指定不同的格式、schema等。示例如下:
df = spark.read.load('../datas/data.json', format="json")
DataFrameReader.table(tableName)
从指定数据表中读取数据,并返回一个dataframe,使用如下:
df = spark.read.table('db.table')
df.show(5, False)
可以从指定的hive数据表中读取数据。
DataFrameReader.option(key, value)
DataFrameReader.options(**options)
将参数以key-value的形式指定,这部分参数需要依据读取的文件格式来指定不同的参数,可参考源码。
参考链接:spark.read.option
有以下这么三种方式读取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文件
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文件介绍参考:parquet与orc
这两种格式文件都是采用snappy压缩,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|
+-----+---+
'''
可直接用spark的api接口读取:
df = spark.read.table('db.table')
不过这个方法比较单一,无法灵活的适应各种复杂的情况。复杂的情况可以使用sparksql进行数据表的读取:
df = spark.sql("select * from db.table where ...")
括号内就是普通的sql语句,可以指定选取的列,过滤的条件等。
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))