我有一个有两个属性的类:值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}}
答案 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
函数以返回数组,而不是就地修改它。