快速上手NumPy
阅读原文时间:2021年05月12日阅读:1

NumPy is the fundamental package for scientific computing in Python.

NumPy是一个开源的Python科学计算库。

官网:https://numpy.org/

文档:https://numpy.org/doc/

对于相同的数值计算任务,使用NumPy比直接使用Python要简洁、高效的多。

NumPy使用ndarray来处理多维数组。

NumPy provides an N-dimensional array type, the ndarray, which describes a collection of “items” of the same type. The items can be indexed using for example N integers.

NumPy提供了一个N维数组类型ndarray,它描述了相同类型的items的集合。

比如下面的学生成绩:

语文

数学

英语

物理

化学

92

99

91

85

90

95

85

88

81

88

85

81

80

78

86

ndarray进行存储:

In [1]:

import numpy as np

score = np.array(
[[92, 99, 91, 85, 90],
[95, 85, 88, 81, 88],
[85, 81, 80, 78, 86]])

score

Out[1]:

array([[92, 99, 91, 85, 90],
[95, 85, 88, 81, 88],
[85, 81, 80, 78, 86]])

用数据说话。所以,这里先通过几行代码来比较ndarray与Python原生的list的执行效率。

In [2]:

import random
import time
import numpy as np

list = [random.random() for i in range(10000000)]

array = np.array(list)

使用%time魔法方法, 可查看当前行的代码运行一次所花费的时间

%time sum_array = np.sum(array)

%time sum_list = sum(list)

CPU times: user 4.59 ms, sys: 3 µs, total: 4.59 ms
Wall time: 4.6 ms
CPU times: user 37.2 ms, sys: 155 µs, total: 37.4 ms
Wall time: 37.2 ms

可以看到ndarray的计算速度要快很多。机器学习通常有大量的数据运算,如果没有一个高效的运算方案,很难流行起来。

NumPy对ndarray的操作和运算进行了专门的设计,所以数组的存储效率和输入输出性能远优于Python中的嵌套列表,数组越大,NumPy的优势就越明显。

那么自然要问了,ndarray为什么这么快?

  • 在内存分配上,ndarray相邻元素的地址是连续的,而python原生list是通过二次寻址方式找到下一个元素的具体位置。如下图所示:

其中图片来自:

https://jakevdp.github.io/blog/2014/05/09/why-python-is-slow/

一个ndarray占用内存中一个连续块,并且元素的类型都是相同的。所以一旦确定了ndarray的元素类型以及元素个数,它的内存占用就确定了。而原生list则不同,它的每个元素在list中其实是一个地址引用,这个地址指向存储实际元素数据的内存空间,也就是说指向的内存不一定是连续的。

  • numpy底层使用C语言编写,内部解除了GIL(全局解释器锁)限制。

In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython’s memory management is not thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.)

  • numpy支持并行运算,系统有多个核时,条件允许的话numpy会自动发挥多核优势。

一维数组

In [3]:

a1 = np.array([1, 2, 3])
a1

Out[3]:

array([1, 2, 3])

In [4]:

# 数组维度
a1.ndim

Out[4]:

1

In [5]:

# 数组形状
a1.shape

Out[5]:

(3,)

In [6]:

# 数组元素个数
a1.size

Out[6]:

3

In [7]:

# 数组元素的类型
a1.dtype

Out[7]:

dtype('int64')

In [8]:

# 一个数组元素的长度(字节数)
a1.itemsize

Out[8]:

8

ndarray的元素类型如下表所示:

类型

描述

简写

bool

用一个字节存储的布尔类型(True或False)

'b'

int8

一个字节大小,-128 至 127

'i'

int16

整数,-32768 至 32767

'i2'

int32

整数,-2^31 至 2^31 -1

'i4'

int64

整数,-2^63 至 2^63 - 1

'i8'

uint8

无符号整数,0 至 255

'u'

uint16

无符号整数,0 至 65535

'u2'

uint32

无符号整数,0 至 2^32 - 1

'u4'

uint64

无符号整数,0 至 2^64 - 1

'u8'

float16

半精度浮点数:16位,正负号1位,指数5位,精度10位

'f2'

float32

单精度浮点数:32位,正负号1位,指数8位,精度23位

'f4'

float64

双精度浮点数:64位,正负号1位,指数11位,精度52位

'f8'

complex64

复数,分别用两个32位浮点数表示实部和虚部

'c8'

complex128

复数,分别用两个64位浮点数表示实部和虚部

'c16'

object_

python对象

'O'

string_

字符串

'S'

unicode_

unicode类型

'U'

创建数组的时候可指定元素类型。若不指定,整数默认int64,小数默认float64

In [9]:

np.array([1, 2, 3.0]).dtype

Out[9]:

dtype('float64')

In [10]:

np.array([True, True, False]).itemsize

Out[10]:

1

In [11]:

np.array(['Python', 'Java', 'Golang'], dtype=np.string_).dtype

Out[11]:

dtype('S6')

二维数组

In [12]:

a2 = np.array([
[1, 2, 3],
[1, 2, 3]
])
a2

Out[12]:

array([[1, 2, 3],
[1, 2, 3]])

In [13]:

# 数组维度
a2.ndim

Out[13]:

2

In [14]:

# 数组形状
a2.shape

Out[14]:

(2, 3)

In [15]:

# 数组元素个数
a2.size

Out[15]:

6

In [16]:

# 数组元素类型
a2.dtype

Out[16]:

dtype('int64')

In [17]:

# 一个数组元素的长度(字节数)
a2.itemsize

Out[17]:

8

三维数组

In [18]:

a3 = np.array([
[[1, 2, 3], [1, 2, 3]],
[[1, 2, 3], [1, 2, 3]],
[[1, 2, 3], [1, 2, 3]],
[[1, 2, 3], [1, 2, 3]]
])
a3

Out[18]:

array([[[1, 2, 3],
[1, 2, 3]],

   \[\[1, 2, 3\],  
    \[1, 2, 3\]\],

   \[\[1, 2, 3\],  
    \[1, 2, 3\]\],

   \[\[1, 2, 3\],  
    \[1, 2, 3\]\]\])

In [19]:

# 数组维度
a3.ndim

Out[19]:

3

In [20]:

# 数组形状
a3.shape

Out[20]:

(4, 2, 3)

In [21]:

# 数组元素个数
a3.size

Out[21]:

24

In [22]:

# 数组元素类型
a3.dtype

Out[22]:

dtype('int64')

In [23]:

# 一个数组元素的长度(字节数)
a3.itemsize

Out[23]:

8

从现有数组生成

In [24]:

score

Out[24]:

array([[92, 99, 91, 85, 90],
[95, 85, 88, 81, 88],
[85, 81, 80, 78, 86]])

In [25]:

# 相当于深拷贝
arr1 = np.array(score)
arr1

Out[25]:

array([[92, 99, 91, 85, 90],
[95, 85, 88, 81, 88],
[85, 81, 80, 78, 86]])

In [26]:

# 相当于浅拷贝, 并没有copy完整的array对象
arr2 = np.asarray(score)
arr2

Out[26]:

array([[92, 99, 91, 85, 90],
[95, 85, 88, 81, 88],
[85, 81, 80, 78, 86]])

In [27]:

score[0, 0] = 100

In [28]:

score

Out[28]:

array([[100, 99, 91, 85, 90],
[ 95, 85, 88, 81, 88],
[ 85, 81, 80, 78, 86]])

In [29]:

arr1

Out[29]:

array([[92, 99, 91, 85, 90],
[95, 85, 88, 81, 88],
[85, 81, 80, 78, 86]])

In [30]:

arr2

Out[30]:

array([[100, 99, 91, 85, 90],
[ 95, 85, 88, 81, 88],
[ 85, 81, 80, 78, 86]])

从上面的结果可以看出:传入ndarray时,np.array()会copy完整的ndarray,而np.asarray()不会。

注意:传入的参数是ndarray,并非Python原生的list。这两种情况不能混淆。下面看下传入list是啥结果。

In [31]:

nums = [1, 2, 3]
nums

Out[31]:

[1, 2, 3]

In [32]:

array1 = np.array(nums)
array1

Out[32]:

array([1, 2, 3])

In [33]:

array2 = np.asarray(nums)
array2

Out[33]:

array([1, 2, 3])

现在修改list中的元素:

In [34]:

nums[0] = 10
nums

Out[34]:

[10, 2, 3]

In [35]:

array1

Out[35]:

array([1, 2, 3])

In [36]:

array2

Out[36]:

array([1, 2, 3])

生成0和1的数组

  • 生成元素全为0的数组

In [37]:

np.zeros([3, 2], dtype=np.int64)

Out[37]:

array([[0, 0],
[0, 0],
[0, 0]])

In [38]:

# Return an array of zeros with the same shape and type as a given array.
np.zeros_like(score)

Out[38]:

array([[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]])

  • 生成元素全为1的数组

In [39]:

np.ones([3, 2], dtype=np.int64)

Out[39]:

array([[1, 1],
[1, 1],
[1, 1]])

In [40]:

# Return an array of ones with the same shape and type as a given array.
np.ones_like(score)

Out[40]:

array([[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]])

生成固定范围的数组

  • 创建等差数组(指定步长, 即等差数列中的公差)

In [41]:

# Return evenly spaced values within a given interval.
np.arange(10, 50, 5)

Out[41]:

array([10, 15, 20, 25, 30, 35, 40, 45])

  • 创建等差数组(指定元素个数)

In [42]:

np.linspace(2.0, 3.0, num=5)

Out[42]:

array([2. , 2.25, 2.5 , 2.75, 3. ])

In [43]:

# If endpoint True, 3.0 is the last sample. Otherwise, 3.0 is not included.
np.linspace(2.0, 3.0, num=5, endpoint=False)

Out[43]:

array([2. , 2.2, 2.4, 2.6, 2.8])

  • 创建等比数列

In [44]:

np.logspace(2, 5, num=4, dtype=np.int64)

Out[44]:

array([ 100, 1000, 10000, 100000])

In [45]:

np.logspace(2, 5, num=4, base=3, dtype=np.int64)

Out[45]:

array([ 9, 27, 81, 243])

默认base=10.0,第一个例子中生成num=4个元素的等比数列,起始值是10^2,终止值是10^5,所以等比数列为[100, 1000, 10000, 100000]

同理,第二个例子中也是生成num=4个元素的等比数列,不过base=3,起始值是3^2,终止值是3^5,所以等比数列为[9, 27, 81, 243]

生成随机数组

实际生产中的数据大多可能是随机数值,而这些随机数据往往又符合某些规律。下面会涉及到概率论的一点点知识,无需畏惧,其实初高中数学就或多或少接触过。

均匀分布

In [46]:

# 生成均匀分布的随机数
x1 = np.random.uniform(0, 10, 100000)
x1

