pyspark 函数分解器输入应为数组或Map类型,而不是结构

eni9jsuy  于 2023-01-01  发布在  Spark
关注(0)|答案(3)|浏览(268)

我有以下数据。

  1. data = [
  2. [
  3. "2022-12-12",
  4. ["IND", "u1", [["auction_1", [[1,20], [2,12]]], ["auction_2", [[1,5], [2,7]]]]],
  5. ],
  6. [
  7. "2022-12-12",
  8. ["USA", "u2", [["auction_1", [[1,8], [2,12]]], ["auction_2", [[1,11], [2,4]]]]],
  9. ],
  10. ]

我有以下模式
x一个一个一个一个x一个一个二个一个x一个一个三个一个
我想有数据在下面的格式作进一步分析.

  1. date, country, userId, refferalId, action, amountSpent, timeSpent
  2. 2022-12-31, IND, 123, 123213, action1, 5, 56
  1. display(df.select(F.explode("data")))
  2. # cannot resolve 'explode(data)' due to data type mismatch: input to function explode should be an array or map type

任何帮助都将不胜感激。
如果不能分解任何StructType,如何实现上述数据格式?
我也看了这些问题,但没有得到太多帮助-〉Error while exploding a struct column in Spark

wwtsj6pe

wwtsj6pe1#

您必须分解数据。用户:

  1. df.select('date', 'data.country', 'data.userId', F.explode('data.users').alias('info'))

对于这些操作,您需要如下所示的查询(在分解data.users之后):

  1. .select('date', 'country', 'userId', 'info.refferalId', F.explode('actions').alias('actionInfo'))

但是因为你把动作定义为结构体,所以它不能被分解,如果你把它的模式改为列表,代码就能正常工作

2ic8powd

2ic8powd2#

这基本上是一项需要转换大量数据以使其成为所需形式的任务,需要结合使用pyspark.sql.functions才能得到所需的形式。
如果我们从您的df开始:

  1. output = df.select("date", "data.country", "data.userId", explode(col("data.users")).alias("users")) \
  2. .select("date", "country", "userId", "users.*") \
  3. .withColumn("actions", explode(array(
  4. struct("actions.action1.*", lit("action1").alias("action")),
  5. struct("actions.action2.*", lit("action2").alias("action"))
  6. )
  7. )) \
  8. .select("date", "country", "userId", "refferalId", "actions.*")
  9. output.printSchema()
  10. root
  11. |-- date: string (nullable = true)
  12. |-- country: string (nullable = true)
  13. |-- userId: string (nullable = true)
  14. |-- refferalId: string (nullable = true)
  15. |-- amountSpent: long (nullable = true)
  16. |-- timeSpent: long (nullable = true)
  17. |-- action: string (nullable = false)
  18. output.show()
  19. +----------+-------+------+----------+-----------+---------+-------+
  20. | date|country|userId|refferalId|amountSpent|timeSpent| action|
  21. +----------+-------+------+----------+-----------+---------+-------+
  22. |2022-12-12| IND| u1| auction_1| 1| 20|action1|
  23. |2022-12-12| IND| u1| auction_1| 2| 12|action2|
  24. |2022-12-12| IND| u1| auction_2| 1| 5|action1|
  25. |2022-12-12| IND| u1| auction_2| 2| 7|action2|
  26. |2022-12-12| USA| u2| auction_1| 1| 8|action1|
  27. |2022-12-12| USA| u2| auction_1| 2| 12|action2|
  28. |2022-12-12| USA| u2| auction_2| 1| 11|action1|
  29. |2022-12-12| USA| u2| auction_2| 2| 4|action2|
  30. +----------+-------+------+----------+-----------+---------+-------+

每个转换的操作:

  • 第一个select语句解包data结构并分解data.users数组
  • 其次,select语句解包users结构
  • 第三,withColumn语句稍微复杂一些,此时我们有两个结构体(action1action2),它们有相同的模式,我们在这里做的是:
  • actions列添加一个文本列action,值为action1action2
  • 使用array函数将这两个相似的列放入数组中
  • 分解数组
  • 第四,select语句用于展开我们创建的actions结构体

希望这有帮助!

展开查看全部
c2e8gylq

c2e8gylq3#

问题是你不能分解struct,你只能分解数组或map,你需要做的第一步是分解data.users(不仅仅是数据),你可以这样做:

  1. users = df\
  2. .withColumn("s", F.explode("data.users"))\
  3. .select("date", "data.country", "data.userId", "s.*")
  4. users.show()
  1. +----------+-------+------+----------+------------------+
  2. | date|country|userId|refferalId| actions|
  3. +----------+-------+------+----------+------------------+
  4. |2022-12-12| IND| u1| auction_1|{{1, 20}, {2, 12}}|
  5. |2022-12-12| IND| u1| auction_2| {{1, 5}, {2, 7}}|
  6. |2022-12-12| USA| u2| auction_1| {{1, 8}, {2, 12}}|
  7. |2022-12-12| USA| u2| auction_2| {{1, 11}, {2, 4}}|
  8. +----------+-------+------+----------+------------------+

从那里,你想要分解动作,但是和以前一样,你不能分解结构体。为了克服这个问题,你可以把它转换成一个结构体数组。

  1. users\
  2. .withColumn("actions", F.array(
  3. [ F.struct(
  4. F.lit(f"action{i}").alias("action"),
  5. F.col("actions")[f"action{i}"].alias("meta")
  6. ) for i in [1, 2] ]
  7. ))\
  8. .withColumn("action", F.explode("actions"))\
  9. .select("date", "country", "userId", "refferalId", "action.action", "action.meta.*")\
  10. .show()
  11. +----------+-------+------+----------+-------+-----------+---------+
  12. | date|country|userId|refferalId| action|amountSpent|timeSpent|
  13. +----------+-------+------+----------+-------+-----------+---------+
  14. |2022-12-12| IND| u1| auction_1|action1| 1| 20|
  15. |2022-12-12| IND| u1| auction_1|action2| 2| 12|
  16. |2022-12-12| IND| u1| auction_2|action1| 1| 5|
  17. |2022-12-12| IND| u1| auction_2|action2| 2| 7|
  18. |2022-12-12| USA| u2| auction_1|action1| 1| 8|
  19. |2022-12-12| USA| u2| auction_1|action2| 2| 12|
  20. |2022-12-12| USA| u2| auction_2|action1| 1| 11|
  21. |2022-12-12| USA| u2| auction_2|action2| 2| 4|
  22. +----------+-------+------+----------+-------+-----------+---------+
展开查看全部

相关问题