首页 > 解决方案 > 先前方程的乘积会受到之后更改输入运算符的影响吗?

问题描述

这个有点难以解释,所以让我通过一个示例向您展示我所指的内容:

from statistics import mean
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import style
import random


# xs = np.array([1,2,3,4,5,6], dtype=np.float64)
# ys = np.array([5,4,6,5,6,7], dtype=np.float64)

def create_dataset(hm, variance, step=2, correlation=False):
    val = 1
    ys = [] # empty list
    for i in range(hm):
        y = val + random.randrange(-variance, variance)
        ys.append(y)
        if correlation and correlation == 'pos':
        val += step
        elif correlation and correlation == 'neg':
        val -= step

    xs = [i for i in range(len(ys))]
    return np.array(xs, dtype=np.float64), np.array(ys, dtype=np.float64)

现在让我们创建一个数据集:

xs, ys = create_dataset(30, 12, 2, correlation='pos')
print("X series: %s\n\nY series: %s" % (xs, ys))

示例输出:

X series: [  0.   1.   2.   3.   4.   5.   6.   7.   8.   9.  10.  11.  12.  13.  14.
  15.  16.  17.  18.  19.  20.  21.  22.  23.  24.  25.  26.  27.  28.  29.]

Y series: [  1.  -6.  10.   9.  -1.  13.  24.  21.  14.  12.  17.  29.  23.  37.  32.
  36.  25.  27.  27.  47.  36.  32.  51.  37.  50.  47.  61.  45.  65.  59.]

来自OOP背景,我对此有点困惑:

if correlation and correlation == 'pos':
   val += step

如您所见, val在已分配后已更改。 y但它似乎y仍然影响岗位分配。因此,这看起来好像某种方程式引用保存在内存中,并且结果可能会受到更改其任何运算符的影响。

为什么以及如何在 python 中实现这一点?在 C# 或 Java 中,一旦您分配原始浮点数或整数,除非您直接引用它,否则它不会改变。当您使用对象浮​​点数或整数时,我认为这是可能的,但前提是另一个变量被分配给同一个引用。将输入更改为先验方程也不会这样做 AFAIK。

无论如何,似乎发生了一些我不熟悉的与 python 相关的事情。

标签: pythonnumpyreference

解决方案


随机方差使得很难看到发生了什么val。所以让我们简化一下函数:

In [16]: def create_dataset(hm, step=2, correlation='pos'):
    ...:     val = 1
    ...:     ys = [] # empty list
    ...:     for i in range(hm):
    ...:         y = val
    ...:         ys.append(y)
    ...:         if correlation and correlation == 'pos':
    ...:             val += step
    ...:         elif correlation and correlation == 'neg':
    ...:             val -= step
    ...:     return ys

In [17]: create_dataset(5, 2, "pos")
Out[17]: [1, 3, 5, 7, 9]
In [18]: create_dataset(5, 2, "neg")
Out[18]: [1, -1, -3, -5, -7]

这就是我所期望的。 val每次迭代递增step(或递减)一次。并且新值存储ys在下一个循环中。

In [19]: val = 0
In [20]: val += 12
In [21]: val
Out[21]: 12
In [22]: val *= 2
In [23]: val
Out[23]: 24

对于这样的数字与以下val -= 12内容相同:

In [24]: val = val - 12
In [25]: val
Out[25]: 12

一个新号码被分配给val

'+' 和 '+=' 转换为方法调用:

val + 12  => val.__add__(12)
val +=12  => val.__iadd__(12)

这些方法是为每种对象类型定义的,因此细节可能因类型而异。

对于像列表和 numpy 数组这样的可变对象,'+' 和 '+=' 之间的差异更为显着,有时会导致迭代出现问题。

我相信 C 和/或 C++ 有i++ 操作。这有点像a += 1


推荐阅读