Out[46]:

array([5.76720988, 5.32880068, 7.58561359, …, 7.59316418, 8.30197616,
4.38992042])

所谓均匀分布,指的是相同间隔内的分布概率是等可能的。直方图可用于较直观地估计一个连续变量的概率分布。 下面简要回顾一下画直方图的步骤,也能加深对使用场景的理解。

(1) 收集数据(数据一般应大于50个)

(2) 确定数据的极差(用数据的最大值减去最小值)

(3) 确定组距。先确定直方图的组数,然后以此组数去除极差,可得直方图每组的宽度,即组距

(4) 确定各组的界限值。为避免出现数据值与组界限值重合而造成频数据计算困难,组的界限值单位应取最小测量单位的1/2

(5) 编制频数分布表。把多个组上下界限值分别填入频数分布表内,并把数据表中的各个数据列入相应的组,统计各组频数据

(6) 按数据值比例画出横坐标

(7) 按频数值比例画纵坐标。以观测值数目或百分数表示

(8) 画直方图。按纵坐标画出每个长方形的高度,它代表取落在此长方形中的数据数。

下面用matplotlib帮助我们画图。

In [47]:

import matplotlib.pyplot as plt

创建画布

plt.figure(figsize=(10, 5), dpi=100)

画直方图, x代表要使用的数据,bins表示要划分区间数

plt.hist(x=x1, bins=20)

设置坐标轴刻度

plt.xticks(np.arange(0, 10.5, 0.5))
plt.yticks(np.arange(0, 6000, 500))

添加网格显示

plt.grid(True, linestyle='--', alpha=0.8)

显示图像

plt.show()

![](data:image/png;base64,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

)

从上图可以直观的看到,100000[0, 10)范围内的样本数据,落在区间[0,0.5)[0.5,1.0)、…、[9.0,9.5)[9.5,10.0)内频数都近乎5000,符合均匀分布规律。

正态分布

正态分布也是一种概率分布。正态分布是具有两个参数μσ的连续型随机变量的分布,参数μ是随机变量的期望(即均值),决定了其位置; 参数σ是随机变量的标准差,决定了其分布的幅度。

若随机变量X服从一个数学期望为μ、方差为σ^2的正态分布,记为N(μ,σ^2)。当μ = 0,σ = 1时的正态分布是标准正态分布。

类似上面的均匀分布,我们通过生成样本数据,画图观察正态分布状况。

已知某地区成年男性身高近似服从正态分布。下面生成均值为170,标准差为5的100000个符合正态分布规律的样本数据。

In [48]:

x2 = np.random.normal(170, 5, 100000)
x2

Out[48]:

array([177.45732513, 171.49250483, 159.53980655, …, 156.38843943,
172.38350177, 164.87975538])

同样使用matplotlib帮助我们画图。

In [49]:

import matplotlib.pyplot as plt

创建画布

plt.figure(figsize=(10, 5), dpi=100)

画直方图

plt.hist(x=x2, bins=100)

添加网格显示

plt.grid(True, linestyle='--', alpha=0.8)

显示图像

plt.show()

