【问题标题】:Numpy for loop gives a different result each timeNumpy for 循环每次都会给出不同的结果
【发布时间】:2016-04-12 10:26:20
【问题描述】:

第一次在这里发布,就这样吧:

我有两组数据(v 和 t),每组有 46 个值。数据通过“pandas”模块导入并转换为 numpy 数组以进行计算。

我需要将 ml_min1[45]、ml_min2[45] 等设置为值“0”。问题是每次我运行脚本时,ml_min1和ml_min2的位置45对应的值都不一样。这是我拥有的一段代码:

t1 = fil_copy.t1.as_matrix()
t2 = fil_copy.t2.as_matrix()
v1 = fil_copy.v1.as_matrix()
v2 = fil_copy.v2.as_matrix()

ml_min1 = np.empty(len(t1))
l_h1 = np.empty(len(t1))

ml_min2 = np.empty(len(t2))
l_h2 = np.empty(len(t2))

for i in range(0, (len(v1) - 1)):

    if (i != (len(v1) - 1)) and (v1[i+1] > v1[i]):
        ml_min1[i] = v1[i+1] - v1[i]
        l_h1[i] = ml_min1[i] * (60/1000)
    elif i == (len(v1)-1):
        ml_min1[i] = 0
        l_h1[i] = 0
        print(i, ml_min1[i])
    else:
        ml_min1[i] = 0
        l_h1[i] = 0
        print(i, ml_min1[i])

for i in range(0, (len(v2) - 1)):

    if (i != (len(v2) - 1)) and (v2[i+1] > v2[i]):
        ml_min2[i] = v2[i+1] - v2[i]
        l_h2[i] = ml_min2[i] * (60/1000)
    elif i == (len(v2)-1):
        ml_min2[i] = 0
        l_h2[i] = 0
        print(i, ml_min2[i])
    else:
        ml_min2[i] = 0
        l_h2[i] = 0
        print(i, ml_min2[i])

【问题讨论】:

  • 不知道它是否相关,但i 永远不会等于len(v1) - 1,所以elif 都不会触发。另外,range(0, x) == range(x)。
  • 我猜你的意思是在 0 ≤ i range(len(v1))。但是由于您对最后一个i 的处理方式不同,实际上您可以使用range(len(v1) - 1) 并将elif 主体移动到for 循环之后(使用-1 作为索引而不是i)。
  • "我需要将 v1[45], v2[45] 设置为值 "0"" - 在这段代码中,您没有修改任何一个元素v1v2
  • @Marcelo Cantos 有一点,我在其中进行计算v1[i+1] - v1[i],所以当 i = 45, v1[i+1] = v1[46] 时,它不存在。我认为,这就是问题所在,所以我做了 elif 声明:elif i == (len(v2)-1;为了将 i-postion 45 值设置为零。
  • @ali_m 我的错误,我的意思是ml_min1l_h1,...等等。

标签: python for-loop numpy pandas


【解决方案1】:

您当前编写的代码不起作用,因为elif 块永远不会被命中,因为range(0, x) 不包括x(它在到达那里之前就停止了)。解决这个问题的最简单方法可能只是使用numpy.zeros 而不是numpy.empty 初始化输出数组,因为那时您不需要在elifelse 块中执行任何操作(您可以删除它们)。

也就是说,在 numpy 代码中使用像您这样的循环通常是设计错误。相反,您应该使用 numpy 的广播功能一次对整个数组(或一个数组的一部分)执行数学运算。

如果我理解正确,以下内容应该等同于您希望代码执行的操作(仅对于其中一个数组,另一个应该相同):

ml_min1 = np.zeros(len(t1)) # use zeros rather than empty, so we don't need to assign any 0s
diff = v1[1:] - v1[:-1]     # find the differences between all adjacent values (using slices)
mask = diff > 0             # check which ones are positive (creates a Boolean array)
ml_min1[:-1][mask] = diff[mask]   # assign with mask to a slice of the ml_min1 array
l_h1 = ml_min1 * (60/1000)  # create l_h1 array with a broadcast scalar multiplication

【讨论】:

  • 谢谢@Blckknght !!!我什至没有考虑过这个选项,我应该了解更多关于 numpy 的信息。您的“广播”解决方案更加优雅、省时且易于理解。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-12
  • 2018-05-02
  • 1970-01-01
相关资源
最近更新 更多