2016-06-09 5 views
1

Ich habe eine Spalte voller Arrays mit Split-HTTP-Anfragen. Ich habe sie auf eine von zwei Möglichkeiten durchgesickert:Wie wird die Scheibe eines Arrays in Spark SQL (Dataframes) gezogen?

|[, courses, 27381...| 
|[, courses, 27547...| 
|[, api, v1, cours...| 
|[, api, v1, cours...| 
|[, api, v1, cours...| 
|[, api, v1, cours...| 
|[, api, v1, cours...| 
|[, api, v1, cours...| 
|[, api, v1, cours...| 
|[, api, v1, cours...| 
|[, courses, 33287...| 
|[, courses, 24024...| 

In beiden Array-Typen, von ‚Kurse‘ weiter die gleichen Daten und die Struktur ist.

Ich möchte die Scheibe des Arrays mit einer case Anweisung, wo, wenn das erste Element des Arrays ist "API", dann nehmen Sie Elemente 3 -> Ende des Arrays. Ich habe versucht, mit Python Slice-Syntax [3:] und normalen PostgreSQL Syntax [3, n], wobei n ist die Länge des Arrays. Wenn es nicht "api" ist, dann nimm einfach den gegebenen Wert.

Mein ideales Endergebnis wäre ein Array, in dem jede Zeile die gleiche Struktur hat, mit Kursen im ersten Index für einfacheres Parsen von diesem Punkt an.

+0

der angegebene Wert == ganzes Array? –

+0

gegebenen Wert wäre nur die Zeile. Wenn zum Beispiel das Array '['Kurse', 'etc ...', ...]' ist, belassen Sie den Wert als, aber wenn es '['api', 'v1', 'Kurse' ist , 'etwas ...'] 'setze dann den Wert auf' ['Kurse', 'etwas', ...] ' – flybonzai

+0

Ich denke, ein udf würde hier nützlich sein. siehe https://ragrawal.wordpress.com/2015/10/02/spark-custom-udf-example/ –

Antwort

1

Es ist sehr einfach, definieren Sie einfach , Sie haben eine very similar question previously gemacht, so dass ich nicht die genaue Antwort posten werde, damit Sie denken und lernen (zu Ihrem Besten).

df = sc.parallelize([(["ab", "bs", "xd"],), (["bc", "cd", ":x"],)]).toDF() 

getUDF = udf(lambda x, y: x[1:] if x[y] == "ab" else x) 

df.select(getUDF(col("_1"), lit(0))).show() 

+------------------------+ 
|PythonUDF#<lambda>(_1,0)| 
+------------------------+ 
|    [bs, xd]| 
|   [bc, cd, :x]| 
+------------------------+ 
+0

Also, wenn ich in eine literale untere und obere Grenze in die 'UDF' übergeben, dann kann ich es einfach als zurückgeben ein solches 'Array [lbound: ubound]' und setze meinen 'UDF' Rückgabewert auf' ArrayType (StringType()) '? – flybonzai

+1

Typ wird von der 'UDF' abgeleitet, aber ja für den Rest. –

+0

Manchmal möchten Sie UDF vermeiden, um Ihren Code zu optimieren. [Hier] (http://stackoverflow.com/questions/40134975/selecting-a-range-of-elements-in-an-array-spark-sql/40147113#40147113) ist ein Beispiel in Scala. Aber die Logik sollte hier sehr ähnlich sein, indem man eine 'Slice'-Funktion' (Int, Int) => Column' definiert und 'when' und' sonst' von der 'Column'-API verwendet. – Wilmerton