![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA0gAAAGlCAYAAADAotauAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAA9hAAAPYQGoP6dpAABOHklEQVR4nO3df3Ac533n+c+3ewBIAglI4OoHFMoCLYlYhRbOigKF0sKxL461umjjxKXaWpdlx0pyu463zK3YuU1s5Tb2JZesktheXbhJLnF8VkqX3Nlbyiq2fJZoOZHXWIE2VsU1KNqBSIkwJRMiLYIGSEgEMN3f+2MawGA4AxIkwXl6+v2qmgL5zDOD5+F8+XR/p7u/be4uAAAAAIAUNXsAAAAAABAKEiQAAAAAyJAgAQAAAECGBAkAAAAAMiRIAAAAAJAhQQIAAACADAkSAAAAAGRIkAAAAAAgU2r2ANaLmZmkayWdaPZYAAAAADTdRkmH3d1X69SyCZIqydHLzR4EAAAAgGBslvT91Tq0coJ0QpJeeukldXV1NXssAAAAAJpkZmZG1113nXQWZ5e1coIkSerq6spdgpQkiQ4cOKAbb7xRcRw3ezjAaYhRhI4YRR4QpwhdUWOUIg0BcndNTk7qDKdHAk1DjCJ0xCjygDhF6IoaoyRIAAAAAJAhQQIAAACADAlSgKIoUl9fn6KIjwdhIkYROmIUeUCcInRFjVFr1XMKzaxL0vT09HTuijQAAAAAuHBmZmbU3d0tSd3uPrNa32KlgzmRJInGxsaUJEmzhwLURYwidMQo8oA4ReiKGqMkSAFyd01NTRWuYgjygxhF6IhR5AFxitAVNUZJkAAAAAAgQ4IEAAAAABkSpABFUaT+/v7CVQxBfhCjCB0xijwgThG6osYoVewAAAAAtDSq2OVcuVzW6OioyuVys4cC1EWMInTEKPKAOEXoihqjJEiBmp2dbfYQgFURowgdMYo8IE4RuiLGKAkSAAAAAGRIkAAAAAAgU2r2AHC6OI41MDCgOI6bPRSgLmIUzdL30S83fG7iwXuW/lwbo2f7OuBiYi1F6IoaoyRIATIz9fT0NHsYQEPEKEK3lhgleUKzsJYidEWNURKkAJXLZe3evVvbt29XqcRHhPAQo1hPqyUsZ/u69sj1gZsT/dl3Y82ndqGGBlxQrKUIXVFjlGuQAlW0corIH2IUoWtnC4ccYC1F6IoYo2w+AAAAACBDggQAAAAAGRKkAMVxrMHBwcJVDEF+EKMI3UIqPfx8rIW02SMBGmMtReiKGqMkSIHq6Oho9hCAVRGjCJlLOrFQ+QmEjLUUoStijJIgBShJEg0PDytJkmYPBaiLGEXo2iNpx7aEQg0IGmspQlfUGGXTAQAAAACZ4hQ0BwAE41zvdQQAwHojQQIAXHAkQACAvDL31ryE1cy6JE1PT0+rq6ur2cNZE3dXkiSK41hm3AEe4SFGcSbNT5Bc7ZE0n0rSucfoxIP3XLARAbVYSxG6VorRmZkZdXd3S1K3u8+s1pdrkAI1NzfX7CEAqyJGETKTtLHtfFIj4OJgLUXoihijnGIXoCRJNDo6qqGhIZVKfEQIDzGK0LVF0v1bE+3cF2dHkc7NakfCOLqE88VaitAVNUY5ggQAAAAAmeKkggCAC6r51xkBAHDhcQQpUEU6jIl8IkYRuvM5tQ64WFhLEboixihV7AAA54QjSI1xfRIAhIUqdjnn7pqamlKrJq/IP2IUoTO5+ja4TMQowsVaitAVNUZJkAKUJInGxsaUJEmzhwLURYwidG2RdO+WRG1s5RAw1lKErqgxyqYDAAAAADIkSAAAAACQIUEKVGdnZ7OHAKyKGEXIXNKxU1yBhPCxliJ0RYxRqtgBAM4JVewao4odAISFKnY5l6apJicnlabcxANhIkYRushct1yRKrLW/BIQrYG1FKEraoySIAUoTVONj48XLhiRH8QoQlcy6a7NqUrW7JEAjbGWInRFjVESJAAAAADIrClBMrMPmtmYmc1kjxEz+5+qnjcz+4SZHTaz183saTPbVvMeHWa208xeNbNZM/uimW2u6XOFmT1iZtPZ4xEzu/y8ZgoAAAAAZ7DWI0gvS/qopB/PHn8n6W+rkqBfl/QRSR+SNCjpFUlfNbONVe/xkKR3SXq3pCFJGyQ9bmZxVZ+/lvRmSXdnjzdLemSNY80tM1NPT4/MODcEYSJGETqXNHGSKnYIG2spQlfUGD3vKnZmNiXp30r6vyQdlvSQu/9+9lyHpCOSfsPd/8zMuiX9QNL73P3zWZ9rJb0k6Wfc/Ukzu1nSdyRtd/dvZn22SxqR9I/dffwsx0UVOwBYR1SxOzdUuAOAi++iVLEzs9jM3i2pU5XkZYukayTtWuzj7nOSvi7pzqzpNkltNX0OS3quqs8dkqYXk6Osz25J01V9WlqappqYmCjcBXHID2IUoYvNdcdVqWKq2CFgrKUIXVFjtLTWF5jZLaokRJdIOinpXe7+HTNbTF6O1LzkiKTrsz9fI2ne3Y/X6XNNVZ+jdX710ao+9cbVIamjqmmjJJXLZZXL5cU+iuNYSZKo+shZFEWKoqhh++LrF8VxLDOr2y5JSZKcVXupVJK7n9YuSQcPHtQ111yjUqm0Yuxpmq4I0rzMqVQqNRw7c8rfnMrlsg4ePKjNmzfL3VtiTtXtrfI5rfec2iPXQlo5na295uu2+VQySW2ntZtMvqLdJS2kpsh8RdW5xfbYXHFVe+JS4o3b2yJXe+T6J1enGpuK9HoipVl79UkilbGb2qOVSdR6z0kSscecZGaan59fsb1vhTm14udU5Dm5+2n7pHmdU+3zq1lzgiRpXJVrgi6XdK+kvzSzt1Y9X/t1ndVpq1Xbp17/M73PxyR9vLZxZGRk6Q7Avb296u/v14EDBzQ5ObnUp6+vT319fdq3b5+mpqaW2vv7+9Xb26s9e/ZodnZ2qX1gYEA9PT3avXv3in/swcFBdXR0aHh4eMUYhoaGNDc3p9HR0aW2UqmkoaEhHT9+XGNjY0vtnZ2duvXWW1Uul7V79+6l9p6eHg0MDOjQoUOamJhYas/LnAYHB3XkyBGNjy+fIcmc8j2nubk5SWqpObXi57Sec9qxLdHDz8c6sVD5c7Wd+2JtbJPu37rcPp9KO/eVdP0G6d4ty+3HTpke3h9r2+WuuzYvbzwnTpoePRjr9itdd1693L53KtKu75vefq3rlp7l9meORBo5anrn9am2bHBddan0wZtTPflypL3HTffdkGrTJcubkUcPxpo4KX3g5mRFMrTec5JE7DEn9fT0aHR0VLOzs0vb+1aYUyt+TkWe0/bt2+XuK/ZJ8zqn6tecyYW4BukpSS9I+v3s54+5+56q5/9W0g/d/f1m9lOSviapp/ookpl9W9Jj7v5xM/slSZ9298trfs8PJX3Y3T/XYBz1jiC9fOzYsaVrkPLyjYIkfeMb39Add9zBESTmFOScyuWyRkZG9Ja3vEVm1hJzqm5vlc9pvef0o7/1RNBHkD54c6o//W6k1xML6gjS/t/7Z8Qec5KZ6dSpUxoZGVna3rfCnFrxcyrynNxdw8PDK/ZJ8zqnmZkZbdq0STqLa5DO5QhSLVMlMTmoStW6d0jaI0lm1i7prZJ+I+v7rKSFrM8Xsj69kt6kSgU8qXL6XreZ3e7u38r6/ISkbknPNBpEdr3T3NKgsmobpVJpxQcqLf+D1WrUXvv6C9luZqe1J0mia6+9Vm1tbaeNaTE4znbsocxJajx25pS/OZmZrr322qXFrZ68zakaczq7Mc6nVvXn0/t6w3ar2566ab7Od3aJm5I1tC+kptSlsalIp7LkaLG9nvmG7fXGfmHmROwxJ0lqa2uru73P85xa8XMq8pxW2yfN25waPV/3NWfdU5KZ/Z6kr6hSdW6jKqW63ybpbnd3M3tI0gNmtl/SfkkPSHpNlbLdcvdpM/uspE+Z2TFJU5I+KWmvpKeyPt81syckfcbMPpD96j+X9PjZVrDLuziO1d/f3+xhAA0Rowhd4qZd3y9WWVrkD2spQlfUGF3rEaSrVbkfUa8qVeXGVEmOvpo9/weSLpX0J5KukPRNSXe5+4mq9/iwpLIqR5AuVeWUu/vdvfoY3X2S/kjL1e6+qMq9lQohSRIdOHBAN954Y8PsGWgmYhShi8319mtdXztsSjysRGm18uiUAC8W1lKErqgxuqYy3+7+y+7e5+4d7n6Vu/90VXIkr/iEu/e6+yXu/lZ3f67mPU65+w533+Tul7n7z7r7SzV9ptz9ve7elT3e6+4/PK+Z5oi7a3JycsV5l0BIiFGELjbplp50xTVKQGhYSxG6osboOd8HCQAAAABaDQkSAAAAAGRIkAIURZH6+vrqVvoAQkCMInSJV+6LVK/KHRAK1lKErqgxeiHKfOMCWwxGIFTEKEKXuGnkKBcgIWyspQhdUWO0WOlgTiRJorGxsbo3kAVCQIwidG2R694tidoiDiEhXKylCF1RY5QEKUDurqmpqcJVDEF+EKMInUnq2+DiGBJCxlqK0BU1RkmQAAAAACBDggQAAAAAGRKkAEVRpP7+/sJVDEF+EKMIXdmlXS9HKhfrrBDkDGspQlfUGKWKXYCiKFJvb2+zhwE0RIwWR99Hv9zsIZyT1E17j3MFEsLGWorQFTVGSZACVC6XtWfPHt16660qlfiIEB5itLXkNQlaTVvkuu+GVH/1QqSFlEQJYWItReiKGqPFOl6WI7Ozs80eArAqYhQhM0mbLqGKHcLHWorQFTFGSZAAAAAAIEOCBAAAAAAZEqQAxXGsgYEBxXHc7KEAdRGjCN1CKj16MNZC2uyRAI2xliJ0RY3R4lxtlSNmpp6enmYPA2iIGEXoXKaJk80eBbA61lKErqgxyhGkAJXLZQ0PD6tcLjd7KEBdxChC1x65dmwrqz3iRkgIF2spQlfUGCVBClTRAhH5Q4widO1s4ZADrKUIXRFjlM0HAAAAAGRIkAAAAAAgY+6teX62mXVJmp6enlZXV1ezh7Mm7q7XXntNl112mcy4zSHCQ4y2lr6PfrnZQ7jgTK6eDmlqrlKwoRVMPHhPs4eAC4y1FKFrpRidmZlRd3e3JHW7+8xqfTmCFKiOjo5mDwFYFTGKkLmkEwuVn0DIWEsRuiLGKGW+A5QkiYaHhzU0NKRSiY8I4SFGEbr2SNqxLdHOfbHmW+ReSKsd6ePoUj6xliJ0RY1RjiABAAAAQIYECQAAAAAyJEgAAAAAkKGKXYDcXUmSKI7j3FcMQWsiRltLK1axk1ztkbLrj1o/RrkGKZ9YSxG6VopRqti1gLm5uWYPAVgVMYqQmaSNbUVIjZB3rKUIXRFjlAQpQEmSaHR0VEmSNHsoQF3EKELXFkn3b03UxlYOAWMtReiKGqNsOgAAAAAgQ4IEAAAAABkSpEAV6WZcyCdiFKFrlRvEorWxliJ0RYxRqtgBQMG1ZhW7YqGKHQCsjip2OefumpqaUqsmr8g/YhShM7n6NrhMxCjCxVqK0BU1RkmQApQkicbGxgpXMQT5QYwidG2RdO8WqtghbKylCF1RY5RNBwAAAABkSJAAAAAAIEOCFKjOzs5mDwFYFTGKkLmkY6e4AgnhYy1F6IoYo1SxA4CCo4pd/lHFDgBWRxW7nEvTVJOTk0pTbuKBMBGjCF1krluuSBVZa34JiNbAWorQFTVGi3fnpxxI01Tj4+O68sorFUXksAgPMZo/RTtKVDLprs2pxqdjzZMjIVCspQhdUWO0ODMFAAAAgDMgQQIAAACADAlSgMxMPT09MrNmDwWoixhF6FzSxEmq2CFsrKUIXVFjdE0Jkpl9zMxGzeyEmR01s8fMrL+mz8Nm5jWP3TV9Osxsp5m9amazZvZFM9tc0+cKM3vEzKazxyNmdvk5zzRH4jjWwMCA4jhu9lCAuohRhG4hNT16MNZCWqyNOvKFtRShK2qMrrVIw1sl/bGk0ey1vytpl5n9qLvPVvV7QtIvVv19vuZ9HpL0s5LeLemYpE9JetzMbnP3JOvz15I2S7o7+/ufS3oke11LS9NUhw4d0hve8IZCXRCH/CBGEbrYXLdf6frWD0yJt36StFoRDkqAh4u1FKEraoyuaabufre7P+zu+9z926okQW+QdFtN1zl3f6XqMbX4hJl1S/plSb/m7k+5+x5J75V0i6SfzvrcrEpi9D+7+4i7j0j6l5L+We0Rq1aUpqkmJiYKV1IR+UGMInSxSXdenSpu/dwIOcZaitAVNUbPt8x3d/Zzqqb9bWZ2VNIPJX1d0m+6+9HsudsktUnatdjZ3Q+b2XOS7pT0pKQ7JE27+zer+uw2s+msz3jtQMysQ1JHVdNGSSqXyyqXy4t9FMexkiRR9Q1yoyhSFEUN2xdfvyiOY5lZ3XZJSpLkrNpLpZLc/bT2bL4r3n9x7GmargjSvMypVCo1HDtzyt+cyuXy0nhbZU7V7a04p9h8RbKQuJS4qS1yVecQZZfSOu0LqeQytUcrr+qptEvtNV+3zaeSSWo7rd1k8hXtrsopcZG5SnZ6e6OxrzanxfG3Rd4yczrXz6lcLvP/KeA5VW/vW2VOZzN25pSPObn7afukeZ1T7fOrOecEySpXa31a0rC7P1f11Fck/SdJ35O0RdLvSPq77PS5OUnXSJp39+M1b3kke07Zz6M63dGqPrU+JunjtY0jIyPq7OyUJPX29qq/v18HDhzQ5OTkUp++vj719fVp3759mppazvX6+/vV29urPXv2aHZ2+QzCgYEB9fT0aPfu3Sv+sQcHB9XR0aHh4eEVYxgaGtLc3JxGR0eX2kqlkoaGhnT8+HGNjY0ttXd2durWW29VuVzW7t3Ll2719PRoYGBAhw4d0sTExFJ7XuY0ODioI0eOaHx8ObdlTvme09zcnCS11Jxa8XNanNPbr3Xd0rO8YXrmSKSRo6Z3Xp+qb8PyBmjXy5H2Hjfdd0OqTZcstz96MNbESekDNycrEoeHn491YkHasW3lRnLnvlgb26T7ty63z6fSzn0lXb9BunfLcvuxU6aH98fadrnrrs3LY5w4WbmO6PYrXXdevdy+dyrSru/bqnPassF11aXSB29O9WSLzOlcP6fh4WH+PwU6p9HRUc3Ozi5t71thTq34ORV5Ttu3b5e7r9gnzeucql9zJladma2Fmf2xpHskDbn7y6v061UlWXq3u/+Nmb1H0ufcvaOm31clveDuv2JmD0h6v7vXFoDYL+mz7v5gnd9T7wjSy8eOHVNXV9din1x8o2Bm2r9/v7Zs2bL02lCy73OdU8jfKDCntc8pSRK9+OKL2rp1qyS1xJyq21vlc6puv+FjjxfqCFLJXG/rdT09aZpLrSXmdK6f03d++27+PwU6p7m5Ob344ot64xvfWDnS2wJzasXPqchzkipfhFbvk+Z1TjMzM9q0aZMkdbv7zGkTrXJOCZKZ7ZT085J+0t0PnkX//ZL+wt1/38x+StLXJPVUH0Uys29LeszdP25mvyTp0+5+ec37/FDSh939c2fxO7skTU9PTy8lSABQVKtdxI/WRpEGAKgkSN3d3dJZJEhrOsUuO61up6R3SXrbWSZHmyRdJ2nx2NmzkhYkvUPSF7I+vZLeJOnXsz4jkrrN7HZ3/1bW5ydUuebpmbWMOY+SJNGBAwd04403Fq6sIvKBGA0TSdCy2Fxvv9b1tcPFqGKHfGItReiKGqNrrdf3x6pUnHuPpBNmdk32uFSSzGyDmX3SzO4wsz4ze5ukL0l6VdJ/liR3n5b0WUmfMrO3m9mtkv5vSXslPZX1+a4qpcI/Y2bbzWy7pM9IetzdTyvQ0GrcXZOTkzqXo3vAxUCMInSxSbf0UMUOYWMtReiKGqNrLdLwwezn0zXtvyjpYUmJKuW6f0HS5aocNfp7Sf/C3U9U9f+wpLIqR5AuVeWUu/t9+R5IknSfpD/ScrW7L0r60BrHCwAAAABnbU0Jkvvq5ym4++uS/ulZvM8pSTuyR6M+U6ocrQIAAACAi6I4t8TNkSiK1NfXV6g7FiNfiFGELvFKieykWGeFIGdYSxG6osbo+d4oFutgMRiBUBGjCF3ippGjXICEsLGWInRFjdFipYM5kSSJxsbG6taiB0JAjCJ0bZHr3i2J2iIOISFcrKUIXVFjlAQpQO6uqampwlUMQX4QowidSerbsPImqkBoWEsRuqLGKAkSAAAAAGRIkAAAAAAgQ4IUoCiK1N/fX7iKIcgPYhShK7u06+VI5WKdFYKcYS1F6Ioao1SxC1AURert7W32MICGiFGELnXT3uNcgYSwsZYidEWNURKkAJXLZe3Zs0e33nqrSiU+IoSHGEXo2iLXfTek+qsXIi2kxU6U+j765YbPTTx4z0UcCWqxliJ0RY3RYh0vy5HZ2dlmDwFYFTGKkJmkTZdQxQ7hYy1F6IoYo8VJBQGgBax2NAAAAJw/jiABAAAAQIYEKUBxHGtgYEBxHDd7KEBdxChCt5BKjx6MtZA2eyRAY6ylCF1RY5RT7AJkZurp6Wn2MICGiFGEzmWaONnsUQCrYy1F6IoaoxxBClC5XNbw8LDK5XKzhwLURYwidO2Ra8e2stojboSEcLGWInRFjVESpEAVLRCRP8QoQtfOFg45wFqK0BUxRtl8AAAAAECGBAkAAAAAMiRIAYrjWIODg4WrGIL8IEYRuoVUevh5qtghbKylCF1RY5QEKVAdHR3NHgKwKmIUIXNJJxYqP4GQsZYidEWMURKkACVJouHhYSVJ0uyhAHURowhdeyTt2JZQqAFBYy1F6Ioao2w6AAAAACBDggQAAAAAGRIkAAAAAMiYe2tewmpmXZKmp6en1dXV1ezhrIm7K0kSxXEsM2v2cIDTEKPN0/fRLzd7CDnhao+k+VSSiNFGJh68p9lDKDTWUoSulWJ0ZmZG3d3dktTt7jOr9eUIUqDm5uaaPQRgVcQoQmaSNraRGiF8rKUIXRFjlAQpQEmSaHR0tHAVQ5AfxChC1xZJ929N1MZWDgFjLUXoihqjbDoAAAAAIFNq9gAAACtxnREAAM3DEaRAlUrkrggbMYrQVQo0AGFjLUXoihijVLEDgMBwBAkXC1XsABQFVexyzt01NTWlVk1ekX/EKEJncvVtcJmIUYSLtRShK2qMFu+YWQ4kSaKxsTENDQ0V8rAmwkeMInRtkXTvlkQ798WcareK1Y5WcnRp/bGWInRFjVGOIAEAAABAhgQJAAAAADIkSIHq7Oxs9hCAVRGjCJlLOnaKK5AQPtZShK6IMUoVOwAIDFXsEAKuQQLQSqhil3NpmmpyclJpypXFCBMxitBF5rrlilSRteaXgGgNrKUIXVFjlAQpQGmaanx8vHDBiPwgRhG6kkl3bU5VsmaPBGiMtRShK2qMkiABAAAAQIYECQAAAAAyJEgBMjP19PTIjHNDECZiFKFzSRMnqWKHsLGWInRFjVGq2AFAYKhihxBQxQ5AK1m3KnZm9jEzGzWzE2Z21MweM7P+mj5mZp8ws8Nm9rqZPW1m22r6dJjZTjN71cxmzeyLZra5ps8VZvaImU1nj0fM7PK1jDev0jTVxMRE4S6IQ34QowhdbK47rkoVU8UOAWMtReiKGqNrPcXurZL+WNJ2Se+QVJK0y8yq7yD165I+IulDkgYlvSLpq2a2sarPQ5LeJendkoYkbZD0uJnFVX3+WtKbJd2dPd4s6ZE1jjeXihqMyA9iFKGLTbrz6lRxsc4KQc6wliJ0RY3R0lo6u/vd1X83s1+UdFTSbZL+i1VOUPxVSb/r7n+T9Xm/pCOS3iPpz8ysW9IvS3qfuz+V9XmvpJck/bSkJ83sZlWSou3u/s2sz7+UNGJm/e4+fo7zBQAAAICGzrdIQ3f2cyr7uUXSNZJ2LXZw9zlJX5d0Z9Z0m6S2mj6HJT1X1ecOSdOLyVHWZ7ek6ao+AAAAAHBBrekIUrXsaNGnJQ27+3NZ8zXZzyM13Y9Iur6qz7y7H6/T55qqPkfr/NqjVX1qx9MhqaOqaaMklctllcvlxT6K41hJkqi6OEUURYqiqGH74usXxXEsM6vbLklJkpxVe6lUkruf1m5muuaaa1a0L449TdMVhznzMqdSqdRw7Mwpf3NKkkRXX321zKxl5lTd3uw5tUeV3zGfmkyutqqvslzSQmqKzFfcBHWxPTZfcVpZ4lLijdvbIlf1WWhll9I67Qup5LKlsa1sl9prvm6bTyWTVoz9Ys4pNtd3jlf6RNYac7rYn9OWjz7ecE7P/87yCSWh/39aFOIasbiWLo6pFebUip9Tkeck6bR90rzOqfb51ZxzgiTpP0oaUOUaolq1V8VanbZatX3q9V/tfT4m6eO1jSMjI+rsrFwi1dvbq/7+fh04cECTk5NLffr6+tTX16d9+/Zpampqqb2/v1+9vb3as2ePZmdnl9oHBgbU09Oj3bt3r/jHHhwcVEdHh4aHh1eMYWhoSHNzcxodHV1qK5VKGhoa0vHjxzU2NrbU3tnZqcHBQXV3d2tkZGSpvaenRwMDAzp06JAmJiaW2vM0pyNHjmh8fPnsSOaU/znFcazx8fGWmlMIn9OObYnmU2nnvpKu3yDdu2V5A3TslOnh/bG2Xe66a/PyhmbipOnRg7Fuv9J159XL7XunIu36vunt17pu6Vluf+ZIpJGjpnden6pvw/KyuuvlSHuPm+67IdWmS5bbHz0Ya+Kk9IGbkxU72Q8/H+vEQmXM1Xbui7WxTbp/63J7M+b0o1d4y81Jav7nVB3Dof9/ksJdI0ZHR1Uul3XkyJGWmVMrfk5Fn9N11123Yp80r3Oqfs2ZnFOZbzPbKennJf2kux+san+jpBck/Zi776lq/1tJP3T395vZT0n6mqSe6qNIZvZtSY+5+8fN7JckfdrdL6/5vT+U9GF3/1ydMdU7gvTysWPHlsp85+UbBTPT/v37tWXLlqXXhpJ9n+ucQv5GgTmtfU5JkujFF1/U1q1bJakl5lTd3uzP6Ud/6wlJrXtk4mLMqWSut/W6np40zaXWEnMK6XPiCNKFmdPc3JxefPFFvfGNb1Qcxy0xp1b8nIo8J0k6cODAin3SvM5pZmZGmzZtks6izPeajiBlp9XtVKUC3duqk6PMQVWq1r1D0p7sNe2qVL/7jazPs5IWsj5fyPr0SnqTKhXwJGlEUreZ3e7u38r6/IQq1zw9U29s2bVOc1VjrUywVFKptHKa1R/w2bTXvv5CtpvZae3lclmvvPKKbrzxxtOeWwyOsx17KHOSGo+dOeVzTkeOHNFNN93U8HfmcU6LLsbntPq9jpZ3eV2m+TrFg1I3zdf5fitxU7KG9oW0fpm3Ru3zDdtPb/OG7es/J4ukH70i1dcOR0rdltrrjz0fc6qnWXNay/+zVlr3Fl2oOcVxXHctzfOcWvFzKvKcVtsnzducGj1f9zVn3bPij1WpRvdzkk6Y2eL1QNPu/rq7u5k9JOkBM9svab+kByS9pkrZbrn7tJl9VtKnzOyYKgUePilpr6Snsj7fNbMnJH3GzD6Q/Y4/l/Q4FewAAAAArJe1JkgfzH4+XdP+i5Iezv78B5IulfQnkq6Q9E1Jd7n7iar+H5ZUVuUI0qWqnHJ3v7tXH6e7T9Ifabna3RdVubcSAAAAAKyLtd4H6Yy33PPKyYKfyB6N+pyStCN7NOozJem9axlfq4iiSH19fXUPQwIhIEYRusQrBQ7qna4GhIK1FKEraoyeTxU7rJPFYARCRYwidImbRo6e8Ts9oKlYSxG6osZosdLBnEiSRGNjY3UriQAhIEYRurbIde+WRG0Rh5AQLtZShK6oMUqCFCB319TU1IrShkBIiFGEziT1bVhZAhsIDWspQlfUGCVBAgAAAIAMCRIAAAAAZEiQAhRFkfr7+wtXMQT5QYwidGWXdr0cqVyss0KQM6ylCF1RY5QqdgGKoki9vb3NHgbQEDGK0KVu2nucK5AQNtZShK6oMVqsdDAnyuWyRkdHVS6Xmz0UoC5iFKFri1z330QVO4SNtRShK2qMkiAFanZ2ttlDAFZFjCJkJmnTJVSxQ/hYSxG6IsYop9gBAIA16fvolxs+N/HgPRdxJABw4XEECQAAAAAyHEEKUBzHGhgYUBzHzR4KUBcxenZW+5Yd62shlR49GGshbfZIgMZYSxG6osYoCVKAzEw9PT3NHgbQEDGK0LlMEyebPQpgdaylCF1RY5RT7AJULpc1PDxcuIohyA9iFKFrj1w7tpXVThU7BIy1FKEraoySIAWqaIGI/CFGEbp2tnDIAdZShK6IMcrmAwAAAAAyJEgAAAAAkCFBClAcxxocHCxcxRDkBzGK0C2k0sPPU8UOYWMtReiKGqMkSIHq6Oho9hCAVRGjCJlLOrFQ+QmEjLUUoStijJIgBShJEg0PDytJkmYPBaiLGEXo2iNpx7aEQg0IGmspQlfUGGXTAQAAAAAZEiQAAAAAyJAgAQAAAEDG3FvzElYz65I0PT09ra6urmYPZ03cXUmSKI5jmVmzhwOchhg9O30f/XKzh1BgrvZImk8liRi9mCYevKfZQ8gN1lKErpVidGZmRt3d3ZLU7e4zq/UtXZwhYa3m5uZ02WWXNXsYQEPEKEJmkja2SVNzVLK72Fb7YoDk6XSspQhdEWOUU+wClCSJRkdHC1cxBPlBjCJ0bZF0/9ZEbWzlEDDWUoSuqDHKpgMAAAAAMiRIAAAAAJDhGqRAlUp8NAgbMVpBIYZwVQo0AGFjLUXoihijVLEDgPNAggScPYo0AGiWtVSx4xS7ALm7pqam1KrJK/KPGEXoTK6+DS6jhh0CxlqK0BU1RkmQApQkicbGxgpXMQT5QYwidG2RdO8WqtghbKylCF1RY5RNBwAAAABkSJAAAAAAIEOCFKjOzs5mDwFYFTGKkLmkY6e4AgnhYy1F6IoYo1SxA4DzQBU74OxRxQ5As1DFLufSNNXk5KTSlJt4IEzEKEIXmeuWK1JF1ppfAqI1sJYidEWNURKkAKVpqvHx8cIFI/KDGEXoSibdtTlVyZo9EqAx1lKErqgxWrxb4wIAgKZY7ZRUTr8DEAqOIAEAAABAhgQpQGamnp4emXFuCMJEjCJ0LmniJFXsEDbWUoSuqDFKFTsAOA9UsQMuDE6xA7CeqGKXc2maamJionAXxCE/iFGELjbXHVeliqlih4CxliJ0RY1REqQAFTUYkR/EKEIXm3Tn1aniYp0VgpxhLUXoihqja06QzOwnzexLZnbYzNzMfr7m+Yez9urH7po+HWa208xeNbNZM/uimW2u6XOFmT1iZtPZ4xEzu/xcJgkAAAAAZ+Ncynx3Svq2pM9JerRBnyck/WLV3+drnn9I0s9KerekY5I+JelxM7vN3ZOsz19L2izp7uzvfy7pkex1AHDRcJ0RAADFseYEyd2/IukrklaraDHn7q/Ue8LMuiX9sqT3uftTWdt7Jb0k6aclPWlmN6uSGG13929mff6lpBEz63f38bWOO0/MTL29vYWrGIL8IEYRusSlvVOREi5BQsBYSxG6osboet0o9m1mdlTSDyV9XdJvuvvR7LnbJLVJ2rXY2d0Pm9lzku6U9KSkOyRNLyZHWZ/dZjad9TktQTKzDkkdVU0bJalcLqtcLi/2URzHSpJE1dX7oihSFEUN2xdfvyiOY5lZ3XZJSpLkrNpLpZLcvW77TTfdpDRNTxt7mqYrzgPN05wajZ055XNON954Y8vNqdHnFJsrcVNb5KreRJRdSuu0L6SSy9Qerdw7r7RL7TUnN8+nkklqO63dZPIV7S5pITVF5irZ6e2x+YrrbhKXEm/c3spzenrSFJvk8paZ06JW+pwWpWma2zXiXNc9d9cNN9wgd1e5XG6JObXi51T0OW3dulVJkqx4TR7nVPv8atYjQfqKpP8k6XuStkj6HUl/l50+NyfpGknz7n685nVHsueU/Tyq0x2t6lPrY5I+Xts4MjKizs5OSVJvb6/6+/t14MABTU5OLvXp6+tTX1+f9u3bp6mpqaX2/v5+9fb2as+ePZqdnV1qHxgYUE9Pj3bv3r3iH3twcFAdHR0aHh5eMYahoSHNzc1pdHR0qa1UKmloaEjHjx/X2NjYUntnZ6d+7Md+THv27NHJkyeX2nt6ejQwMKBDhw5pYmJiqT0vcxocHNSRI0c0Pr6c2zKnfM+pra1N27dvb6k5Nfqcbr/SNXLU9M7rU/VtWF6sd70cae9x0303pNp0yXL7owdjTZyUPnBzsmKH9OHnY51YkHZsW7lB2bkv1sY26f6ty+3zqbRzX0nXb5Du3bLcfuyU6eH9sbZd7rpr8/KGZuKk6dGDsW6/0nXn1cvte6ci7fq+6e3Xum7pWW5/5kjU0nPassG1sU06sSA92SJzasXPqXpOR44cye0aca7r3sjIiF577TV1dHS0zJxa8XMq8pzuuOMOPf/88zp27Fju51T9mjM5r/sgmZlLepe7P7ZKn15VkqV3u/vfmNl7JH3O3Ttq+n1V0gvu/itm9oCk97t7f02f/ZI+6+4P1vk99Y4gvXzs2LGl+yDl5RsFSfrGN76hO+64Q6VSacXYm519n+ucQv5GgTmtfU7lclkjIyN6y1vesvQtaN7nVN1eO/b+f/dEYb7Fb5U5tUeuD96c6k+/G+n1xFpiTq34OVWP/R/+95/J7RpxruveqVOnNDIysrS9b4U5teLnVOQ5ubuGh4dX7JPmdU4zMzPatGmTdBb3QVqvU+yWuPukmX1P0k1Z0yuS2s3sipqjSFdJeqaqz9V13u5KVY401fs9c5LmFv++eK5kqVRa8YFKy/9gtRq1177+Qrab2Wnt5XJ5qb32ucXgONuxhzInqfHYmVM+57T4f6yV5rSoduyJV+a6kNY/B7tR+3zD9tPbvGG71W1P3TRf5/utxK3udTeN2lt1TqblHff0DJ9fXuZUTyvN6Y0PfKXumKXKTWRDXiPO1L7aGOtt7/M+p/NtZ07hzGm1fdK8zanR8/Ws+32QzGyTpOskLR47e1bSgqR3VPXplfQmLSdII5K6zez2qj4/Iam7qg8AAAAAXFBrPoJkZhsk3VjVtMXM3ixpKnt8QpXy35OS+iT9nqRXJf1nSXL3aTP7rKRPmdmx7DWflLRX0lNZn++a2ROSPmNmH8h+z59LerzVK9hJlQy7r6+vbpYNhIAYRegSr1zrQhU7hIy1FKEraoyeyyl2Py7p76v+/uns519K+qCkWyT9gqTLVUmS/l7Sv3D3E1Wv+bCksqQvSLpU0tck3V91DyRJuk/SH2m52t0XJX3oHMabO4vBCISKGEXoEjeNHC1WWVrkD2spQlfUGF1zOujuT7u71Xnc7+6vu/s/dfer3L3d3a/P2l+qeY9T7r7D3Te5+2Xu/rN1+ky5+3vdvSt7vNfdf3ie882FJEk0NjZWt3gDEAJiFKFri1z3bknUFnEICeFiLUXoihqjxTpelhPurqmpqRWVO4CQEKMInUnq27CyShoQGtZShK6oMUqCBAAAAAAZEiQAAAAAyJAgBSiKIvX39xeuYgjygxhF6Mou7Xo5UrlYZ4UgZ1hLEbqixui63ygWaxdFkXp7e5s9DKAhYhShS9209zhXICFsrKUIXVFjtFjpYE6Uy2WNjo6qXC43eyhAXcQoQtcWue6/iSp2CBtrKUJX1BglQQrU7Oxss4cArIoYRchM0qZLqGKH8LGWInRFjFESJAAAAADIkCABAAAAQIYEKUBxHGtgYEBxHDd7KEBdxChCt5BKjx6MtZA2eyRAY6ylCF1RY5QqdgEyM/X09DR7GEBDxChC5zJNnGz2KIDVsZYidEWNUY4gBahcLmt4eLhwFUOQH8QoQtceuXZsK6udKnYIGGspQlfUGCVBClTRAhH5Q4widO1s4ZADrKUIXRFjlM0HAAAAAGRIkAAAAAAgY+6teX62mXVJmp6enlZXV1ezh7Mm7q7XXntNl112mcy4zSHC04ox2vfRLzd7CLiATK6eDmlqrlKwAfk28eA9zR7CumjFtRStpZVidGZmRt3d3ZLU7e4zq/XlCFKgOjo6mj0EYFXEKELmkk4sVH4CIWMtReiKGKOU+Q5QkiQaHh7W0NCQSiU+IoSHGEXo2iNpx7ZEO/fFmudeSLm32hHePB9dYi1F6IoaoxxBAgAAAIAMCRIAAAAAZEiQAAAAACBDFbsAubuSJFEcx7mvGILW1IoxShW7VuNqj5Rdf9QaMYr68nwNUiuupWgtrRSjVLFrAXNzc80eArAqYhQhM0kb20iNED7WUoSuiDFKghSgJEk0OjqqJEmaPRSgLmIUoWuLpPu3JmpjK4eAsZYidEWN0eLU6wNQeJxGBwAAzoTv1gAAAAAgQ4IUqCLdjAv5RIwidNwgFnnAWorQFTFGqWIHoDA4xQ5oPXmuYgfg4qGKXc65u6amptSqySvyjxhF6Eyuvg0uEzGKcLGWInRFjVESpAAlSaKxsbHCVQxBfhCjCF1bJN27hSp2CBtrKUJX1Bhl0wEAAAAAGRIkAAAAAMiQIAWqs7Oz2UMAVkWMImQu6dgprkBC+FhLEboixihV7AAUBlXsgNZDFTsAZ4MqdjmXpqkmJyeVptzEA2EiRhG6yFy3XJEqstb8EhCtgbUUoStqjBbvzk85kKapxsfHdeWVVyqKyGERHmIUoSuZdNfmVOPTsebJkVramY4Mh3yEibUUoStqjBZnpgAAAABwBiRIAAAAAJAhQQqQmamnp0dm1uyhAHURowidS5o4SRU7hI21FKEraoxSxQ5AYVDFDiiekK9BAnDxUMUu59I01cTEROEqhiA/iFGELjbXHVeliqlih4CxliJ0RY1REqQAFTUYkR/EKEIXm3Tn1aniYp0VgpxhLUXoihqjJEgAAAAAkFlzgmRmP2lmXzKzw2bmZvbzNc+bmX0ie/51M3vazLbV9Okws51m9qqZzZrZF81sc02fK8zsETObzh6PmNnl5zJJAAAAADgb53IEqVPStyV9qMHzvy7pI9nzg5JekfRVM9tY1echSe+S9G5JQ5I2SHrczOKqPn8t6c2S7s4eb5b0yDmMN3fMTL29vYWrGIL8IEYRusSlvVOREi5BQsBYSxG6osboeVWxMzOX9C53fyz7u0k6LOkhd//9rK1D0hFJv+Huf2Zm3ZJ+IOl97v75rM+1kl6S9DPu/qSZ3SzpO5K2u/s3sz7bJY1I+sfuPn4WY6OKHYAVqGIHFA9V7ABIa6tiV7rAv3uLpGsk7VpscPc5M/u6pDsl/Zmk2yS11fQ5bGbPZX2elHSHpOnF5Cjrs9vMprM+pyVIWSLWUdW0UZLK5bLK5fJiH8VxrCRJVJ0YRlGkKIoati++flEcxzKzuu2SlCTJWbWXSiW5+2ntZqb9+/dry5YtS69dHHuapisulMvLnEqlUsOxM6f8zSlJEr344ovaunWrJOVmTu1RZTwuaSE1xeYrLuJPXEq8cXtb5Kr+Dq3sUlqnfSGVXLb0+1a2S+01x+7nU8kktZ3WbjL5ivbFsUfmKtnp7cypMvaSud7W63p60jSXWkvMqRU/p4sxp8W1JcS1fG5uTi+++KLe+MY3Ko5jtk/MKbg5SdKBAwdW7JPmdU61z6/mQidI12Q/j9S0H5F0fVWfeXc/XqfPNVV9jtZ5/6NVfWp9TNLHaxtHRkbU2dkpSert7VV/f78OHDigycnJpT59fX3q6+vTvn37NDU1tdTe39+v3t5e7dmzR7Ozs0vtAwMD6unp0e7du1f8Yw8ODqqjo0PDw8MrxjA0NKS5uTmNjo4utZVKJQ0NDen48eMaGxtbau/s7NStt96ql156Sa+88spSe09PjwYGBnTo0CFNTEwstedlToODgzpy5IjGx5dzW+aU7zmdOnVKN910k1544YWg5vRXX/nGUvuxU6aH98e65YpUd21OtSO7GnLipOnRg7Fuv9J159XLi/XeqUi7vm96+7WuW3qW2585EmnkqOmd16fq27C8WO96OdLe46b7bki16ZLl9kcPxpo4KX3g5mTFztvDz8c6sSDt2LZyg7JzX6yNbdL9W5fb51Np576Srt8g3btluX1xTtsud921eXmMzGnlnLZscF11qbTtCteTLTKnVvycLsachoeHg13Lv/Wtb2l6elpHjlR2m9g+MafQ5rR9+3YdPnx4xT5pXudU/ZozudCn2N0p6b9KutbdJ6v6fUbSde5+t5m9R9Ln3L2j5r2+KukFd/8VM3tA0vvdvb+mz35Jn3X3B+uMpd4RpJePHTu2dIpdXr5RkKRvfOMbuuOOO1QqlVaMvdnZ97nOKeRvFJjT2udULpc1MjKit7zlLTKzoObU/5vLp9Hl9Rvv5fbW+Rb/Ys+pPXJ98OZUf/rdSK8nHEEq8py+89t3SwpzLT916pRGRkaWtvdsn5hTaHNydw0PD6/YJ83rnGZmZrRp0yapCafYLaaX10iarGq/SstHlV6R1G5mV9QcRbpK0jNVfa6u8/5X6vSjU5Iqp/JJmlv8++LFZKVSacUHKi3/g9Vq1F77+gvZbmantZfL5aX22ucWg+Nsxx7KnKTGY2dO+ZzT4v+x0OY0n55+IWnqpvk63wUlbnUv4m/UvlDnvVdrrzeWSvvpbd6w3eq2M6fV52Ra3nFP3Zba6489H3OqhzmdeU7Va0WIa3m97T3bJ+YUypxW2yfN25waPV/Phb4P0kFVkpt3LDaYWbukt2o5+XlW0kJNn15Jb6rqMyKp28xur+rzE5K6q/q0rCiK1NfXVzeIgBAQowhd4pVTuahih5CxliJ0RY3RNR9BMrMNkm6satpiZm+WNOXuh8zsIUkPZKfD7Zf0gKTXVCnbLXefNrPPSvqUmR2TNCXpk5L2Snoq6/NdM3tC0mfM7APZ7/lzSY+fTQW7vFsMRiBUxChCl7hp5GixytIif1hLEbqixui5pIM/LmlP9pCkT2d//u3s73+gyn2O/kTSf5P0I5LucvcTVe/xYUmPSfqCKtcsvSbpZ929+kTG+1RJmnZljzFJ7zuH8eZOkiQaGxure20SEAJiFKFri1z3bknUFnEICeFiLUXoihqjaz6C5O5PS2r4tZxXrqb6RPZo1OeUpB3Zo1GfKUnvXev4WoG7a2pqasWFaUBIiFGEziT1bfDGGysgAKylCF1RY/RCF2kAAAAIxmo3iOYmsgDqKdYVVwAAAACwChKkAEVRpP7+/sJVDEF+EKMIXdkrNx4tF+usEOQMaylCV9QY5RS7AEVRpN7e3mYPA2iIGEXoUjftPc4VSAgbaylCV9QYJUEKULlc1p49e3Trrbeu6aZWwMXS7Bhd7ZoCQKpUsbvvhlR/9ULU8MajQLM1ey0FzqSoMVqs42U5Mjs72+whAKsiRhEyk7TpEqrYIXyspQhdEWOUBAkAAAAAMiRIAAAAAJAhQQpQHMcaGBhQHMfNHgpQFzGK0C2k0qMHYy2kzR4J0BhrKUJX1BgtztVWOWJm6unpafYwgIaIUYTOZZo42exRAKtjLUXoihqjHEEKULlc1vDwsMrlcrOHAtRFjCJ07ZFrx7ay2iNuhIRwsZYidEWNURKkQBUtEJE/xChC184WDjnAWorQFTFG2XwAAAAAQIZrkAAEiZvBAgCAZjD31jw/28y6JE1PT0+rq6ur2cNZE3fXa6+9pssuu0xm3OYQ4bkYMUqChPNhcvV0SFNzlYINwFpNPHjPuv8OtvcIXSvF6MzMjLq7uyWp291nVuvLKXaB6ujoaPYQgFURowiZSzqxUPkJhIy1FKErYoySIAUoSRINDw8rSZJmDwWoixhF6Nojace2hEINCBprKUJX1Bhl0wEAAAAAGRIkAAAAAMiQIAEAAABAhip2AXJ3JUmiOI5zXzEErelixChV7HB+XO2RNJ9KooodzsHFqmLH9h4ha6UYpYpdC5ibm2v2EIBVEaMImUna2EZqhPCxliJ0RYxRbhQboCRJNDo6qqGhIZVKfEQIDzGK0LVF0v1bE+3cF2dHkYC1We0o9oU6usRaitAVNUY5ggQAAAAAGRIkAAAAAMgU51hZzhTpMCby6ULEKIUYsJ44tQ55wPYeoStijFLFDkDTkCAByKOLUeEOwIVFFbucc3dNTU2pVZNX5B8xitCZXH0bXCZiFOFiLUXoihqjJEgBSpJEY2NjSpKk2UMB6iJGEbq2SLp3S6I2tnIIGGspQlfUGGXTAQAAAAAZEiQAAAAAyJAgBaqzs7PZQwBWRYwiZC7p2CmuQEL4WEsRuiLGKFXsADQNVewA5BFV7ID8oYpdzqVpqsnJSaUpN/FAmIhRhC4y1y1XpIqsNb8ERGtgLUXoihqjxbvzUw6kaarx8XFdeeWViiJyWISHGEXoSibdtTnV+HSseXIkXGCrHf1ey9El1lKErqgxSoIEYF1xGh0AAMiT4qSCAAAAAHAGJEgBMjP19PTIzJo9FKAuYhShc0kTJ6lih7CxliJ0RY1RqtgBWFecYgegSKhwB4RpLVXsuAYpQGma6tChQ3rDG95QqAvikB/EKEIXm+v2K13f+oEp8WJ984nmWksBB9ZShK6oMVqcmeZImqaamJgoXElF5AcxitDFJt15daqY3AgBYy1F6IoaoyRIAAAAAJAhQQIAAACADNcgBcjM1NvbW7iKIciP2hilEANCk7i0dypS0pp1iNAi2N4jdEWN0Qt+BMnMPmFmXvN4pep5y/ocNrPXzexpM9tW8x4dZrbTzF41s1kz+6KZbb7QYw1VHMfq7+9XHMfNHgpQFzGK0CVu2vX9iAINCBprKUJX1Bhdr1Ps9knqrXrcUvXcr0v6iKQPSRqU9Iqkr5rZxqo+D0l6l6R3SxqStEHS42ZWiE8nSRKNj48rSZJmDwWoixhF6GJz3fUjqWLjEBLCxVqK0BU1RtcrQSq7+ytVjx9IlaNHkn5V0u+6+9+4+3OS3i/pMknvyfp0S/plSb/m7k+5+x5J71UlyfrpdRpvUNxdk5OTatV7VCH/iFGELjbplh6q2CFsrKUIXVFjdL2uQbrJzA5LmpP0TUkPuPuLkrZIukbSrsWO7j5nZl+XdKekP5N0m6S2mj6Hzey5rM+T9X6hmXVI6qhq2ihJ5XJZ5XJ5sY/iOFaSJCs+6CiKFEVRw/bF1y+K41hmVrdd0mlZdqP2Uqkkd6+blbv7ivdfHHuapitKLeZlTqVSqeHYmVP+5lQul5fGmySJ2qPlsSdeOb2pLXJV75uWXUrrtC+kkstWvMdyu9Re8zXOfCqZpLbT2k0mX9HukhZSU2Sukp3eHpuv2IFeHHujduaUnzktjr8t8paZUyt+TkWb0+LaXb2WV2/v2T4xp9Dm5O6n7ZPmdU61z69mPRKkb0r6BUnPS7pa0v8q6ZnsOqNrsj5Hal5zRNL12Z+vkTTv7sfr9LlGjX1M0sdrG0dGRtTZ2SlJ6u3tVX9/vw4cOKDJycmlPn19ferr69O+ffs0NTW11N7f36/e3l7t2bNHs7OzS+0DAwPq6enR7t27V/xjDw4OqqOjQ8PDwyvGMDQ0pLm5OY2Oji61lUolDQ0N6fjx4xobG1tq7+zs1K233qpyuazdu3cvtff09GhgYECHDh3SxMTEUnte5jQ4OKgjR45ofHycObXInObm5iRJBw4c0I5tywvkM0cijRw1vfP6VH0blhe2XS9H2nvcdN8NqTZdstz+6MFYEyelD9ycrNjRefj5WCcWtOK9JWnnvlgb26T7ty63z6fSzn0lXb9BunfLcvuxU6aH98fadrnrrs3Li/LESdOjB2PdfqXrzquX2/dORdr1fdPbr3Xd0rPczpzyN6ctG1xXXSp98OZUT7bInFrxcyranBbX6MW1fHR0VLOzs0vbe7ZPzCm0OW3fvl3uvmKfNK9zqn7Nmdh6HzIzs05JL0j6A0m7Jf1XSde6+2RVn89Ius7d7zaz90j6nLt31LzPVyW94O6/0uD31DuC9PKxY8fU1dW12CcX3yhEUaTvfe97+pEf+ZGluxaHkn2f65xC/kaBOa19Tmma6uWXX1ZfX5/cXTf/u68s9S/yt8PMKZw5lcx12z9yPfuqaS61lphTK35ORZvTd377bknLa/n8/LxeeuklXXfddYqiiO0TcwpuTmamQ4cOrdgnzeucZmZmtGnTJknqdvcZrWLdEyRpKbk5IOkPVUmWfiy7tmjx+b+V9EN3f7+Z/ZSkr0nqqT6KZGbflvSYu592lKjB7+ySND09Pb2UIAFYH5T5BoDzM/HgPc0eAtDSZmZm1N3dLZ1FgrTuN4rNjuzcLGlS0kFVqta9o+r5dklvlfRM1vSspIWaPr2S3lTVp6UlSaKxsbHCVQxBfhCjCF1b5Lp3S6K2aP2/BATOFXGK0BV1e3/Br0Eys09K+pKkQ5KuUuUapC5Jf+nubmYPSXrAzPZL2i/pAUmvSfprSXL3aTP7rKRPmdkxSVOSPilpr6SnLvR4Q+TumpqaKlzFEOQHMYrQmaS+DStPdwJCQ5widEXd3q9HkYbNkv4fSf9I0g9Uue5ou7t/L3v+DyRdKulPJF2hSlGHu9z9RNV7fFhSWdIXsr5fk3S/uxcrfQUAAABwUV3wBMnd332G513SJ7JHoz6nJO3IHgACUH2dUXvk2rEt0b/6rSc0n/LdJwAAaB3rfg0S1i6KIvX396+oFgKEpOyV8rXlYh1xR44Qo8gD4hShK+o+6XrdKBbnIYoi9fb2NnsYQEOpm/Ye58gRwkWMIg+IU4SuqPukxUoHc6JcLmt0dHRNd/wFLqa2yHX/TVReQriIUeQBcYrQFXWflAQpUGu52y9wsZmkTZdQeQnhIkaRB8Qp8qCI+6QkSAAAAACQIUECAAAAgAxFGgIUx7EGBgYUx3GzhwLUtZBKjx6MtZA2eyRAfcQo8qA6TqtvpVBr4sF7LuKogGVF3SclQQqQmamnp6fZwwAacpkmTjZ7FEBjxCjygDhF6Iq6T8opdgEql8saHh4uXMUQ5EflRrFltVN5CYEiRpEHxClCV9R9Uo4gBapogYgwrHaKR612vl5B4IhR5AFxitAVcZ+U/5YAAAAAkOEIEgAAQMAo4ABcXBxBClAcxxocHCxcxRDkx0IqPfw8FcIQLmIUeUCcInRF3SflCFKgOjo6mj0EtKC1XGO0Gpd0YqHyEwgRMYo8IE6RB0XcJ+UIUoCSJNHw8LCSJGn2UIC62iNpx7aEi4sRLGIUeUCcInRF3SflvyQAAAAAZEiQAAAAACDDNUgAAAA5RYU74MIz99a8NNDMuiRNT09Pq6urq9nDWRN3V5IkiuNYZtbs4aCFXKgiDZKrPZLmU0kiRhEiYhR5sL5xSoKE89VK+6QzMzPq7u6WpG53n1mtL6fYBWpubq7ZQwAaMkkb29jtRLiIUeQBcYo8KOI+KQlSgJIk0ejoaOEqhiA/2iLp/q2J2lhBEChiFHlAnCJ0Rd0n5RokoMVcuNPoAAAAiofvLAAAAAAgwxGkQJVKfDQIW+WiYiBcxCjyYD3jlAp3uBCKuE9KFTsghziNDgBwPkiQUDRUscs5d9fU1JRaNXlF/plcfRtcJmIUYSJGkQfEKUJX1H1SEqQAJUmisbGxwlUMQX60RdK9W6i8hHARo8gD4hShK+o+afFOKgRygtPoAADrheuTgMb4zgIAAAAAMiRIgers7Gz2EICGXNKxU5w1j3ARo8gD4hR5UMR9UqrYAYHiFDsAQDNwih1aEVXsci5NU01OTipNuYkHwhSZ65YrUkXWml+wIP+IUeQBcYrQFXWflCINAUrTVOPj47ryyisVReSwCE/JpLs2pxqfjjXPdh0BIkaRB6HGKQUcsKio+6QkSEATcRodAABAWEiQgHVGEgQAaBUcXUIRFOdYWY6YmXp6emRmzR4KUJdLmjhJ5SWEixhFHhCnCF1R90k5ghSgOI41MDDQ7GEADS2kpkcPxs0eBtAQMYo8IE4RuqLuk5IgBShNUx06dEhveMMbCnVBHPIjNtftV7q+9QNT4sX6Vgn5QIwiD1otTjn9rvUUdZ+UBClAaZpqYmJCmzdvLlQw5lnRrjOKTbrz6lTPvhor4dwQBIgYRR4QpwhdUfdJizNTAAAAADgDjiABZ6loR4kAALhQznUbyql5aAYSpACZmXp7ewtXMSQEJEFnJ3Fp71TEKSEIFjGKPCBOEbqi7pOae2v+rzSzLknT09PT6urqavZwkBMkSAAA5B9HnlBrZmZG3d3dktTt7jOr9Q3+CJKZ/WtJ/1ZSr6R9kn7V3b/R3FGtryRJdODAAd14442KY8p/ngsSnfUVm+vt17q+drg1Ki+h9RCjyAPiFKEr6j5p0AmSmf0LSQ9J+teS/qukD0j6ipn9qLsfaubY1pO7a3JyUjfccEOzhxI0kqDmiU26pSfV05NUXkKYiFHkAXG6fig5fmEUdZ806ARJ0kckfdbd/yL7+6+a2T+V9EFJH2vesLBW57pQkQQBAIALiYIROJNgEyQza5d0m6QHa57aJenOOv07JHVUNW2UpKmpKZXL5cU+iuNYSZKo+tqrKIoURVHD9sXXL4rjWGZWt12qHI48m/ZSqSR3P61dkk6ePKmpqSmVSqUVY0/TVGmaVs/7os5p8HefkiQtpJJJKtUUil9ITSY/rT1NTZG5Yju9/5aPfEFRVXvqUuKmuKb/YntbtPJrtsSltE57OZVcjdqlttPGvrY5Lawyp9i84ZzqtedtTlHkev21VMlcLHO1xJyqx94qn1OR5xRFrlOvpYoWIimxlphTtVb5nIo+p6iULsVpnFpLzKkVP6fF9ht+7QsXfU6jv/nTkpq3D+vup+2TSo33YUulUsN91Wbvw87MrHrZ0QrBFmkws2slfV/SP3H3Z6raH5D0fnfvr+n/CUkfv6iDBAAAAJAnm939+6t1CPYIUpXaDM7qtEnSv5f06Zq2HklT6zGodbZR0suSNks60eSxAPUQowgdMYo8IE4RulaL0Y2SDp+pU8gJ0quSEknX1LRfJelIbWd3n5M0V9N89sfSAlJVa/7EmcoQAs1AjCJ0xCjygDhF6FowRs9qDtGZuzSHu89LelbSO2qeeoekZ05/BQAAAACcn5CPIEmVU+YeMbP/JmlE0r+S9AZJ/2dTRwUAAACgJQWdILn7581sk6TfUuVGsc9J+hl3/15zR7bu5iT9bzr9lEEgFMQoQkeMIg+IU4SukDEabBU7AAAAALjYgr0GCQAAAAAuNhIkAAAAAMiQIAEAAABAhgQJAAAAADIkSBeJmf2kmX3JzA6bmZvZz9c8/3DWXv3YXdOnw8x2mtmrZjZrZl80s80XdSJoaWeK06zPzVnsTZvZCTPbbWZvqHqeOMW6OYu1tHYdXXz826o+xCjWzVnE6AYz+49m9rKZvW5m3zWzD9b0IUaxbs4iRq/O9ksPm9lrZvaEmd1U06elY5QE6eLplPRtSR9apc8TqpQzX3z8TM3zD0l6l6R3SxqStEHS42YWX+jBorBWjVMzu0HSsKR/kPQ2Sf+DpN+RdKqq20MiTrF+zrSW9tY8fkmSS3q0qs9DIkaxfs4Uo/9B0t2S3ivp5uzvO83s56r6PCRiFOunYYyamUl6TNIbJf2cpFslfU/SU2bWWdX1IbVwjFLmuwnMzCW9y90fq2p7WNLl7v7zDV7TLekHkt7n7p/P2q6V9JIq94Z6cp2HjYJpEKf/r6QFd39fg9cQp7ho6sVonT6PSdro7m/P/k6M4qJpsI4+J+nz7v47VW3PSvr/3P3fEaO4mGpj1My2ShqX9CZ335e1xZKOSvoNd/+LIsQoR5DC8jYzO2pmz5vZZ8zsqqrnbpPUJmnXYoO7H1bl5rl3XuRxooDMLJJ0j6TnzezJLFa/WXNonjhFMMzsalVi9rNVzcQomm1Y0jvN7Ees4n+UtFXS4k4lMYpm6sh+Lp0Z4u6JpHlVjhRJBYhREqRwfEXSfZJ+StKvSRqU9Hdmthio10iad/fjNa87kj0HrLerVDmE/lFVTge9S9J/lvQ3ZvbWrA9xipC8X9IJSX9T1UaMotn+jaTvSHpZlZ3OJyT9a3cfzp4nRtFM/6DKKXX/3syuMLN2M/uoKrHXm/Vp+RgtNXsAqFg8RJl5zsz+myoBeo9WbtxrmSrn1wPrbfELlb919/+Q/fm/m9mdkn5F0tdXeS1ximb4JUl/5e6nztiTGMXF828kbZf0TlW28z8p6U/MbNLdn1rldcQo1p27L5jZvaoceZ+SlEh6SpUv8s+kZWKUI0iBcvdJVRbOxaohr0hqN7MrarpepUrGDqy3VyWVVfnms9p3JS1WsSNOEQQze4ukfkl/UfMUMYqmMbNLJf2epI+4+5fcfczd/6Okz0v6X7JuxCiayt2fdfc3S7pcUq+73y1pk6SDWZeWj1ESpECZ2SZJ10mazJqelbQg6R1VfXolvUnSMxd9gCgcd5+XNKrKTme1raok8xJxinD8sqRn3f3bNe3EKJqpLXukNe2JlvfJiFEEwd2n3f0HWYnvH5f0t9lTLR+jnGJ3kZjZBkk3VjVtMbM3q3L4ckrSJ1QpQzspqU+Vb5heVeUaD7n7tJl9VtKnzOxY9ppPStqryqFP4LytFqfufkjSH0r6vJn9F0l/r0qp2p9VpeQ3cYp1dxYxKjPrkvTPVbmecwViFOvtTDFqZl+X9Idm9roqXy69VdIvSPqIRIxi/Z1FjP5zVarUHZJ0i6T/Q9Jj7r5LKkiMujuPi/BQZQfS6zwelnSpKtVrjqpyweb3svbrat7jEkk7JR2T9JqkL9X24cHjfB6rxWlVn1+StF/S65L+u6Sfq3kP4pTHuj3OMkb/VRZ73Q3egxjlsW6PM8WoKhexf07S97N19B9USY6s6j2IUR7r9jiLGP03qpTsXtwn/R1J7TXv0dIxyn2QAAAAACDDNUgAAAAAkCFBAgAAAIAMCRIAAAAAZEiQAAAAACBDggQAAAAAGRIkAAAAAMiQIAEAAABAhgQJAAAAADIkSAAAAACQIUECAAAAgAwJEgAAAABkSJAAAAAAIPP/Ax3/EvbGGgvqAAAAAElFTkSuQmCC

)

