如何使用pysparkSQL将字符串传输到dict

2024-10-03 06:27:06 发布

您现在位置:Python中文网/ 问答频道 /正文

在pysparkSQL中,我有一个名为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”列中的数据类型是字符串,但在python中它们可以通过“eval function”传输到dict列表。那么我应该如何在这里应用eval()来将这里的字符串转移到每一行的列表中呢?我试过很多方法:

  1. bmd2.select('genres'.astype('list')):AttributeError: 'str' object has no attribute 'astype'
  2. bmd2.select(eval('genres')):NameError: name 'genres' is not defined
  3. bmd2.withColumn('genres',eval('genres')):NameError: name 'genres' is not defined

Tags: 数据字符串nameid列表stringiseval
2条回答

我写这个作为一个答案,因为我找不到评论选项。我建议您从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\u extract的函数来实现这一点。但以上是我个人的喜好。另外,如果您想切换回原始字符串,您可以使用它来创建json函数。希望这有帮助。你知道吗

我用自定义函数解决了我的问题,它是用户定义的函数。你知道吗

首先,导入它:

from pyspark.sql.functions import udf

然后,定义自定义项,就像一个匿名函数:

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

您应该在这里指定返回值的类型,这样您将得到一个具有预期类型的返回值。然后可以在代码中像调用其他函数一样调用这个自定义项。你知道吗

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

在这个问题中,我可以修改UDF来获得我需要的任何类型。你知道吗

相关问题 更多 >