私はcsvデータを作成してPandas read_csvを使用し、すべての列を文字列として強制します。次に、Sparkからデータフレームを作成しようとするとPandas dataframe、以下のエラーメッセージが表示されます。
from pyspark import SparkContext
from pyspark.sql import SQLContext
from pyspark.sql.types import *
z=pd.read_csv("mydata.csv", dtype=str)
z.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 74044003 entries, 0 to 74044002
Data columns (total 12 columns):
primaryid object
event_dt object
age object
age_cod object
age_grp object
sex object
occr_country object
drug_seq object
drugname object
route object
outc_cod object
pt object
q= sqlContext.createDataFrame(z)
File "<stdin>", line 1, in <module>
File "/usr/hdp/2.4.2.0-258/spark/python/pyspark/sql/context.py", line 425, in createDataFrame
rdd, schema = self._createFromLocal(data, schema)
File "/usr/hdp/2.4.2.0-258/spark/python/pyspark/sql/context.py", line 341, in _createFromLocal
struct = self._inferSchemaFromList(data)
File "/usr/hdp/2.4.2.0-258/spark/python/pyspark/sql/context.py", line 241, in _inferSchemaFromList
schema = reduce(_merge_type, map(_infer_schema, data))
File "/usr/hdp/2.4.2.0-258/spark/python/pyspark/sql/types.py", line 862, in _merge_type
for f in a.fields]
File "/usr/hdp/2.4.2.0-258/spark/python/pyspark/sql/types.py", line 856, in _merge_type
raise TypeError("Can not merge type %s and %s" % (type(a), type(b)))
TypeError: Can not merge type <class 'pyspark.sql.types.DoubleType'> and <class 'pyspark.sql.types.StringType'>
例を示します。公開データをダウンロードしてpandasデータフレームを作成していますが、sparkが作成しませんsparkからデータフレームをpandasデータフレーム。
import pandas as pd
from pyspark import SparkContext
from pyspark.sql import SQLContext
from pyspark.sql.types import *
url ="http://www.nber.org/fda/faers/2016/demo2016q1.csv.Zip"
import requests, zipfile, StringIO
r = requests.get(url, stream=True)
z = zipfile.ZipFile(StringIO.StringIO(r.content))
z.extractall()
z=pd.read_csv("demo2016q1.csv") # creates pandas dataframe
Data_Frame = sqlContext.createDataFrame(z)
長い話は、スキーマの推論に依存しません。それは一般的に高価でトリッキーです。特に、データの一部の列(たとえばevent_dt_num
)には、Pandasを押して混合型として表現するための欠落値があります(欠落していない文字列、欠落値はNaN)。
疑問がある場合は、すべてのデータを文字列として読み取り、後でキャストすることをお勧めします。コードブックにアクセスできる場合は、常にスキーマを提供して問題を回避し、全体的なコストを削減する必要があります。
最後に、ドライバーからデータを渡すことはアンチパターンです。 csv
形式(Spark 2.0.0+)またはspark-csv
ライブラリ(Spark 1.6以下)を使用して、このデータを直接読み取ることができるはずです。
df = (spark.read.format("csv").options(header="true")
.load("/path/tp/demo2016q1.csv"))
## root
## |-- primaryid: string (nullable = true)
## |-- caseid: string (nullable = true)
## |-- caseversion: string (nullable = true)
## |-- i_f_code: string (nullable = true)
## |-- i_f_code_num: string (nullable = true)
## ...
## |-- to_mfr: string (nullable = true)
## |-- occp_cod: string (nullable = true)
## |-- reporter_country: string (nullable = true)
## |-- occr_country: string (nullable = true)
## |-- occp_cod_num: string (nullable = true)
この特定のケースでは、inferSchema="true"
オプションの追加も機能するはずですが、それを回避することをお勧めします。次のようにスキーマを提供することもできます。
from pyspark.sql.types import StructType
schema = StructType.fromJson({'fields': [{'metadata': {},
'name': 'primaryid',
'nullable': True,
'type': 'integer'},
{'metadata': {}, 'name': 'caseid', 'nullable': True, 'type': 'integer'},
{'metadata': {}, 'name': 'caseversion', 'nullable': True, 'type': 'integer'},
{'metadata': {}, 'name': 'i_f_code', 'nullable': True, 'type': 'string'},
{'metadata': {},
'name': 'i_f_code_num',
'nullable': True,
'type': 'integer'},
{'metadata': {}, 'name': 'event_dt', 'nullable': True, 'type': 'integer'},
{'metadata': {}, 'name': 'event_dt_num', 'nullable': True, 'type': 'string'},
{'metadata': {}, 'name': 'mfr_dt', 'nullable': True, 'type': 'integer'},
{'metadata': {}, 'name': 'mfr_dt_num', 'nullable': True, 'type': 'string'},
{'metadata': {}, 'name': 'init_fda_dt', 'nullable': True, 'type': 'integer'},
{'metadata': {},
'name': 'init_fda_dt_num',
'nullable': True,
'type': 'string'},
{'metadata': {}, 'name': 'fda_dt', 'nullable': True, 'type': 'integer'},
{'metadata': {}, 'name': 'fda_dt_num', 'nullable': True, 'type': 'string'},
{'metadata': {}, 'name': 'rept_cod', 'nullable': True, 'type': 'string'},
{'metadata': {},
'name': 'rept_cod_num',
'nullable': True,
'type': 'integer'},
{'metadata': {}, 'name': 'auth_num', 'nullable': True, 'type': 'string'},
{'metadata': {}, 'name': 'mfr_num', 'nullable': True, 'type': 'string'},
{'metadata': {}, 'name': 'mfr_sndr', 'nullable': True, 'type': 'string'},
{'metadata': {}, 'name': 'lit_ref', 'nullable': True, 'type': 'string'},
{'metadata': {}, 'name': 'age', 'nullable': True, 'type': 'double'},
{'metadata': {}, 'name': 'age_cod', 'nullable': True, 'type': 'string'},
{'metadata': {}, 'name': 'age_grp', 'nullable': True, 'type': 'string'},
{'metadata': {}, 'name': 'age_grp_num', 'nullable': True, 'type': 'string'},
{'metadata': {}, 'name': 'sex', 'nullable': True, 'type': 'string'},
{'metadata': {}, 'name': 'e_sub', 'nullable': True, 'type': 'string'},
{'metadata': {}, 'name': 'wt', 'nullable': True, 'type': 'double'},
{'metadata': {}, 'name': 'wt_cod', 'nullable': True, 'type': 'string'},
{'metadata': {}, 'name': 'rept_dt', 'nullable': True, 'type': 'integer'},
{'metadata': {}, 'name': 'rept_dt_num', 'nullable': True, 'type': 'string'},
{'metadata': {}, 'name': 'to_mfr', 'nullable': True, 'type': 'string'},
{'metadata': {}, 'name': 'occp_cod', 'nullable': True, 'type': 'string'},
{'metadata': {},
'name': 'reporter_country',
'nullable': True,
'type': 'string'},
{'metadata': {}, 'name': 'occr_country', 'nullable': True, 'type': 'string'},
{'metadata': {},
'name': 'occp_cod_num',
'nullable': True,
'type': 'integer'}],
'type': 'struct'})
読者に直接:
(spark.read.schema(schema).format("csv").options(header="true")
.load("/path/to/demo2016q1.csv"))