从图中我们可以看出,大多人身高都集中在170左右。讲到这里,不知道你有没有回想起高中数学讲过的原则:

P(μ-σ < X ≤ μ+σ) = 68.3%

P(μ-2σ < X ≤μ+2σ) = 95.4%

P(μ-3σ < X ≤μ+3σ) = 99.7%

即:

  • 数值分布在(μ-σ, μ+σ)中的概率为68.3%
  • 数值分布在(μ-2σ, μ+2σ)中的概率为95.4%
  • 数值分布在(μ-3σ, μ+3σ)中的概率为99.7%

可以认为,取值几乎全部集中在(μ-3σ, μ+3σ)区间,超出这个范围的可能性仅到0.3%

其实,生活、生产与科学实验中很多随机变量的概率分布都可以近似地用正态分布来描述。

数组的索引与切片

数组的索引与切片类似Python中的list。下面演示一下即可。

In [50]:

score

Out[50]:

array([[100, 99, 91, 85, 90],
[ 95, 85, 88, 81, 88],
[ 85, 81, 80, 78, 86]])

In [51]:

score[0]

Out[51]:

array([100, 99, 91, 85, 90])

In [52]:

score[0, 1]

Out[52]:

99

In [53]:

score[0, 2:4]

Out[53]:

array([91, 85])

