如何筛选出配置单元中具有nan值的行?

y0u0uwnf  于 2021-05-29  发布在  Hadoop
关注(0)|答案(2)|浏览(479)

我在hue中运行一个hive表的sum函数,得到一个返回值nan。
这是我的密码: select sum(v1) from hivedb.tb1; 我不知道为什么它会给我一个结果。我检查了我的v1值是否为空: select * from hivedb.tb1 where v1 is null; ,结果没有记录具有空值。这个表有1亿行,所以我不能手动检查每条记录。
有人知道我为什么得到一个结果吗?
如果是因为我在某些行中有一些异常值,我怎么能找到它们呢?
感谢您的帮助。提前谢谢!
update1我手动筛选了前1000行,幸运的是在tb1中发现了一些异常的nan值。这是由于前面步骤中的一些舍入误差造成的。所以我的问题1可能已经回答了。如果您认为还有其他原因,请随时发表评论。
我仍然不知道如何使用一种有效的方法来发现具有nan值的行。所以我仍然期待着我的问题2的任何答案。请随意分享。我感谢你的帮助。
更新2在下面的讨论部分中,在接受答案的帮助下,问题得以解决。有多种方法可以解决这个问题。
使用条件选择v1+1>v1。它将选择具有非nan值的行。
使用条件选择cast(v1 as string)=“nan”。它将选择具有nan值的行。

qc6wkl3g

qc6wkl3g1#

你可以把nan当作

SELECT SUM(CAST(IF(v1 ='NaN', 0, v1)) as Double) FROM hivedb.tb1
v1l68za4

v1l68za42#

hive依赖于java(加上针对null和friends的sql特定语义),java遵守ieee数字语义标准。也就是说。。。南很狡猾。
引用那篇文章。。。 (Float.NaN == Float.NaN) 总是返回false。
事实上,如果您看看 Float.isNaN() ,如果一个数不等于它自己,它就不是一个数(这是有意义的,因为一个数应该等于它自己)。
对double.nan也一样
因此,向您展示如何使用调用的(未记录的)配置单元函数是没有意义的 reflect2 ,它允许您在配置单元列上调用原始java方法,即。

where v1 is not null and not reflect2(v1, "isNaN")

……因为——理论上——你可以简单地说:

where v1 is not null and v1=v1

免责声明——我见过这样的情况:配置单元优化器进行了激进的“优化”,并产生了错误的结果。
换句话说,如果 v1=v1 子句没有按预期筛选出nan值,然后查看 reflect2 ...
编辑——实际上,优化器似乎忽略了 v1=v1 在某些版本的配置单元中使用子句(请参阅注解),因此需要一个更离经叛道的公式: v1 +1.0 > v1 应该有用。。。除非舍入误差 abs(v1) <<1或 abs(v1) >> 1
其他“数字”技巧在边缘情况下也会失败,尤其是在 v1 =0.0 最后,最稳健的方法似乎在尝试 cast(v1 as String) <>'NaN' (因为所有可能的nan值都显示为“nan”,即使它们在算术意义上不是严格的“相等”)。
关于的旁注 reflect2 --你可以看到,它确实没有提到在官方Hive文件,而 reflect 被提及(甚至有一个特定的wiki条目)。但是它早在hive v0.11(参见hive-4025)中就已经实现了
edit—java“反射”现在在odbc/jdbc/hue连接的默认情况下被禁用(请参阅注解),并且在使用诸如ranger或sentry之类的安全插件时不能重新启用。因此它的用法仅限于(已弃用) hive 客户端。

相关问题