使用 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 将正值和负值转换为位串的主要内容,如果未能解决你的问题,请参考以下文章