更多关于数组的内容

通常我们需要计算涉及多个数组的数据。如果两个数组大小相同,Python 可以轻松地进行涉及两个数组的计算。

在我们的第一个示例中,我们再次回到温度数据。这次,我们创建了 1850 年、1900 年、1950 年和 2000 年前后几十年间的日均高温低温数组。

[In ]:
from datascience import *
import numpy as np
path_data = '../../../assets/data/'
[In ]:
baseline_high = 14.48
highs = make_array(baseline_high - 0.880, 
                   baseline_high - 0.093,
                   baseline_high + 0.105, 
                   baseline_high + 0.684)
highs
array([13.6  , 14.387, 14.585, 15.164])
[In ]:
baseline_low = 3.00
lows = make_array(baseline_low - 0.872, baseline_low - 0.629,
                  baseline_low - 0.126, baseline_low + 0.728)
lows
array([2.128, 2.371, 2.874, 3.728])

假设我们要计算每个十年间的日均气温差值。也就是说,我们想用 1850 年代的日均低温减去该年代的日均高温,其余每个十年同理。

我们可以用 .item 费力地写出:

[In ]:
make_array(
    highs.item(0) - lows.item(0),
    highs.item(1) - lows.item(1),
    highs.item(2) - lows.item(2),
    highs.item(3) - lows.item(3)
)
array([11.472, 12.016, 11.711, 11.436])

就像我们将温度数组从摄氏转换为华氏时一样,Python 提供了一种更简洁的写法:

[In ]:
highs - lows
array([11.472, 12.016, 11.711, 11.436])

数组减法的图示。左侧显示 highs 数组,接着是减号,然后是 lows 数组。两个数组对齐,使第一个位置的数彼此相邻,第二、第三、第四位置同理。接着是一个等号和一个数组表示,显示 highs 的第一个条目减去 lows 的第一个条目,第二、第三、第四个条目同理。接着是另一个等号,显示一个数组,其中每个条目是相减的结果。

我们在这些示例中看到的是数组一般特性的特例。

数值数组对的逐元素算术运算

如果一个算术运算符作用于两个大小相同的数组,则运算会在这两个数组的每对对应元素上执行。最终结果是一个数组。

例如,如果 array1array2 元素数量相同,那么 array1 * array2 的结果是一个数组。其第一个元素是 array1 的第一个元素乘以 array2 的第一个元素,第二个元素是 array1 的第二个元素乘以 array2 的第二个元素,依此类推。

示例:沃利斯的 $\pi$ 公式

数字 $\pi$ 在数学的许多不同领域中都很重要。在计算机发明之前的几个世纪里,数学家们一直在寻找逼近 $\pi$ 数值的简单方法。我们已经看到了莱布尼茨的 $\pi$ 公式。大约在莱布尼茨之前半个世纪,英国数学家 约翰·沃利斯(1616-1703)也将 $\pi$ 用简单分数表示为一个无穷乘积。

$$ \pi = 2 \cdot \left( \frac{2}{1}\cdot\frac{2}{3}\cdot\frac{4}{3}\cdot\frac{4}{5}\cdot\frac{6}{5}\cdot\frac{6}{7}\dots \right) $$

这是 “偶数/奇数” 分数的乘积。让我们用数组将一百万个这样的分数相乘,看看乘积是否接近 $\pi$。

记住乘法可以按任意顺序进行 [1],因此我们可以重新调整计算为:

$$\pi \approx 2 \cdot \left( \frac{2}{1} \cdot \frac{4}{3} \cdot \frac{6}{5} \cdots \frac{1,000,000}{999999} \right) \cdot \left( \frac{2}{3} \cdot \frac{4}{5} \cdot \frac{6}{7} \cdots \frac{1,000,000}{1,000,001} \right)$$

现在我们准备进行计算。首先创建一个偶数数组:2, 4, 6,一直到 1,000,000。然后创建两个奇数列表:1, 3, 5, 7, ... 到 999,999,以及 3, 5, 7, ... 到 1,000,001。

[In ]:
even = np.arange(2, 1000001, 2)
one_below_even = even - 1
one_above_even = even + 1

记住 np.prod 将数组的所有元素相乘。现在我们可以计算沃利斯乘积,得到一个很好的近似值。

[In ]:
2 * np.prod(even/one_below_even) * np.prod(even/one_above_even)
3.1415910827951143

这与 $\pi$ 精确到小数点后五位。沃利斯显然提出了一个伟大的公式。

(footnotes)=

脚注

[1] 正如我们在莱布尼茨公式示例中看到的,当我们将无穷多个分数相加时,顺序会起作用。对于分数的乘法也是如此,就像我们这里所做的。但我们求 $\pi$ 的近似值只用了大量有限的分数,因此按任意方便的顺序相乘都是可以的。