PySpark-numpy interoperability

Viewed 48

I am working on a dataset where most of the columns are 1D sequences of doubles, like the following one:

source_data = [
    Row(ID="F0", P1=[-1.0, -2.0, -3.0], P2=[-4.0, -5.0, -6.0]),
    Row(ID="F1", P1=[1.0, 2.0, 3.0], P2=[4.0, 5.0, 6.0]),
]
df = spark.createDataFrame(source_data)

which looks like:

+---+------------------+------------------+
| ID|                P1|                P2|
+---+------------------+------------------+
| F0|[-1.0, -2.0, -3.0]|[-4.0, -5.0, -6.0]|
| F1|   [1.0, 2.0, 3.0]|   [4.0, 5.0, 6.0]|
+---+------------------+------------------+

The columns P1 and P2 have spark type ArrayType(DoubleType()). In my real dataset, I have hundreds of columns of different length.

My goal is to execute mathematical operations such as mean, median, quantiles, fft, etc on these sequences in a distributed manner on a cluster. My approach is to wrap numpy functions as follows. First, I "hide" the numpy types which do not seem to be supported by Spark:

# wrap functions to "hide" numpy data types
def py_median(param_val):
    param_val = np.array(param_val)
    param_median = np.median(param_val)
    return float(param_median)

def py_abs(param_val):
    param_val = np.array(param_val)
    param_abs = np.abs(param_val)
    return param_abs.tolist()

Then, I transform the functions to pySpark UDFs:

# wrap functions to operate as udfs
median = F.udf(py_median, DoubleType())
abs = F.udf(py_abs, ArrayType(DoubleType()))

Finally, I can use them with pySpark to do the work:

df_processed = (
    df.withColumn("P1_mean", median(col("P1")))
    .withColumn("P2_abs", abs(col("P2")))
)

Note that I have to convert the result type to simple python types such as:

  • python float (functions returning a scalar)
  • python list of float (functions returning a 1D numpy array) otherwise I get Spark errors

I need different wrapping strategies to handle functions returning a complex array (e.g. the fft) or multiple return value. Is there a cleaner way to get my job done? Perhaps using Pandas UDFs?

Thanks in advance,

Marco

0 Answers
Related