web-dev-qa-db-ja.com

Project_Bank.csvはParquetファイルではありません。尾のマジックナンバーが予想される[80、65、82、49]が、見つかった[110、111、13、10]

だから私はカスタムスキーマを推測してcsvファイルをロードしようとしましたが、毎回次のエラーが発生します:

Project_Bank.csvは寄木細工のファイルではありません。テール[80、65、82、49]で予想されるマジックナンバーですが、[110、111、13、10]が見つかりました

これが私のプログラムと私のcsvファイルエントリの外観です。

年齢;仕事;結婚;教育;デフォルト;バランス;住宅;ローン;連絡先;日;月;期間;キャンペーン; pdays;前;結果; y58;管理;結婚;高等教育;いいえ; 2143;はい; no; unknown; 5; may; 261; 1; -1; 0; unknown; no 44; technician; single; Secondary; no; 29; yes; no; unknown; 5; may; 151; 1; -1; 0;不明;いいえ33;起業家;既婚;二次;いいえ; 2;はい;はい;不明; 5;可能性; 76; 1; -1; 0;不明;いいえ

私のコード:

$ spark-Shell --packages com.databricks:spark-csv_2.10:1.5.0

val sqlContext = new org.Apache.spark.sql.SQLContext(sc)
import org.Apache.spark.sql.types._
import org.Apache.spark.sql.SQLContext   
import sqlContext.implicits._    
import org.Apache.spark.sql.types.{StructType, StructField, StringType, IntegerType}

val bankSchema = StructType(Array(
  StructField("age", IntegerType, true),
  StructField("job", StringType, true),
  StructField("marital", StringType, true),
  StructField("education", StringType, true),
  StructField("default", StringType, true),
  StructField("balance", IntegerType, true),
  StructField("housing", StringType, true),
  StructField("loan", StringType, true),
  StructField("contact", StringType, true),
  StructField("day", IntegerType, true),
  StructField("month", StringType, true),
  StructField("duration", IntegerType, true),
  StructField("campaign", IntegerType, true),
  StructField("pdays", IntegerType, true),
  StructField("previous", IntegerType, true),
  StructField("poutcome", StringType, true),
  StructField("y", StringType, true)))


 val df = sqlContext.
  read.
  schema(bankSchema).
  option("header", "true").
  option("delimiter", ";").
  load("/user/amit.kudnaver_gmail/hadoop/project_bank/Project_Bank.csv").toDF()

  df.registerTempTable("people")
  df.printSchema()
  val distinctage = sqlContext.sql("select distinct age from people")

正しいスキーマをプッシュした後、ここでcsvファイルを操作できない理由に関する提案。よろしくお願いします。

ありがとうアミットK

6
amitk

ここでの問題は、データフレームが処理中にParquetファイルを予期することです。 CSVでデータを処理するため。ここであなたができること。

まず、データからヘッダー行を削除します。

58;management;married;tertiary;no;2143;yes;no;unknown;5;may;261;1;-1;0;unknown;no
44;technician;single;secondary;no;29;yes;no;unknown;5;may;151;1;-1;0;unknown;no
33;entrepreneur;married;secondary;no;2;yes;yes;unknown;5;may;76;1;-1;0;unknown;no

次に、データを読み取るために次のコードを記述します。

ケースクラスを作成する

case class BankSchema(age: Int, job: String, marital:String, education:String, default:String, balance:Int, housing:String, loan:String, contact:String, day:Int, month:String, duration:Int, campaign:Int, pdays:Int, previous:Int, poutcome:String, y:String)

HDFSからデータを読み取り、解析します

val bankData = sc.textFile("/user/myuser/Project_Bank.csv").map(_.split(";")).map(p => BankSchema(p(0).toInt, p(1), p(2),p(3),p(4), p(5).toInt, p(6), p(7), p(8), p(9).toInt, p(10), p(11).toInt, p(12).toInt, p(13).toInt, p(14).toInt, p(15), p(16))).toDF()

そして、テーブルを登録してクエリを実行します。

bankData.registerTempTable("bankData")
val distinctage = sqlContext.sql("select distinct age from bankData")

出力は次のようになります

+---+
|age|
+---+
| 33|
| 44|
| 58|
+---+
3

ここで予想されるファイル形式はcsvですが、エラーによりparquetファイル形式を探しています。

これは、ファイル形式を以下のように明示的に言及することで克服できます(共有された問題では欠落していました)。ファイル形式を指定しない場合、デフォルトでParquet形式が想定されるためです。

Javaコードバージョン(サンプル例))のとおり:

_Dataset<Row> resultData = session.read().format("csv")
                                            .option("sep", ",")
                                            .option("header", true)
                                            .option("mode", "DROPMALFORMED")
                                            .schema(definedSchema)
                                            .load(inputPath);
_

ここで、スキーマは、Java class (ie. POJO class)を使用するか、すでに述べたようにStructTypeを使用して定義できます。また、inputPathはinput csvファイルのパスです。

1
RPaul