In [54]:

score[0, :-2]

Out[54]:

array([100, 99, 91])

In [55]:

score[:-1, :-3]

Out[55]:

array([[100, 99],
[ 95, 85]])

In [56]:

score[:-1, :-3] = 100

In [57]:

score[:-1, :-3]

Out[57]:

array([[100, 100],
[100, 100]])

操作数据非常方便。

修改数组形状

还记得数组的形状是什么吗?

In [58]:

score.shape

Out[58]:

(3, 5)

(3, 5)表示这是3行5列的二维数组。

如果现在想得到一个5行3列的二维数组呢?

In [59]:

# Returns an array containing the same data with a new shape
score.reshape([5, 3])

Out[59]:

array([[100, 100, 91],
[ 85, 90, 100],
[100, 88, 81],
[ 88, 85, 81],
[ 80, 78, 86]])

score本身的形状有变化吗,看看此时的score啥样?

In [60]:

score

Out[60]:

array([[100, 100, 91, 85, 90],
[100, 100, 88, 81, 88],
[ 85, 81, 80, 78, 86]])

如果想就地修改score的形状,应该使用resize()

In [61]:

# Change shape and size of array in-place
score.resize([5, 3])

score

Out[61]:

array([[100, 100, 91],
[ 85, 90, 100],
[100, 88, 81],
[ 88, 85, 81],
[ 80, 78, 86]])

