为什么在变平ndarrays列表时,我会得到副本而不是参考?

发布于 2025-01-18 15:22:52 字数 1676 浏览 4 评论 0原文

如何获取 ndarrays 中每个元素的引用?

目标是获取包含基元的可变形状 ndarrays列表,对所有 ndarrays 使用 ravel()并将它们合并成一个list,其中元素都是对ndarrayslist中元素的引用。

这是我的尝试。需要明确的是,weightsndarrayslist,我希望 weights_unraveled 是一个一维 >list 包含对每个 ndarray 中每个元素的引用。

def unravel_weights(weights):
    weights_unraveled = []
    for w in weights:
        weights_unraveled.extend(w.ravel())
    return weights_unraveled

我知道 w.ravel() 返回一个一维 list,其中引用了 w 的元素,并将其分配给另一个变量不会产生复制。我已经测试过了。将值传递给函数是否会生成副本?从函数返回的值是否会生成副本?我对此表示怀疑,因为作业没有。

如果 extend() 正在制作副本,我该如何停止它,或者如何合并 w.ravel() 返回的引用的 列表 > 放入单个 list 中,其中包含对每个 ndarray 中每个元素的引用?

这是表现出不良行为的代码。

    flat_child_weights = unravel_weights(child_weights)
    flat_parent_weights = unravel_weights(weights1) 
    for i in range(len(flat_child_weights)):
        change = random.choice([True, False])
        if change:
            flat_child_weights[i] = flat_parent_weights[i]

分配unravel_weights的返回值时是否进行了复制?我也怀疑。

调试已验证 flat_child_weightsflat_parent_weights 确实是一维 list,但它们是 child_weights的副本>权重1分别。需要明确的是,flat_child_weights[i] = flat_parent_weights[i] 确实更改了 flat_child_weights 的元素,但这些更改不会反映在 child_weights 中。

如何获取 child_weights 的元素以反映 flat_child_weights 的变化?

And how do I get references to each element in the ndarrays?

The goal is to take a list of variable shaped ndarrays containing primitives, use ravel() on all the ndarrays and merge them into a list who elements are all references to the elements in the list of ndarrays.

Here is my attempt at this. To be clear, weights is a list of ndarrays, and I want weights_unraveled to be a one dimensional list containing references to every element in each ndarray.

def unravel_weights(weights):
    weights_unraveled = []
    for w in weights:
        weights_unraveled.extend(w.ravel())
    return weights_unraveled

I know that w.ravel() returns a one dimensional list with references to elements of w and assigning it to another variable does not make a copy. I have tested it. Does passing the value to a function make a copy? Does the returning of a value from a function make a copy? I doubt it because assignment did not.

If extend() is making copies, how do I stop it, or how do I merge the list of references returned by w.ravel() into a single list containing references to every element in each ndarray?

This is the code that manifests the undesired behavior.

    flat_child_weights = unravel_weights(child_weights)
    flat_parent_weights = unravel_weights(weights1) 
    for i in range(len(flat_child_weights)):
        change = random.choice([True, False])
        if change:
            flat_child_weights[i] = flat_parent_weights[i]

Is a copy being made when assigning the return value of unravel_weights? I also doubt it.

Debugging has verified that flat_child_weights and flat_parent_weights are indeed one dimensional lists, but they are copies of child_weights and weights1 respectively. To be clear, flat_child_weights[i] = flat_parent_weights[i] does change the elements of flat_child_weights, but the changes are not reflected in child_weights.

How can I get the elements of child_weights to reflect changes in flat_child_weights?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

哥,最终变帅啦 2025-01-25 15:22:52

您可以从numpy调用中获得参考而不是副本,因为它们返回视图而不是副本,与array.extend.extend不同。这是一种可以做同样的方法,尽管它需要一些前期工作。您删除了旧问题,因此我无法参考该代码。

如果我还记得,您从ndarray s的列表开始,因为ndarray s是不同的长度,因此不能直接变成2D ndarray。这将替换您的Unravel_Weights

  1. 创建一个1D ndArray,所有权重扁平:
flat_child_weights = np.concatenate([weights.ravel() for weights in child_weights)
  1. 将输出链接到扁平的重量上的工作的关键步骤:从 view flat_child_weights,类似:
child_weights_new = []
index = 0
for weights in child_weights:
    child_weights_new.append(flat_child_weights[index:index+weights.size()].reshape(weights.shape))
    index += weights.size()

现在您可以在flat_child_weightschild_weights_new上进行/code>),因此返回child_weights_new

You get references instead of copies from your numpy calls because they return views and not copies, unlike the array.extend. Here is a method that will do the same, though it requires some upfront work. You deleted your old question, so I cannot reference that code.

If I recall, you started with a list of ndarrays, which could not be directly turned into a 2D ndarray because the ndarrays are different lengths. This will replace your unravel_weights.

  1. Create a 1D ndarray with all the weights flattened:
flat_child_weights = np.concatenate([weights.ravel() for weights in child_weights)
  1. Key step to link your output to the work on the flattened weights: recreate child_weights from views of flat_child_weights, something like:
child_weights_new = []
index = 0
for weights in child_weights:
    child_weights_new.append(flat_child_weights[index:index+weights.size()].reshape(weights.shape))
    index += weights.size()

Now you can run through your work on the flat_child_weights, and child_weights_new will be updated (but not child_weights), so return child_weights_new.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文