在Python中,可以使用n.is_integer()
检查float
是否包含整数值,基于以下QA:How to check if a float value is a whole number的数据。
numpy是否有类似的操作可以应用于数组?可以实现以下功能的东西:
>>> x = np.array([1.0 2.1 3.0 3.9])
>>> mask = np.is_integer(x)
>>> mask
array([True, False, True, False], dtype=bool)
字符串
有可能做类似的事情
>>> mask = (x == np.floor(x))
型
或者是
>>> mask = (x == np.round(x))
型
但是它们涉及到调用额外的方法和创建一堆可能被避免的临时数组。
numpy是否有一个向量化的函数,以类似于Python的float.is_integer
的方式检查浮点数的小数部分?
5条答案
按热度按时间eaf3rand1#
据我所知,没有这样的函数返回一个布尔数组,指示浮点数是否有小数部分。我能找到的最接近的是
np.modf
,它返回小数和整数部分,但它创建了两个浮点数组(至少暂时),所以它可能不是最好的内存方式。如果你在工作中感到快乐,你可以尝试以下方法:
字符串
这应该比使用round或floor保存内存(在这里必须保留
x
),但当然会丢失原始的x
。另一个选择是要求在Numpy中实现它,或者自己实现它。
w51jfk4q2#
我需要这个问题的答案,原因略有不同:检查何时可以将整个浮点数数组转换为整数而不丢失数据。
Hunse的答案几乎对我有用,除了我显然不能使用就地技巧,因为我需要能够撤消操作:
字符串
从那里,我想到了以下选项,在许多情况下 * 可能 * 更快:
型
原因是模运算比减法慢。然而,现在我们预先将其转换为整数-相对而言,我不知道该操作有多快。但是如果你的数组中的 * 大部分 * 都是整数(在我的例子中是整数),后一个版本几乎肯定更快。
另一个好处是,您可以用类似
np.isclose
的东西来替换减法,以在一定的容差范围内进行检查(当然,您应该小心,因为截断不是正确的舍入!).型
编辑:较慢,但可能值得根据您的用例,也是单独转换整数,如果存在的话。
型
举个例子,说明这一点的重要性:这对我来说是可行的,因为我有稀疏的数据(这意味着大部分是零),然后我将其转换为JSON,一次,然后在服务器上重用。对于浮点数,
ujson
将其转换为[ ...,0.0,0.0,0.0,... ]
,对于整型数,将其转换为[...,0,0,0,...]
,从而节省字符串中一半的字符数。这减少了服务器(更短的字符串)和客户端(更短的字符串,可能稍微快一点的JSON解析)的开销。kiayqfof3#
虽然
(x % 1) == 0
的公认方法已经足够了,但让我感到困扰的是,在numpy中没有办法在本机实现这一点,特别是考虑到vanilla python中存在float.is_integer
。因此,我对numpy支持的浮点格式(
float16
,float32
,float64
,float128
(实际上是extended precision))和how to write a ufunc做了一些研究。其结果是,对于IEEE754浮点数足够小,可以放入相应的无符号整数类型(在普通机器上几乎所有
float64
),您可以通过一些简单的位调整来进行检查。例如,下面是一个C99函数,它可以快速地告诉您float32
是否包含整数值:字符串
我继续将这个函数及其兄弟函数 Package 在ufunc中,可以在这里找到:https://gitlab.com/madphysicist/is_integer_ufunc。一个很好的特性是这个ufunc返回所有整数类型的
True
,而不是引发错误。另一个原因是它的运行速度比(x % 1) == 0
快5倍到40倍,具体取决于dtype和输入大小。根据链接的教程,您可以使用
python setup.py {build_ext --inplace, build, install}
安装,这取决于您有多想要它。也许我应该看看numpy社区是否有兴趣包含这个ufunc。k5ifujac4#
你也可以在列表解析中使用Python方法。
字符串
与the answer using mod 1相比,对于给定的4个值的示例(5.66 us vs 8.03 us),这稍微快一点,对于1000个值的数组,速度快3倍以上。
n3schb8v5#
受公认答案的启发,这里有一个使用
%
运算符的非就地版本:字符串
或者更简洁地说
型