如果想转置数组呢(即数组的行、列进行互换)?

In [62]:

score.T

Out[62]:

array([[100, 85, 100, 88, 80],
[100, 90, 88, 85, 78],
[ 91, 100, 81, 81, 86]])

主意:调用数组的转置后,score本身并没有改变,如下:

In [63]:

score

Out[63]:

array([[100, 100, 91],
[ 85, 90, 100],
[100, 88, 81],
[ 88, 85, 81],
[ 80, 78, 86]])

数组去重

In [64]:

# Find the unique elements of an array

Returns the sorted unique elements of an array

np.unique(score)

Out[64]:

array([ 78, 80, 81, 85, 86, 88, 90, 91, 100])

修改数组元素类型

In [65]:

score.dtype

Out[65]:

dtype('int64')

In [66]:

# Copy of the array, cast to a specified type.
score.astype(np.float64)

Out[66]:

array([[100., 100., 91.],
[ 85., 90., 100.],
[100., 88., 81.],
[ 88., 85., 81.],
[ 80., 78., 86.]])

逻辑运算

如果想操作符合某些条件的数据,应该怎么做?

In [67]:

# 成绩是否及格(60分及以上为及格)
score >= 60

Out[67]:

array([[ True, True, True],
[ True, True, True],
[ True, True, True],
[ True, True, True],
[ True, True, True]])

