Операция Spark dataframe над списком возвращает [Ljava.яз..Объект;@]
У меня есть фрейм данных pyspark, где я сгруппировал данные в список с помощью collect_list.
from pyspark.sql.functions import udf, collect_list
from itertools import combinations, chain
#Create Dataframe
df = spark.createDataFrame( [(1,'a'), (1,'b'), (2,'c')] , ["id", "colA"])
df.show()
>>>
+---+----+
| id|colA|
+---+----+
| 1| a|
| 1| b|
| 2| c|
+---+----+
#Group by and collect to list
df = df.groupBy(df.id).agg(collect_list("colA").alias("colAlist"))
df.show()
>>>
+---+--------+
| id|colAList|
+---+--------+
| 1| [a, b]|
| 2| [c]|
+---+--------+
Затем я использую функцию, чтобы найти все комбинации элементов списка в новый список
allsubsets = lambda l: list(chain(*[combinations(l , n) for n in range(1,len(l)+1)]))
df = df.withColumn('colAsubsets',udf(allsubsets)(df['colAList']))
Поэтому я бы выделил что-то вроде
+---+--------------------+
| id| colAsubsets |
+---+--------------------+
| 1| [[a], [b], [a,b]] |
| 2| [[b]] |
+---+--------------------+
Но я получаю:
df.show()
>>>
+---+--------+-----------------------------------------------------------------------------------------+
|id |colAList|colAsubsets |
+---+--------+-----------------------------------------------------------------------------------------+
|1 |[a, b] |[[Ljava.lang.Object;@75e2d657, [Ljava.lang.Object;@7f662637, [Ljava.lang.Object;@b572639]|
|2 |[c] |[[Ljava.lang.Object;@26f67148] |
+---+--------+-----------------------------------------------------------------------------------------+
Есть идеи, что делать? А потом, может быть, как расплющить список на разные строки?
2 ответа:
Все, что вам нужно сделать, это извлечь элементы из объектов, созданных
chain
иcombinations
уплощенным способомИтак, изменение
allsubsets = lambda l: list(chain(*[combinations(l , n) for n in range(1,len(l)+1)]))
К следующему
allsubsets = lambda l: [[z for z in y] for y in chain(*[combinations(l , n) for n in range(1,len(l)+1)])]
Должен дать вам
+---+---------+------------------+ |id |colA_list|colAsubsets | +---+---------+------------------+ |1 |[a, b] |[[a], [b], [a, b]]| |2 |[c] |[[c]] | +---+---------+------------------+
Я надеюсь, что ответ будет полезным
Улучшение ответа @RameshMaharjan, чтобы сгладить список в разные строки:
Вы должны использовать explode на массиве. Вы должны перед этим указать тип вашего udf, чтобы он не возвращал StringType.
from pyspark.sql.functions import explode from pyspark.sql.types import ArrayType, StringType allsubsets = lambda l: [[z for z in y] for y in chain(*[combinations(l , n) for n in range(1,len(l)+1)])] df = df.withColumn('colAsubsets', udf(allsubsets, ArrayType(ArrayType(StringType())))(df['colAList'])) df = df.select('id', explode('colAsubsets'))
Результат:
+---+------+ | id| col| +---+------+ | 1| [a]| | 1| [b]| | 1|[a, b]| | 2| [c]| +---+------+