Как перевести строку в dict с помощью pysparkSQL - PullRequest
0 голосов
/ 09 мая 2018

В pysparkSQL у меня есть DataFrame с именем bmd2, например:

DataFrame[genres: string, id: int, tagline: string, title: string, vote_average: double, vote_count: int]

И данные bmd2['genres'] выглядят так:

bmd2.select('genres').show():
+--------------------+
|              genres|
+--------------------+
|[{'id': 16, 'name...|
|[{'id': 12, 'name...|
|[{'id': 10749, 'n...|
|[{'id': 35, 'name...|
|[{'id': 35, 'name...|
|[{'id': 28, 'name...|
|[{'id': 35, 'name...|
|[{'id': 28, 'name...|
|[{'id': 28, 'name...|
|[{'id': 12, 'name...|
|[{'id': 35, 'name...|
|[{'id': 35, 'name...|
|[{'id': 10751, 'n...|
|[{'id': 36, 'name...|
|[{'id': 28, 'name...|
|[{'id': 18, 'name...|
|[{'id': 18, 'name...|
|[{'id': 80, 'name...|
|[{'id': 80, 'name...|
|[{'id': 28, 'name...|
+--------------------+
only showing top 20 rows

Тип данных в столбце 'genres' является строковым, но они могут быть перенесены в список dicts с 'eval function' в python. Так как же мне применить здесь eval () для передачи строки в список в каждой строке? Я пробовал много способов:

  1. bmd2.select ('genres'.astype (' list ')): AttributeError: объект' str ' не имеет атрибута "astype"
  2. bmd2.select (eval ('genres')): NameError: имя 'genres' не определено
  3. bmd2.withColumn ('genres', eval ('genres')): NameError: name 'genres' не определено

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

Я решил свой вопрос, используя UDF, определяемую пользователем функцию.

Сначала импортируйте его:

from pyspark.sql.functions import udf

Затем определите свой UDF, как анонимную функцию:

getdirector = udf(lambda x:[i['name'] for i in x if i['job'] == 'Director'],StringType())

Вы должны назначить тип возвращаемого значения здесь, чтобы вы получили возвращаемое значение с ожидаемым типом. Затем вы можете вызывать этот UDF в своем коде, как и другие функции.

cres2 = cres1.select('id',getcharacter('cast').alias('cast'),getdirector('crew').alias('crew'))

В этой задаче я могу изменить UDF для получения любого нужного мне типа.

0 голосов
/ 10 мая 2018

Я пишу это как ответ, так как не могу найти опцию комментария. Я бы посоветовал вам взглянуть на from_json из pyspark.sql.functions. Например, вот как вы бы это использовали:

# given a row that looks like:

+----------genres-------------+
| [{ id:1, name:"hiphop"}]    |
+-----------------------------+

# define a schema
schema = ArrayType(StructType().add("id", IntegerType())\
                              .add("name", StringType()))

# transform
new_df = df.select(from_json("genres", schema).alias("genres_dict"))

# display
new_df.printSchema()
new_df.show()

Существует еще один метод для достижения этой цели с помощью функции regexp_extract. Но вышесказанное - мое личное предпочтение. Также, если вы хотите вернуться к исходной строке, вы можете использовать функцию to_json. Надеюсь, это поможет.

...