使用 numpy.clip 将正值和负值转换为位串

Posted

技术标签:

【中文标题】使用 numpy.clip 将正值和负值转换为位串【英文标题】:Converting positive and negative values to a bitstring using numpy.clip 【发布时间】:2014-09-23 17:15:38 【问题描述】:

我想有效地将​​列表(或 numpy 数组)中的值转换为 numpy 位数组:负值应在新数组中变为 0,正值应在新数组中变为 1。

例如,

>> import numpy as np
>> np.clip([1,2,3,-1,-2],  a_min=0, a_max=1)
array([1, 1, 1, 0, 0])

但是,如果列表中有浮点数,此方法将保持原样:

>> np.clip([1,0.45,3,-1,-2],  a_min=0, a_max=1)
array([ 1.  ,  0.45,  1.  ,  0.  ,  0.  ])

有没有规避这种行为的好方法?一种方法是对值进行四舍五入。但我希望所有正数都分配一个 1。如果我使用 np.around(),这将是 0.45 -> 0。

【问题讨论】:

【参考方案1】:

要将大于 0 的所有内容映射到 1(以及小于 0 的所有内容),您可以使用 np. where:

In [25]: np.where(np.array([1,0.45,3,-1,-2]) > 0, 1, 0)
Out[25]: array([1, 1, 1, 0, 0])

In [29]: (np.array([1,0.45,3,-1,-2]) > 0).astype('i1')
Out[29]: array([1, 1, 1, 0, 0], dtype=int8)

请注意,np.where 返回一个 dtype 为 int32(4 字节整数)的数组,而astype('i1') 返回一个 dtype 为 int8(1 字节整数)的数组。

如果您希望将这些二进制值打包到一个 uint8 中,您可以使用 np.packbits:

In [48]: x = np.array([1,0.45,3,-1,-2])

In [49]: np.packbits((x > 0).astype('i1'))
Out[49]: array([224], dtype=uint8)

In [50]: bin(224)
Out[50]: '0b11100000'

或者,作为一个字符串:

In [60]: np.packbits((x > 0).astype('i1')).tostring()
Out[60]: '\xe0'

In [62]: bin(0xe0)
Out[62]: '0b11100000'

【讨论】:

很好,谢谢!当 *** 允许我时,我会接受这个答案! 请注意,如果性能是一个问题,我知道(a > 0).astype('i1')np.where(a > 0, 1, 0) 快得多。数组越大,差异越大。对于 100 长度的数组,我的速度提高了大约 2 倍,对于 10k 长度的数组,我的速度提高了 10 倍。 感谢@RogerFan 的留言【参考方案2】:
In [21]: arr = np.array([1,0.45,3,-1,-2])

In [22]: np.ceil(arr.clip(0, 1))
Out[22]: array([ 1.,  1.,  1.,  0.,  0.])

【讨论】:

以上是关于使用 numpy.clip 将正值和负值转换为位串的主要内容,如果未能解决你的问题,请参考以下文章

快速将正值转换为负值

在 R 中使用 For 循环匹配负值和正值

它们是一个 SQL 函数,可以使用下面的查询给我一个负值和正值吗?

对具有负值和正值的整数和浮点数列表进行排序?

使numpy数组的负值变为正

带有用于正值和负值的单独条形的条形图