Боковой вид взорвать странное поведение - PullRequest
2 голосов
/ 05 ноября 2019

Я объединяю два столбца массива и преобразовываю их обратно в массив. Теперь, когда я применяю взрыв, ничего не происходит. Использование Spark 2.3. Здесь что-нибудь странное?

df = spark.createDataFrame([(1,25,['A','B','B','C'],['A','B','B','C']),(1,20,['A','A','B','C'],['A','B','B','C']),(1,20,['A','C','B','C'],['A','B','B','C']),(2,26,['X','Y','Z','C'],['A','B','B','C'])],['id','age','one','two'])
+---+---+------------+------------+
| id|age|         one|         two|
+---+---+------------+------------+
|  1| 25|[A, B, B, C]|[A, B, B, C]|
|  1| 20|[A, A, B, C]|[A, B, B, C]|
|  1| 20|[A, C, B, C]|[A, B, B, C]|
|  2| 26|[X, Y, Z, C]|[A, B, B, C]|
+---+---+------------+------------+

>>> df.createOrReplaceTempView('df')
>>> df2 = spark.sql('''select id,age, array(concat_ws(',', one, two)) as three from df''')
>>> df2.show()
+---+---+-----------------+
| id|age|            three|
+---+---+-----------------+
|  1| 25|[A,B,B,C,A,B,B,C]|
|  1| 20|[A,A,B,C,A,B,B,C]|
|  1| 20|[A,C,B,C,A,B,B,C]|
|  2| 26|[X,Y,Z,C,A,B,B,C]|
+---+---+-----------------+

>>> df2.createOrReplaceTempView('df2')
>>> spark.sql('''select id, age, four from df2 lateral view explode(three) tbl as four''').show() //not exploding
+---+---+---------------+
| id|age|           four|
+---+---+---------------+
|  1| 25|A,B,B,C,A,B,B,C|
|  1| 20|A,A,B,C,A,B,B,C|
|  1| 20|A,C,B,C,A,B,B,C|
|  2| 26|X,Y,Z,C,A,B,B,C|
+---+---+---------------+

Обратите внимание, что я могу заставить его работать

>>> df2 = spark.sql('''select id,age, split(concat_ws(',', one, two),',') as three from df''')

Но просто удивляюсь, почему первый подход не работает.

Ответы [ 2 ]

1 голос
/ 05 ноября 2019

concat_ws создает столбец из одной строки, а не массив:

df.select(F.size(df.one)).show()
df2.select(F.size(df2.three)).show()

Вывод:

+---------+
|size(one)|
+---------+
|        4|
|        4|
|        4|
|        4|
+---------+
+-----------+
|size(three)|
+-----------+
|          1|
|          1|
|          1|
|          1|
+-----------+

Это означает, что в вашем массиве есть только один элемент:

df2.select(df2.three.getItem(0)).show()
df2.select(df2.three.getItem(1)).show()
df2.printSchema()

Выход:

+---------------+
|       three[0]|
+---------------+
|A,B,B,C,A,B,B,C|
|A,A,B,C,A,B,B,C|
|A,C,B,C,A,B,B,C|
|X,Y,Z,C,A,B,B,C|
+---------------+

+--------+
|three[1]|
+--------+
|    null|
|    null|
|    null|
|    null|
+--------+

root
 |-- id: long (nullable = true)
 |-- age: long (nullable = true)
 |-- three: array (nullable = false)
 |    |-- element: string (containsNull = false)

То, что вы на самом деле должны использовать, это concat при искре> = 2,4:

df3 = spark.sql('''select id,age, concat(one, two) as three from df''')
df3.show(truncate=False)
df3.printSchema()
df3.select(df3.three.getItem(0)).show()
df3.select(df3.three.getItem(1)).show()

Выход:

+---+---+------------------------+
|id |age|three                   |
+---+---+------------------------+
|1  |25 |[A, B, B, C, A, B, B, C]|
|1  |20 |[A, A, B, C, A, B, B, C]|
|1  |20 |[A, C, B, C, A, B, B, C]|
|2  |26 |[X, Y, Z, C, A, B, B, C]|
+---+---+------------------------+

root
 |-- id: long (nullable = true)
 |-- age: long (nullable = true)
 |-- three: array (nullable = true)
 |    |-- element: string (containsNull = true)

+--------+
|three[0]|
+--------+
|       A|
|       A|
|       A|
|       X|
+--------+

+--------+
|three[1]|
+--------+
|       B|
|       A|
|       C|
|       Y|
+--------+

Для объединения двух массивов с искрой <2.4 требуется udf (проверьте этот <a href="http://(https://stackoverflow.com/a/37284548/6664872)" rel="nofollow noreferrer"> ответ для примера).

0 голосов
/ 05 ноября 2019

Пример способа сделать это с использованием UDF:

arraycat = F.udf(lambda x,y : x + y, ArrayType(StringType()))
df = df.withColumn("combined", arraycat("one", "two"))
df = df.withColumn("combined", F.explode("combined"))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...