我有一个庞大的pyspark数据帧。我需要将Person
分组,然后将collect
个Budget
项分组到列表中,以执行进一步的计算。
例如,
a = [('Bob', 562,"Food", "12 May 2018"), ('Bob',880,"Food","01 June 2018"), ('Bob',380,'Household'," 16 June 2018"), ('Sue',85,'Household'," 16 July 2018"), ('Sue',963,'Household'," 16 Sept 2018")]
df = spark.createDataFrame(a, ["Person", "Amount","Budget", "Date"])
分组依据:
import pyspark.sql.functions as F
df_grouped = df.groupby('person').agg(F.collect_list("Budget").alias("data"))
架构:
root
|-- person: string (nullable = true)
|-- data: array (nullable = true)
| |-- element: string (containsNull = true)
但是,当我尝试在每个人身上应用UDF时,我收到内存错误。如何获得每个人的每个列表(data
)的大小(以兆字节或千兆字节为单位)?
我已完成以下操作,但收到nulls
import sys
size_list_udf = F.udf(lambda data: sys.getsizeof(data)/1000, DoubleType())
df_grouped = df_grouped.withColumn("size",size_list_udf("data") )
df_grouped.show()
输出:
+------+--------------------+----+
|person| data|size|
+------+--------------------+----+
| Sue|[Household, House...|null|
| Bob|[Food, Food, Hous...|null|
+------+--------------------+----+
答案 0 :(得分:0)
您的代码只有一个小问题。 sys.getsizeof()
以整数形式返回对象的大小(以字节为单位)。您将其除以整数值1000
以获取千字节数。在python 2中,这将返回一个整数。但是,您定义了udf
以返回DoubleType()
。简单的解决方法是除以1000.0
。
import sys
size_list_udf = f.udf(lambda data: sys.getsizeof(data)/1000.0, DoubleType())
df_grouped = df_grouped.withColumn("size",size_list_udf("data") )
df_grouped.show(truncate=False)
#+------+-----------------------+-----+
#|person|data |size |
#+------+-----------------------+-----+
#|Sue |[Household, Household] |0.112|
#|Bob |[Food, Food, Household]|0.12 |
#+------+-----------------------+-----+
我发现在udf
返回null
的情况下,罪魁祸首常常是类型不匹配。