我有一个长度为1和0的numpy数组,在我所拥有的所有1个中,我想转换一定比例的他们到0岁了。我需要将其余的人保持在适当的位置。
我当然可以运行for循环这样做,但我想知道是否还有更好的东西。感谢。
这是我尝试做的事情。它有两个问题。
1)没有工作
2)1并不是随机替换的。我需要以某种方式收集指数才能做到这一点,但我不知道如何
x = np.array([1,0,1,0,1,1,0,1])
print(x)
for i in np.nditer(x,op_flags=['readwrite']):
if i ==1 & sum(x)>2:
i[...] = 0 #np.random.binomial(1,0)
print(x)
注意:如果有30个1,我希望能够准确指定30个中的多少个将变为零(比如说14个)。但是,那些14应该从30中随机选择,并赋值为零。
答案 0 :(得分:4)
使用逻辑索引来获得快速结果:
>>> a = np.array([0, 1, 1, 0, 1, 1, 0, 0, 0, 1.])
>>> a_orig = a.copy()
>>> a[a!=0] = np.random.rand(a.sum())
>>> a[a>0.5] = 1
>>> a[a<=0.5] = 0
>>> a_orig
array([ 0., 1., 1., 0., 1., 1., 0., 0., 0., 1.])
>>> a
array([ 0., 0., 0., 0., 0., 1., 0., 0., 0., 1.])
零保留,有些已经改变。
备注我强制原始数组的数据类型(dtype)为'float'类型。但是,如果它是'int8'或变体,您可以使用np.random.randint(0,2, a.sum())
代替np.random.rand(a.sum())
和后续2行。
修改:使用修订后的帖子,详细说明您希望具体数量的,您可以使用np.random.shuffle
,如下所示:
>>> a = np.array([0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1])
>>> a_orig = a.copy()
>>> how_many_flip = 4 # you'll have to make sure it's less than a.sum()
>>> b = np.hstack((np.zeros(how_many_flip, dtype=int), np.ones(a.sum()-how_many_flip, dtype=int)))
>>> np.random.shuffle(b)
>>> b
array([1, 1, 0, 0, 1, 1, 0, 1, 0])
>>> a[a!=0] = b
>>> a
array([0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0])
>>> a_orig
array([0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1])
答案 1 :(得分:0)
可以这样做
a = [1,1,1,1,1,0,0,0,0]
a[2:4]=[0]*2
>>> a
[1, 1, 0, 0, 1, 0, 0, 0, 0]
答案 2 :(得分:0)
如果数组已排序,您可以使用二进制搜索(将在O(log n)时间内发生)找到0和1之间的边界。一旦有了边界,将比例量1设置为0 - 你应该能够在恒定时间内实现(O(1))。
如果数组未排序,您可以做的最好是线性时间(O(n))。