python - Redshift Python UDF 自行运行,但在部分使用 count 或作为另一个查询的一部分时会引发错误
问题描述
编辑/更新(下)
我存储并可以在 AWS-Redshift 中成功运行 python UDF。boolean
如果该点在另一个给定点的给定距离内,则UDF 正在获取纬度/经度点并返回 a 。
当我跑
SELECT dist_in_range(5000.0, latitude, longitude, 38.897957, -77.036560) as in_range
from test_2;
它按预期返回一列真或假。
当我跑
SELECT a.in_range from (SELECT dist_in_range(5000.0, latitude, longitude, 38.897957, -77.036560) as in_range
from test_2) as a
where a.in_range = false;
过滤假,它再次正确运行。
如果我count()
在查询中添加一个函数,例如:
SELECT count(a.in_range) from (SELECT dist_in_range(5000.0, latitude, longitude, 38.897957, -77.036560) as in_range
from test_2) as a
where a.in_range = false;
它返回错误:
[Amazon](500310) Invalid operation: TypeError: a float is required. Please look at svl_udf_log for more information Details: ----------------------------------------------- error: TypeError: a float is required. Please look at svl_udf_log for more information code: 10000 context: UDF query: 1766 location: udf_client.cpp:369 process: query1_995_1766 [pid=50711] -----------------------------------------------;
此错误似乎表明它是 UDF 和 UDF 输入的问题,但如上所示,UDF 自身正常工作。我认为在结果上使用 count() 只是一个 sql 查询,将返回的项目计数为 false。为什么在尝试计算 UDF 的结果时会出现错误?
更新/编辑:我开始相信这种在 python 2.7 中发生的某种类型的精度错误(版本 Redshift 文档说明它正在使用)。这是我正在运行的 UDF(感谢https://skipperkongen.dk/category/spatial/获取代码;我只是做了一些补充):
CREATE OR REPLACE FUNCTION dist_in_range (radius float,lat1 float, lon1 float, lat2 float, lon2 float)
RETURNS bool IMMUTABLE AS
$$
from math import radians, sin, cos, asin, sqrt, pi, atan2
import numpy as np
earth_radius_miles = 3956.0
def dist_in_range(radius, lat1, lon1, lat2, lon2):
"""checks if a point is within int number of miles of second set of points.
"""
lat1, lon1 = radians(lat1), radians(lon1)
lat2, lon2 = radians(lat2), radians(lon2)
dlat, dlon = float(lat2 - lat1), float(lon2 - lon1)
a = sin(dlat/2.0)**2 + cos(lat1) * cos(lat2) * sin(dlon/2.0)**2
great_circle_distance = 2 * asin(min(1,sqrt(a)))
if float(earth_radius_miles * great_circle_distance) < float(radius):
return True
else:
return False
return dist_in_range(radius, lat1, lon1, lat2, lon2)
$$ LANGUAGE plpythonu;
在我正在测试的数据集上,如果我运行此查询:
SELECT dist_in_range(40, latitude, longitude, 20.652975, -87.102572) as in_range from test_2
where in_range = true;
它返回没有错误的结果。如果我将半径变量降低到 40 以下,我开始得到“需要浮点数”错误,除非我设置 WHERE in_range = false,然后它再次返回结果而没有错误。
我在 jupyter 笔记本中检查运行较小的半径,在某些情况下,在打印计算步骤时,我得到的数字非常小
1.0134428420666964e-13
所以,我想知道这是 python 2.7 中的精度问题,如果有什么我可以做些什么来调整?
最后,aws 错误引用的日志没有提供更多信息,因为它只是模仿“TypeError:需要浮点数”消息,并指向 UDF 中的第 11 行和第 21 行,但第 11 行是注释第 21 行是该else: return False
行。
解决方案
推荐阅读
- excel - 尝试从网页中使用 vba 搜索地点的纬度和经度。单击vba的查找按钮不起作用
- objective-c - NSCFBoolean 和 NSNumber 发生了什么?
- python - 如何为 Pandas 小时/工作日图设置两级刻度?
- java - 序列化和静态变量
- c# - WPF将项目添加到BindingList不会更新Viewmodel中的另一个属性
- java - Java Swing 类对象
- android - 小米手环 3 配对和获取数据(心率、步数等)问题
- uwp - UWP 垂直排列底部项目(拆分视图)
- sitemap - 无法在 netlify 上将 sitemap.xml 添加到 Google 控制台
- c# - C# EF Random Order 导致相关列表消失