In [68]:

# 成绩是否优秀(90分及以上为优秀)
score >= 90

Out[68]:

array([[ True, True, True],
[False, True, True],
[ True, False, False],
[False, False, False],
[False, False, False]])

给满足条件的数据赋值。

In [69]:

# 给及格的同学都加上5分
score[score >= 60] += 5

score

Out[69]:

array([[105, 105, 96],
[ 90, 95, 105],
[105, 93, 86],
[ 93, 90, 86],
[ 85, 83, 91]])

In [70]:

# 分数不允许超过满分(即100)
score[score > 100] = 100

score

Out[70]:

array([[100, 100, 96],
[ 90, 95, 100],
[100, 93, 86],
[ 93, 90, 86],
[ 85, 83, 91]])

In [71]:

# 前面2个同学是否都满分
np.all(score[:2] >= 100)

Out[71]:

False

In [72]:

# 前面2个同学是否有满分的
np.any(score[:2] >= 100)

Out[72]:

True

In [73]:

# 分数大于90且小于95的置为1,否则为0
np.where(np.logical_and(score > 90, score < 95), 1, 0)

Out[73]:

array([[0, 0, 0],
[0, 0, 0],
[0, 1, 0],
[1, 0, 0],
[0, 0, 1]])

In [74]:

# 分数为100或者小于90置为1,否则为0
np.where(np.logical_or(score == 100, score < 90), 1, 0)

