Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python RuntimeError:来自pandas_udf的结果向量不是所需的长度:应为2,得到1_Python_Pandas_Apache Spark_Pyspark_User Defined Functions - Fatal编程技术网

Python RuntimeError:来自pandas_udf的结果向量不是所需的长度:应为2,得到1

Python RuntimeError:来自pandas_udf的结果向量不是所需的长度:应为2,得到1,python,pandas,apache-spark,pyspark,user-defined-functions,Python,Pandas,Apache Spark,Pyspark,User Defined Functions,我正在尝试使用pandas\u udf 我有我的Spark数据框,其中有一个数组列Struct: root |-- values: array (nullable = true) | |-- element: struct (containsNull = true) | | |-- x: double (nullable = true) | | |-- y: double (nullable = true) 我想做的是在values列上运行pandas_u

我正在尝试使用
pandas\u udf

我有我的Spark数据框,其中有一个数组列Struct:

root
 |-- values: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- x: double (nullable = true)
 |    |    |-- y: double (nullable = true)
我想做的是在
values
列上运行pandas_udf,并根据定义的逻辑为每个记录(即每个数组)返回一个值

在我的数据源中,如果有多条记录的
values
列包含空数组,则会出现以下错误:

line 89, in verify_result_length "expected %d, got %d" % (len(a[0]), len(result)))

RuntimeError: Result vector from pandas_udf was not the required length: expected 2, got 1
在Google上搜索时,我在此处找到了源代码:

另一方面,如果我只有一条带有空数组的记录,那么进程将毫无问题地结束。使用空数组筛选Spark记录没有帮助(仅供参考
.filter(“大小(值)!=0”)
),它会导致相同的行为

但我不明白为什么我会犯这个错误,我做错了什么。有人能帮忙吗

编辑

代码

import numpy as np
import pandas as pd
import pyspark.sql.functions as f

udf = f.pandas_udf(udf_function, returnType="float")
df.withColumn("newColumn",
             f.when(f.size(f.col("values")) == 0, 0)\
             .otherwise(udf(f.col("values.x"), f.col("values.y"))))

def udf_function(x_array, y_array, Window=20):
   xy = []
   data = pd.DataFrame({'x': x_array.tolist()[0], 'y': y_array.tolist()[0]})

   x = data['x'].rolling(int(Window / 2), center=True, min_periods=1).sum()
   y = data['y'].rolling(int(Window / 2), center=True, min_periods=1).sum()

   for index in range(len(x)):
       xy.append(np.sqrt(x[index] ** 2 + y[index] ** 2))

   if not xy:
       result = 0
   else:
       result = max(xy)

   return pd.Series(result)
{
  "values": []
}

{
  "values": []
}

{
  "values": [
    {
      "x": -0.638,
      "y": 0.879,
    },
    {
      "x": -0.616,
      "y": 0.809,
    },
    {
      "x": -0.936,
      "y": 0.762,
    }]
}
记录

import numpy as np
import pandas as pd
import pyspark.sql.functions as f

udf = f.pandas_udf(udf_function, returnType="float")
df.withColumn("newColumn",
             f.when(f.size(f.col("values")) == 0, 0)\
             .otherwise(udf(f.col("values.x"), f.col("values.y"))))

def udf_function(x_array, y_array, Window=20):
   xy = []
   data = pd.DataFrame({'x': x_array.tolist()[0], 'y': y_array.tolist()[0]})

   x = data['x'].rolling(int(Window / 2), center=True, min_periods=1).sum()
   y = data['y'].rolling(int(Window / 2), center=True, min_periods=1).sum()

   for index in range(len(x)):
       xy.append(np.sqrt(x[index] ** 2 + y[index] ** 2))

   if not xy:
       result = 0
   else:
       result = max(xy)

   return pd.Series(result)
{
  "values": []
}

{
  "values": []
}

{
  "values": [
    {
      "x": -0.638,
      "y": 0.879,
    },
    {
      "x": -0.616,
      "y": 0.809,
    },
    {
      "x": -0.936,
      "y": 0.762,
    }]
}
另外,即使使用
f.when(f.size(f.col(“values”)==0,0)。否则(udf())
条件应该过滤掉带有空数组的记录(或者至少在空数组的情况下,不应该调用udf函数),看起来udf函数无论如何都会处理这些记录!这对我来说很奇怪

进一步的上下文

import numpy as np
import pandas as pd
import pyspark.sql.functions as f

udf = f.pandas_udf(udf_function, returnType="float")
df.withColumn("newColumn",
             f.when(f.size(f.col("values")) == 0, 0)\
             .otherwise(udf(f.col("values.x"), f.col("values.y"))))

def udf_function(x_array, y_array, Window=20):
   xy = []
   data = pd.DataFrame({'x': x_array.tolist()[0], 'y': y_array.tolist()[0]})

   x = data['x'].rolling(int(Window / 2), center=True, min_periods=1).sum()
   y = data['y'].rolling(int(Window / 2), center=True, min_periods=1).sum()

   for index in range(len(x)):
       xy.append(np.sqrt(x[index] ** 2 + y[index] ** 2))

   if not xy:
       result = 0
   else:
       result = max(xy)

   return pd.Series(result)
{
  "values": []
}

{
  "values": []
}

{
  "values": [
    {
      "x": -0.638,
      "y": 0.879,
    },
    {
      "x": -0.616,
      "y": 0.809,
    },
    {
      "x": -0.936,
      "y": 0.762,
    }]
}
当我使用大约15个或更多的输入文件时,出现了一个例外,这与使用空数组的记录无关。无论如何,这是一个奇怪的异常,因为对于观察到的行为,我期待类似“JavaOutOfMemory异常”的东西,但报告的异常对我理解真正的问题没有太大帮助


与此同时,我回来时使用了更多的stables RDD而不是pandas_udf。

你能提供一些虚拟数据和你的udf来复制这个问题吗?@pansen编辑!我希望它有助于复制它(如何在Spark中阅读json取决于您),如果您需要其他东西或者您成功地复制了这种情况,请告诉我。您可以使用空数组轻松地增加或减少记录数