Python 将字典添加到for循环中的列表时,未正确添加每次运行的last dict.key的值

Python 将字典添加到for循环中的列表时,未正确添加每次运行的last dict.key的值,python,arrays,numpy,dictionary,for-loop,Python,Arrays,Numpy,Dictionary,For Loop,我通过创建for循环,随机删除数据数组中的行并重新计算一个度量(sum)。在for循环的每次迭代中,我都会洗牌数据并删除第一行值。然后我对其余行中的值求和。对于每次迭代或运行,我希望跟踪运行次数、剩余点的总和以及删除的行。为此,我为每次运行创建一个结果字典,然后将这些结果附加到列表中。但是,当我打印结果字典列表时,运行编号和总和是正确的,但是每个结果字典中删除行的值似乎总是上次运行中删除的行,而不是其特定运行中的值 import random import numpy as np Points

我通过创建for循环,随机删除数据数组中的行并重新计算一个度量(sum)。在for循环的每次迭代中,我都会洗牌数据并删除第一行值。然后我对其余行中的值求和。对于每次迭代或运行,我希望跟踪运行次数、剩余点的总和以及删除的行。为此,我为每次运行创建一个结果字典,然后将这些结果附加到列表中。但是,当我打印结果字典列表时,运行编号和总和是正确的,但是每个结果字典中删除行的值似乎总是上次运行中删除的行,而不是其特定运行中的值

import random
import numpy as np

Points = np.array([[1,1,1,1],[2,2,2,2],[3,3,3,3],[4,4,4,4],[5,5,5,5],[6,6,6,6]])
index = 1
all_results = []
N = 5
for i in range(N):
    np.random.shuffle(Points)
    removed_row = Points[:index]
    print(f'Removed row from run {i}: {removed_row}')
    remaining_rows = Points[index:]
    sum = np.sum(remaining_rows)
    run_results = {'Run':i,"Sum of remaining points": sum ,"Removed row": removed_row}
    all_results.append(run_results)
print(all_results)

#output
Removed row from run 0: [[2 2 2 2]]
Removed row from run 1: [[2 2 2 2]]
Removed row from run 2: [[4 4 4 4]]
Removed row from run 3: [[5 5 5 5]]
Removed row from run 4: [[4 4 4 4]]
[{'Run': 0, 'Sum of remaining points': 76, 'Removed row': array([[4, 4, 4, 4]])}, {'Run': 1, 'Sum of remaining points': 76, 'Removed row': array([[4, 4, 4, 4]])}, {'Run': 2, 'Sum of remaining points': 68, 'Removed row': array([[4, 4, 4, 4]])}, {'Run': 3, 'Sum of remaining points': 64, 'Removed row': array([[4, 4, 4, 4]])}, {'Run': 4, 'Sum of remaining points': 68, 'Removed row': array([[4, 4, 4, 4]])}]


如您所见,它似乎总是使用上次运行的“删除的行”变量,而不是运行特定的“删除的行”

您需要实际删除行:

import random
import numpy as np

Points = np.array([[1,1,1,1],[2,2,2,2],[3,3,3,3],[4,4,4,4],[5,5,5,5],[6,6,6,6]])
index = 1
all_results = []
N = 5
for i in range(N):
    np.random.shuffle(Points)
    removed_row = Points[:index]
    Points = Points[index:]     # <<<<<<< Remove row
    print(f'Removed row from run {i}: {removed_row}')
    remaining_rows = Points[index:]
    sum = np.sum(remaining_rows)
    run_results = {'Run':i,"Sum of remaining points": sum ,"Removed row": removed_row}
    all_results.append(run_results)
print(all_results)

嗯,这确实很棘手

问题在于任务:

run_results = {'Run':i,"Sum of remaining points": sum ,"Removed row": removed_row}
它存储对
removed\u行的引用,就像在Python中一样,变量只是对对象的引用

创建新数组
np.array(已删除的行)

输出:

Removed row from run 0: [[4 4 4 4]]
Removed row from run 1: [[6 6 6 6]]
Removed row from run 2: [[6 6 6 6]]
Removed row from run 3: [[3 3 3 3]]
Removed row from run 4: [[4 4 4 4]]
[{'Run': 0, 'Sum of remaining points': 68, 'Removed row': array([[4, 4, 4, 4]])}, {'Run': 1, 'Sum of remaining points': 60, 'Removed row': array([[6, 6, 6, 6]])}, {'Run': 2, 'Sum of remaining points': 60, 'Removed row': array([[6, 6, 6, 6]])}, {'Run': 3, 'Sum of remaining points': 72, 'Removed row': array([[3, 3, 3, 3]])}, {'Run': 4, 'Sum of remaining points': 68, 'Removed row': array([[4, 4, 4, 4]])}]

注意,洗牌需要很多时间。以下是一种矢量化方法:

# choose the index to drop first:
to_drop = np.random.choice(np.arange(len(Points)), N, replace=False)

# remain sum:
remains = Points.sum(0) - Points[to_drop[::-1]].cumsum(0)

out = [{'run':i, 'sum_renmaining': remains[i], 'remove row': Points[to_drop[i]]} for i in range(N)]
Removed row from run 0: [[4 4 4 4]]
Removed row from run 1: [[6 6 6 6]]
Removed row from run 2: [[6 6 6 6]]
Removed row from run 3: [[3 3 3 3]]
Removed row from run 4: [[4 4 4 4]]
[{'Run': 0, 'Sum of remaining points': 68, 'Removed row': array([[4, 4, 4, 4]])}, {'Run': 1, 'Sum of remaining points': 60, 'Removed row': array([[6, 6, 6, 6]])}, {'Run': 2, 'Sum of remaining points': 60, 'Removed row': array([[6, 6, 6, 6]])}, {'Run': 3, 'Sum of remaining points': 72, 'Removed row': array([[3, 3, 3, 3]])}, {'Run': 4, 'Sum of remaining points': 68, 'Removed row': array([[4, 4, 4, 4]])}]
# choose the index to drop first:
to_drop = np.random.choice(np.arange(len(Points)), N, replace=False)

# remain sum:
remains = Points.sum(0) - Points[to_drop[::-1]].cumsum(0)

out = [{'run':i, 'sum_renmaining': remains[i], 'remove row': Points[to_drop[i]]} for i in range(N)]