您好,登錄后才能下訂單哦!
如何在pyspark中創(chuàng)建DataFrame?很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
為了便于操作,使用pyspark時(shí)我們通常將數(shù)據(jù)轉(zhuǎn)為DataFrame的形式來完成清洗和分析動(dòng)作。
在上一篇pyspark基本操作有提到RDD也是spark中的操作的分布式數(shù)據(jù)對(duì)象。
這里簡(jiǎn)單看一下RDD和DataFrame的類型。
print(type(rdd)) # <class 'pyspark.rdd.RDD'> print(type(df)) # <class 'pyspark.sql.dataframe.DataFrame'>
翻閱了一下源碼的定義,可以看到他們之間并沒有繼承關(guān)系。
class RDD(object): """ A Resilient Distributed Dataset (RDD), the basic abstraction in Spark. Represents an immutable, partitioned collection of elements that can be operated on in parallel. """
class DataFrame(object): """A distributed collection of data grouped into named columns. A :class:`DataFrame` is equivalent to a relational table in Spark SQL, and can be created using various functions in :class:`SparkSession`:: ... """
RDD是一種彈性分布式數(shù)據(jù)集,Spark中的基本抽象。表示一種不可變的、分區(qū)儲(chǔ)存的集合,可以進(jìn)行并行操作。
DataFrame是一種以列對(duì)數(shù)據(jù)進(jìn)行分組表達(dá)的分布式集合, DataFrame等同于Spark SQL中的關(guān)系表。相同點(diǎn)是,他們都是為了支持分布式計(jì)算而設(shè)計(jì)。
但是RDD只是元素的集合,但是DataFrame以列進(jìn)行分組,類似于MySQL的表或pandas中的DataFrame。
實(shí)際工作中,我們用的更多的還是DataFrame。
嘗試第一種情形發(fā)現(xiàn),僅僅傳入二元組,結(jié)果是沒有列名稱的。
于是我們嘗試第二種,同時(shí)傳入二元組和列名稱。
a = [('Alice', 1)] output = spark.createDataFrame(a).collect() print(output) # [Row(_1='Alice', _2=1)] output = spark.createDataFrame(a, ['name', 'age']).collect() print(output) # [Row(name='Alice', age=1)]
這里collect()是按行展示數(shù)據(jù)表,也可以使用show()對(duì)數(shù)據(jù)表進(jìn)行展示。
spark.createDataFrame(a).show() # +-----+---+ # | _1| _2| # +-----+---+ # |Alice| 1| # +-----+---+ spark.createDataFrame(a, ['name', 'age']).show() # +-----+---+ # | name|age| # +-----+---+ # |Alice| 1| # +-----+---+
d = [{'name': 'Alice', 'age': 1}] output = spark.createDataFrame(d).collect() print(output) # [Row(age=1, name='Alice')]
a = [('Alice', 1)] rdd = sc.parallelize(a) output = spark.createDataFrame(rdd).collect() print(output) output = spark.createDataFrame(rdd, ["name", "age"]).collect() print(output) # [Row(_1='Alice', _2=1)] # [Row(name='Alice', age=1)]
from pyspark.sql import Row a = [('Alice', 1)] rdd = sc.parallelize(a) Person = Row("name", "age") person = rdd.map(lambda r: Person(*r)) output = spark.createDataFrame(person).collect() print(output) # [Row(name='Alice', age=1)]
from pyspark.sql.types import * a = [('Alice', 1)] rdd = sc.parallelize(a) schema = StructType( [ StructField("name", StringType(), True), StructField("age", IntegerType(), True) ] ) output = spark.createDataFrame(rdd, schema).collect() print(output) # [Row(name='Alice', age=1)]
df.toPandas()可以把pyspark DataFrame轉(zhuǎn)換為pandas DataFrame。
df = spark.createDataFrame(rdd, ['name', 'age']) print(df) # DataFrame[name: string, age: bigint] print(type(df.toPandas())) # <class 'pandas.core.frame.DataFrame'> # 傳入pandas DataFrame output = spark.createDataFrame(df.toPandas()).collect() print(output) # [Row(name='Alice', age=1)]
output = spark.range(1, 7, 2).collect() print(output) # [Row(id=1), Row(id=3), Row(id=5)] output = spark.range(3).collect() print(output) # [Row(id=0), Row(id=1), Row(id=2)]
通過臨時(shí)表得到DataFrame
spark.registerDataFrameAsTable(df, "table1") df2 = spark.table("table1") b = df.collect() == df2.collect() print(b) # True
在createDataFrame中可以指定列類型,只保留滿足數(shù)據(jù)類型的列,如果沒有滿足的列,會(huì)拋出錯(cuò)誤。
a = [('Alice', 1)] rdd = sc.parallelize(a) # 指定類型于預(yù)期數(shù)據(jù)對(duì)應(yīng)時(shí),正常創(chuàng)建 output = spark.createDataFrame(rdd, "a: string, b: int").collect() print(output) # [Row(a='Alice', b=1)] rdd = rdd.map(lambda row: row[1]) print(rdd) # PythonRDD[7] at RDD at PythonRDD.scala:53 # 只有int類型對(duì)應(yīng)上,過濾掉其他列。 output = spark.createDataFrame(rdd, "int").collect() print(output) # [Row(value=1)] # 沒有列能對(duì)應(yīng)上,會(huì)拋出錯(cuò)誤。 output = spark.createDataFrame(rdd, "boolean").collect() # TypeError: field value: BooleanType can not accept object 1 in type <class 'int'>
spark.registerDataFrameAsTable(df, "table1") spark.dropTempTable("table1")
print(spark.getConf("spark.sql.shuffle.partitions")) # 200 print(spark.getConf("spark.sql.shuffle.partitions", u"10")) # 10 print(spark.setConf("spark.sql.shuffle.partitions", u"50")) # None print(spark.getConf("spark.sql.shuffle.partitions", u"10")) # 50
spark.registerFunction("stringLengthString", lambda x: len(x)) output = spark.sql("SELECT stringLengthString('test')").collect() print(output) # [Row(stringLengthString(test)='4')] spark.registerFunction("stringLengthString", lambda x: len(x), IntegerType()) output = spark.sql("SELECT stringLengthString('test')").collect() print(output) # [Row(stringLengthString(test)=4)] spark.udf.register("stringLengthInt", lambda x: len(x), IntegerType()) output = spark.sql("SELECT stringLengthInt('test')").collect() print(output) # [Row(stringLengthInt(test)=4)]
可以查看所有臨時(shí)表名稱和對(duì)象。
spark.registerDataFrameAsTable(df, "table1") print(spark.tableNames()) # ['table1'] print(spark.tables()) # DataFrame[database: string, tableName: string, isTemporary: boolean] print("table1" in spark.tableNames()) # True print("table1" in spark.tableNames("default")) # True spark.registerDataFrameAsTable(df, "table1") df2 = spark.tables() df2.filter("tableName = 'table1'").first() print(df2) # DataFrame[database: string, tableName: string, isTemporary: boolean]
前提是需要下載jar包。
Mysql-connector-java.jar
from pyspark import SparkContext from pyspark.sql import SQLContext import pyspark.sql.functions as F sc = SparkContext("local", appName="mysqltest") sqlContext = SQLContext(sc) df = sqlContext.read.format("jdbc").options( url="jdbc:mysql://localhost:3306/mydata?user=root&password=mysql&" "useUnicode=true&characterEncoding=utf-8&useJDBCCompliantTimezoneShift=true&" "useLegacyDatetimeCode=false&serverTimezone=UTC ", dbtable="detail_data").load() df.show(n=5) sc.stop()
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。