Pyspark-调用pandas_udf并返回Series.interpolate()作为结果时出错

时间:2019-02-06 22:00:17

标签: python pandas pyspark user-defined-functions

我正在尝试创建一个返回interpolation函数的UDF,但是该函数返回的是带有索引的Series并引发异常。

from pyspark.sql.types import FloatType

@F.pandas_udf(FloatType(), F.PandasUDFType.GROUPED_AGG)
def udf_interpolate(v):
  return v.interpolate('linear')

## Test data
df = spark.createDataFrame([
    ("charles", 1),
    ("charles", None),
    ("charles", 3),
], ["name", "value"])

window = Window.partitionBy('name').rowsBetween(Window.unboundedPreceding, Window.unboundedFollowing)
df.withColumn('test_interp', udf_interpolate(df.value).over(window)).show()

错误消息:

pyarrow.lib.ArrowInvalid: Could not convert 0    3.0
1    2.0
2    1.0
Name: _0, dtype: float64 with type Series: tried to convert to float32

我试图强制转换为float32,但是错误仍然存​​在。我最初的想法是因为我要返回“期望一个值”中具有多个值的系列,但我不知道该如何解决这个问题。

例如,如果我更改函数以返回v.mean(),效果很好。

感谢任何帮助。

谢谢。

1 个答案:

答案 0 :(得分:1)

GROUPED_AGG requires the UDF to return a scalar;在您的情况下,最好使用GROUPED_MAP,因为您要返回一个Series并需要按组进行计算;本质上,您将每个名称的子数据框传递给pandas_udf,使用pandas API对其进行转换,然后将转换后的数据框返回:

@F.pandas_udf(df.schema, F.PandasUDFType.GROUPED_MAP)
def udf_interpolate(g):
    return g.assign(value=g.value.interpolate('linear'))

df.groupby('name').apply(udf_interpolate).show()
+-------+-----+                                                                 
|   name|value|
+-------+-----+
|charles|    1|
|charles|    2|
|charles|    3|
+-------+-----+