重新采样对象的麻烦

时间:2016-07-22 03:54:57

标签: python python-3.x numpy

我有一个有两个属性的类:值weight和权重update()。然后我列出了这些。

作为第2步中的第1步,我想从此对象列表中进行替换。由于它采用替换进行采样,因此结果列表通常会有重复的对象(具有匹配值和权重的对象)。

作为2的第2步,我想抖动每个对象'值。每个对象都有update()方法。它为其价值对象增加了一些噪音。在调用copy.deepcopy之后,我不希望具有匹配值的对象具有匹配值。

如何获得理想的行为?最快的方法是什么?我曾与import numpy as np class MyClass: def __init__(self, val, weight): self.val = val self.weight = weight def update(self): self.val += np.random.normal() np.random.seed(1) orig = [MyClass(np.random.normal(), np.abs(np.random.normal())) for _ in range(10)] wt = [elem.weight for elem in orig] wt /= np.sum(wt) shuffled = np.random.choice(a=orig, size=len(orig), replace=True, p=wt) for o in shuffled: o.update() [o.val for o in shuffled] print(shuffled[0].val == shuffled[2].val) # not ok 玩过,但我无法改变行为。以下是一个小例子。

np.random.seed(1)        
orig = [MyClass(np.random.normal(), np.abs(np.random.normal())) for _ in range(10)]
wt = [elem.weight for elem in orig]
wt /= np.sum(wt)
idx = np.random.choice(len(orig), size=len(orig), replace=True, p=wt)
vs = [orig[i].val for i in idx]
ws = [orig[i].weight for i in idx]
shuffled = [MyClass(v,w) for v,w in zip(vs,ws)]
for o in shuffled:
    o.update()
[o.val for o in shuffled]

编辑:

这很有效。但有更快的方法吗?为什么我需要重新实例化?

{{1}}

1 个答案:

答案 0 :(得分:1)

你真的需要class MyClass吗?我认为,在拥有异构数据和附带方法的集合和/或使用继承的情况下,应该使用面向对象的代码。由于您只是使用NxM浮点数,因此在这里使用numpy.array更容易理解,维护和使用,恕我直言:

import numpy as np

def update(x):
    x += np.random.normal(size=x.size)

def equal_elem(x):
    x.sort()
    v = np.searchsorted(x, x)
    return np.any(v - np.arange(v.size))

size = 10

vals = np.random.normal(size=size)
weights = np.abs(np.random.normal(size=size))
weights /= weights.sum()

svals = np.random.choice(vals, size=vals.size, replace=True, p=weights)
update(svals)
while equal_elem(svals):
    update(svals)

equal_elem检查可能会使用svals中的当前值再次抖动svals中的所有元素。如果您想避免这种情况,可以创建另一个变量retvals,并更改update函数以返回数组,而不是就地修改它。