Out[74]:

array([[1, 1, 0],
[0, 0, 1],
[1, 0, 1],
[0, 0, 1],
[1, 1, 0]])

统计运算

如果想统计分数的最大值、最小值、平均值、方差,该怎么做?

上面演示过程中,把成绩都弄乱了。这里先恢复一下最开始的数据。

In [75]:

score = np.array(
[[92, 99, 91, 85, 90],
[95, 85, 88, 81, 88],
[85, 81, 80, 78, 86]])

score

Out[75]:

array([[92, 99, 91, 85, 90],
[95, 85, 88, 81, 88],
[85, 81, 80, 78, 86]])

In [76]:

# 每门课的最高分(axis=0表示按照列的维度去统计)
np.max(score, axis=0)

Out[76]:

array([95, 99, 91, 85, 90])

In [77]:

# 每个学生的最高分(axis=1表示按照行的维度去统计)
np.max(score, axis=1)

Out[77]:

array([99, 95, 86])

如果想知道每门课最高分对应的是哪个同学,怎么办?

In [78]:

# 每门课的最高分对应的学生(即下标)
np.argmax(score, axis=0)

Out[78]:

array([1, 0, 0, 0, 0])

其他统计函数也都类似。

In [79]:

# 每门课的最低分
np.min(score, axis=0)

Out[79]:

array([85, 81, 80, 78, 86])

In [80]:

# 每门课的平均分
np.mean(score, axis=0)

Out[80]:

array([90.66666667, 88.33333333, 86.33333333, 81.33333333, 88. ])

In [81]:

# 每门课的中位数
np.median(score, axis=0)

Out[81]:

array([92., 85., 88., 81., 88.])

In [82]:

# 每门课的方差
np.var(score, axis=0)

Out[82]:

array([17.55555556, 59.55555556, 21.55555556, 8.22222222, 2.66666667])

In [83]:

# 每门课的标准差
np.std(score, axis=0)

Out[83]:

array([4.18993503, 7.7172246 , 4.64279609, 2.86744176, 1.63299316])

数组与数的运算

In [84]:

arr = np.array([[1, 2, 3], [11, 22, 33]])
arr

Out[84]:

array([[ 1, 2, 3],
[11, 22, 33]])

In [85]:

arr * 10 + 1

Out[85]:

array([[ 11, 21, 31],
[111, 221, 331]])

数组与数组的运算

通常对于两个numpy数组的相加、相减以及相乘都是对应元素之间的操作。

In [86]:

arr + arr

Out[86]:

array([[ 2, 4, 6],
[22, 44, 66]])

In [87]:

arr - arr

Out[87]:

array([[0, 0, 0],
[0, 0, 0]])

In [88]:

arr / arr

Out[88]:

array([[1., 1., 1.],
[1., 1., 1.]])

In [89]:

arr * arr

Out[89]:

array([[ 1, 4, 9],
[ 121, 484, 1089]])

数组在进行矢量化运算时,要求数组的形状是相等的。当两个数组的形状不相同的时候,可以通过扩展数组的方法来实现相加、相减、相乘等操作,这种机制叫做广播(broadcasting)。

矩阵乘法

大学线性代数课程中讲过矩阵的知识。矩阵在这里可以看成二维数组。

矩阵乘法:(M行, N列) * (N行, L列) = (M行, L列)。计算过程如下图所示:

下面举一个简单的例子说明矩阵乘法的应用。

很多学科的最终成绩都是综合平时成绩与期末成绩得到的,即:

平时成绩 * 0.3 + 期末成绩  * 0.7 = 最终成绩

用矩阵乘法来计算就是:

看下在NumPy中如何计算矩阵乘法:

In [90]:

a = np.array([[80, 86],
[82, 80],
[85, 78],
[90, 90],
[86, 82],
[82, 90],
[78, 80],
[92, 94]])

In [91]:

b = np.array([[0.3], [0.7]])

In [92]:

np.matmul(a, b)

Out[92]:

array([[84.2],
[80.6],
[80.1],
[90. ],
[83.2],
[87.6],
[79.4],
[93.4]])

另外,np.dot也可以计算矩阵乘法,如下:

In [93]:

np.dot(a, b)

Out[93]:

array([[84.2],
[80.6],
[80.1],
[90. ],
[83.2],
[87.6],
[79.4],
[93.4]])

np.matmul不同的是,np.dot还可以与标量进行乘法运算:

In [94]:

np.dot(a, 2)

Out[94]:

array([[160, 172],
[164, 160],
[170, 156],
[180, 180],
[172, 164],
[164, 180],
[156, 160],
[184, 188]])