PySpark - 获取分组中每个列表的大小

时间:2018-02-26 13:12:28

标签: pyspark spark-dataframe user-defined-functions

我有一个庞大的pyspark数据帧。我需要将Person分组,然后将collectBudget项分组到列表中,以执行进一步的计算。 例如,

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|
+------+--------------------+----+

1 个答案:

答案 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的情况下,罪魁祸首常常是类型不匹配。