CSVをSpark DataFrameとして読み取り、それに対して機械学習操作を実行しています。PythonシリアライゼーションEOFErrorが発生し続けます-理由は何ですか?これはメモリの問題である可能性があります-つまり、ファイルが利用可能RAM-を超えていますが、DataFrameのサイズを大幅に縮小しても、EOFエラーは発生しませんでした。
以下のおもちゃのコードとエラー。
_#set spark context
conf = SparkConf().setMaster("local").setAppName("MyApp")
sc = SparkContext(conf = conf)
sqlContext = SQLContext(sc)
#read in 500mb csv as DataFrame
df = sqlContext.read.format('com.databricks.spark.csv').options(header='true',
inferschema='true').load('myfile.csv')
#get dataframe into machine learning format
r_formula = RFormula(formula = "outcome ~ .")
mldf = r_formula.fit(df).transform(df)
#fit random forest model
rf = RandomForestClassifier(numTrees = 3, maxDepth = 2)
model = rf.fit(mldf)
result = model.transform(mldf).head()
_
単一のノードで_spark-submit
_を使用して上記のコードを実行すると、モデルをフィットする前にDataFrameのサイズが縮小された場合でも、次のエラーが繰り返しスローされます(例:tinydf = df.sample(False, 0.00001)
:
_Traceback (most recent call last):
File "/home/hduser/spark1.6/python/lib/pyspark.Zip/pyspark/daemon.py", line 157,
in manager
File "/home/hduser/spark1.6/python/lib/pyspark.Zip/pyspark/daemon.py", line 61,
in worker
File "/home/hduser/spark1.6/python/lib/pyspark.Zip/pyspark/worker.py", line 136,
in main if read_int(infile) == SpecialLengths.END_OF_STREAM:
File "/home/hduser/spark1.6/python/lib/pyspark.Zip/pyspark/serializers.py", line 545,
in read_int
raise EOFError
EOFError
_
エラーはpySpark read_int関数で発生するようです。 spark site のコードは次のとおりです。
def read_int(stream):
length = stream.read(4)
if not length:
raise EOFError
return struct.unpack("!i", length)[0]
これは、ストリームから4バイトを読み取るときに、0バイトが読み取られると、EOFエラーが発生することを意味します。python docs is here 。
コードのどこでEOErrorが発生しているか確認しましたか?
私の推測では、ファイルを実際に読み取ろうとしているのはコード内の唯一の場所なので、dfを定義しようとすると、それが来ると考えられます。
df = sqlContext.read.format('com.databricks.spark.csv').options(header='true',
inferschema='true').load('myfile.csv')
この行の後のすべての時点で、コードはファイル自体ではなく変数df
を処理しているため、この行がエラーを生成している可能性があります。
これが当てはまるかどうかをテストする簡単な方法は、コードの残りの部分をコメント化するか、上記の行の直後にこのような行を配置することです。
print(len(df))
もう1つの方法は、次のようにtry
ループを使用することです。
try:
df = sqlContext.read.format('com.databricks.spark.csv').options(header='true',
inferschema='true').load('myfile.csv')
except:
print('Didn't load file into df!')
その行がEOFErrorを生成している行であることが判明した場合、最初にデータフレームを取得することはないため、データフレームを減らしても違いはありません。
それがエラーを生成する行である場合、2つの可能性が思い浮かびます:
1)コードが以前に.csvファイルの一方または両方を呼び出しており、この行の前に閉じていない。その場合は、コードの上で閉じるだけです。
2).csvファイル自体に問題があります。このコードの外でそれらをロードしてみて、csv.readerのようなものを使用して、最初にそれらを適切にメモリに入れ、期待どおりに操作できるかどうかを確認してください。