在对象列表上使用 numpy 选择时生成新对象

Posted

技术标签:

【中文标题】在对象列表上使用 numpy 选择时生成新对象【英文标题】:Generating new objects when using numpy choice on a list of objects 【发布时间】:2022-01-22 14:31:00 【问题描述】:

我有一个对象列表。我使用带有替换的 numpy 选择从列表中选择多个对象。问题是我正在生成对同一个对象的多个引用。我想要的是生成一个完整的 new 对象列表。

这是我的代码:

import numpy as np
class agent:
    def __init__(self, name):
        self.name = name
parents = []
parents.append(agent("John"))
parents.append(agent("Max"))
parents.append(agent("Alex"))
select_probs = [0.4, 0.3, 0.3]
new_generation = list(np.random.choice(people, 5, replace = True, p = select_probs))
print(new_generation)
# example of output
# [<__main__.agent object at 0x000001F360DC0760>, 
#  <__main__.agent object at 0x000001F360DC03D0>, 
#  <__main__.agent object at 0x000001F360DC0760>, 
#  <__main__.agent object at 0x000001F360DC0760>, 
#  <__main__.agent object at 0x000001F360DC03D0>]

如您所见,我的选择 0、2、3 是同一个对象。我希望他们成为不同的人。将 0x000001F360DC0760 视为父对象,将所选对象视为子对象。

有什么建议我可以使用 numpy 选择来生成新对象,而不是对旧对象的引用?

谢谢。

【问题讨论】:

你为什么用numpy.choice开头?为此使用标准库random 模块。 无论如何,这些函数都不会永远隐式复制对象。如果您希望这种情况发生,您必须以某种方式自己处理(可能只是new_generation = [copy.copy(person) for person in new_generation],甚至[agent(a.name) for a in new_generation] 问题不在于选择功能。问题是当我选择同一个对象时,它会创建对同一个对象的另一个引用。例如,如果您选择整数,就不会遇到这个问题。我需要独立的副本,而不是对同一个副本的多次引用。 如果您使用 python 对象,即int 对象列表,您绝对会遇到同样的问题(当然,对于不可变对象来说,这不应该是个问题)对象)。这对 Python 来说是非常基础的。如果您使用 numpy.ndarray 对象,那就不同了,因为它们基本上是原始数组的包装器。将numpy.random 与 python 列表一起使用是没有意义的,这是我唯一的观点,在任何一种情况下,尽管这两个函数的工作方式相同 您可以在名称上choice,然后从中制作新的对象。 【参考方案1】:

所以上面的解决方案几乎正是我需要的一个小修正:我需要使用深拷贝而不是“浅”拷贝:

new_generation = [copy.deepcopy(person) for person in new_generation]

【讨论】:

嗯,不,你没有,在你发布的例子中没有。

以上是关于在对象列表上使用 numpy 选择时生成新对象的主要内容,如果未能解决你的问题,请参考以下文章

numpy数组的对象列表

AttributeError:“列表”对象没有属性“numpy”

带有自定义对象的可编辑列表视图

如何使用另一个列表中的对象的属性创建一个新列表

Python 酸洗错误:TypeError:对象泡菜未返回列表。 numpy的问题?

使用 Tensorflow 的 numpy_input_fn 会抛出“列表对象没有属性形状”