0

Im Folgenden ist der Inhalt meiner CSV-Datei:Funken keine Spalten mit Nullwerten in der ersten Reihe lesen

A1,B1,C1 
A2,B2,C2,D1 
A3,B3,C3,D2,E1 
A4,B4,C4,D3 
A5,B5,C5,,E2 

So gibt es 5 Spalten, aber nur drei Werte in der ersten Reihe.

Ich las es mit dem folgenden Befehl:

val csvDF : DataFrame = spark.read 
.option("header", "false") 
.option("delimiter", ",") 
.option("inferSchema", "false") 
.csv("file.csv") 

Und nach ist das, was ich csvDF.show()

+---+---+---+ 
|_c0|_c1|_c2| 
+---+---+---+ 
| A1| B1| C1| 
| A2| B2| C2| 
| A3| B3| C3| 
| A4| B4| C4| 
| A5| B5| C5| 
+---+---+---+ 

Wie kann ich alle Daten in allen Spalten gelesen werden verwendet?

+0

ist es möglich, alle 5 Spalten jeder Zeile hinzufügen? Wie für Zeile 1 anstelle von A1, B1, C1 ist es A1, B1, C1 ,, – Tom

+0

Das ist nur eine Problemumgehung und wird nicht funktionieren, wenn der CSV von jemand anderem verwaltet wird. –

+0

Geben Sie einfach Schema manuell –

Antwort

0

Sie können es als Datensatz mit nur einer Spalte lesen (zum Beispiel durch ein anderes Trennzeichen verwenden):

var df = spark.read.format("csv").option("delimiter",";").load("test.csv") 
df.show() 

+--------------+ 
|   _c0| 
+--------------+ 
|  A1,B1,C1| 
| A2,B2,C2,D1| 
|A3,B3,C3,D2,E1| 
| A4,B4,C4,D3| 
| A5,B5,C5,,E2| 
+--------------+ 

Dann können Sie this answer verwenden, um manuell Ihre Spalte in fünf geteilt wird diese null addieren Werte, wenn das Element nicht existiert:

var csvDF = df.withColumn("_tmp",split($"_c0",",")).select(
    $"_tmp".getItem(0).as("col1"), 
    $"_tmp".getItem(1).as("col2"), 
    $"_tmp".getItem(2).as("col3"), 
    $"_tmp".getItem(3).as("col4"), 
    $"_tmp".getItem(4).as("col5") 
) 
csvDF.show() 

+----+----+----+----+----+ 
|col1|col2|col3|col4|col5| 
+----+----+----+----+----+ 
| A1| B1| C1|null|null| 
| A2| B2| C2| D1|null| 
| A3| B3| C3| D2| E1| 
| A4| B4| C4| D3|null| 
| A5| B5| C5| | E2| 
+----+----+----+----+----+ 
1

Grundsätzlich Ihre cSV-Datei nicht ordnungsgemäß im Sinne formatiert ist, dass es nicht eine gleiche Anzahl von Spalten in jeder Zeile hat, die, wenn Sie wollen, erforderlich ist, um lesen Sie es mit spark.read.csv. Sie können es jedoch stattdessen mit spark.read.textFile lesen und dann jede Zeile analysieren.

Wie ich es verstehe, wissen Sie nicht die Anzahl der Spalten im Voraus, so dass Sie möchten, dass Ihr Code eine beliebige Anzahl von Spalten behandelt. Dazu müssen Sie die maximale Anzahl von Spalten in Ihrem Datensatz festlegen, sodass Sie zwei Durchläufe über Ihren Datensatz benötigen.

val data = spark.read.textFile("file.csv").rdd 

val rdd = data.map(s => (s, s.split(",").length)).cache 
val maxColumns = rdd.map(_._2).max() 

val x = rdd 
    .map(row => { 
    val rowData = row._1.split(",") 
    val extraColumns = Array.ofDim[String](maxColumns - rowData.length) 
    Row((rowData ++ extraColumns).toList:_*) 
    }) 

Hope that :)

0

Wenn die Spalte dataTypes und die Anzahl der Spalten sind bekannt hilft:

Für dieses spezielle Problem, würde ich mit RDDs statt Datenrahmen oder Datensammlungen, wie dies eigentlich gehen dann können Sie schema definieren und die schema beim Lesen der csv Datei als dataframe anwenden. Im Folgenden werde ich alle fünf Spalten als stringType

val schema = StructType(Seq(
    StructField("col1", StringType, true), 
    StructField("col2", StringType, true), 
    StructField("col3", StringType, true), 
    StructField("col4", StringType, true), 
    StructField("col5", StringType, true))) 

val csvDF : DataFrame = sqlContext.read 
    .option("header", "false") 
    .option("delimiter", ",") 
    .option("inferSchema", "false") 
    .schema(schema) 
    .csv("file.csv") 

definiert haben, sollten Sie dataframe als

bekommen sein
+----+----+----+----+----+ 
|col1|col2|col3|col4|col5| 
+----+----+----+----+----+ 
|A1 |B1 |C1 |null|null| 
|A2 |B2 |C2 |D1 |null| 
|A3 |B3 |C3 |D2 |E1 | 
|A4 |B4 |C4 |D3 |null| 
|A5 |B5 |C5 |null|E2 | 
+----+----+----+----+----+