<jupyter_start><jupyter_text>向量化的数组运算比纯python同等程度的运算要快很多。一个简单的例子，假设我们想要评价函数`sqrt(x^2 + y^2)`。`np.meshgrid`函数取两个1维的数组，产生一个2维的矩阵，对应于所有两个数组中(x, y)的组合：<jupyter_code>import numpy as np<jupyter_output><empty_output><jupyter_text>在进行书中的内容之前，先举个例子说明meshgrid的效果。meshgrid函数用两个坐标轴上的点在平面上画网格。用法：- `[X,Y]=meshgrid(x,y)`- `[X,Y]=meshgrid(x)`与`[X,Y]=meshgrid(x,x)`是等同的- `[X,Y,Z]=meshgrid(x,y,z)`生成三维数组，可用来计算三变量的函数和绘制三维立体图这里，主要以`[X,Y]=meshgrid(x,y)`为例，来对该函数进行介绍。`[X,Y] = meshgrid(x,y)` 将向量x和y定义的区域转换成矩阵X和Y,其中矩阵X的行向量是向量x的简单复制，而矩阵Y的列向量是向量y的简单复制(注：下面代码中X和Y均是数组，在文中统一称为矩阵了)。假设x是长度为m的向量，y是长度为n的向量，则最终生成的矩阵X和Y的维度都是 nm （注意不是mn）。<jupyter_code>m, n = (5, 3)
x = np.linspace(0, 1, m)
y = np.linspace(0, 1, n)
X, Y = np.meshgrid(x, y)
x
y
X
Y<jupyter_output><empty_output><jupyter_text>可以看到X和Y的shape都是3x5，用图的话更好理解：[](../MarkdownPhotos/chp04/v2-a7f1c996c371d1167a0fb7b5273c6d01_r.jpg)![](http://oydgk2hgw.bkt.clouddn.com/pydata-book/jaa76.jpg)把X和Y画出来后，就可以看到网格了：<jupyter_code>import matplotlib.pyplot as plt
%matplotlib inline
plt.style.use('ggplot')

plt.plot(X, Y, marker='.', color='blue', linestyle='none')<jupyter_output><empty_output><jupyter_text>可以用zip得到网格平面上坐标点的数据：<jupyter_code>z = [i for i in zip(X.flat, Y.flat)]
z<jupyter_output><empty_output><jupyter_text>好了，下面继续进入书中的内容<jupyter_code>points = np.arange(-5, 5, 0.01) # 1000 equally spaced points
xs, ys = np.meshgrid(points, points) # xs和ys是一样的
ys
z = np.sqrt(xs ** 2 + ys ** 2)
z<jupyter_output><empty_output><jupyter_text>这里我们用matplotlib把图画出来：<jupyter_code>plt.imshow(z, cmap=plt.cm.gray); plt.colorbar()
plt.title("Image plot of $\sqrt{x^2 + y^2}$ for a grid of values")<jupyter_output><empty_output><jupyter_text>1 Expressing Conditional Logic as Array Operations (像数组操作一样表示逻辑条件)`numpy.where`函数是一个向量版的三相表达式，`x if condition else y`。假设我们有一个布尔数组和两个数组：<jupyter_code>xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
cond = np.array([True, False, True, True, False])<jupyter_output><empty_output><jupyter_text>假设如果cond中为true，我们去xarr中对应的值，否则就取yarr中的值。列表表达式的话会这么写：<jupyter_code>result = [(x if c else y)
          for x, y, c in zip(xarr, yarr, cond)]

result<jupyter_output><empty_output><jupyter_text>这么做的话会有很多问题。首先，对于很大的数组，会比较慢。第二，对于多维数组不起作用。但`np.where`能让我们写得更简洁：<jupyter_code>result = np.where(cond, xarr, yarr)
result<jupyter_output><empty_output><jupyter_text>`np.where`中第二个和第三个参数不用必须是数组。where在数据分析中一个典型的用法是基于一个数组，产生一个新的数组值。假设我们有一个随机数字生成的矩阵，我们想要把所有的正数变为2，所有的负数变为-2。用where的话会非常简单：<jupyter_code>arr = np.random.randn(4, 4)
arr
arr > 0
np.where(arr > 0, 2, -2)<jupyter_output><empty_output><jupyter_text>我们可以结合标量和数组。比如只把整数变为2，其他仍未原来的数字：<jupyter_code>np.where(arr > 0, 2, arr) # set only positive value to 2<jupyter_output><empty_output><jupyter_text>2 Mathematical and Statistical Methods (数学和统计方法)一些能计算统计值的数学函数能基于整个数组，或者沿着一个axis（轴）。可以使用aggregations(often called reductions，汇总，或被叫做降维)，比如sum, mean, and std(标准差).下面是一些aggregate statistics（汇总统计）：<jupyter_code>arr = np.random.randn(5, 4)
arr
arr.mean()
np.mean(arr)
arr.sum()<jupyter_output><empty_output><jupyter_text>mean, sum这样的函数能接受axis作为参数来计算统计数字，返回的结果维度更少：<jupyter_code>arr.mean(axis=1)
arr.sum(axis=0)<jupyter_output><empty_output><jupyter_text>这里`arr.mean(1)`表示，compute mean acros the columns(计算各列之间的平均值)。`arr.sum(0)`表示，compute sum down the rows(计算各行总和)。其他一些方法，像cumsum和cumprod不做汇总，而是产生一个中间结果的数组：<jupyter_code>arr = np.array([0, 1, 2, 3, 4, 5, 6, 7])
arr.cumsum()<jupyter_output><empty_output><jupyter_text>上面的计算是一个累加的结果，`0+1=1，1+2=3，3+3=6`以此类推。<jupyter_code>np.cumsum?<jupyter_output><empty_output><jupyter_text>对于多维数组，accumulation functions（累积函数）比如cumsum，返回的是同样大小的数组，但是部分聚合会沿着指示的轴向较低维度进行切片：<jupyter_code>arr = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
arr
arr.cumsum(axis=0) # 沿着行加法
arr.cumprod(axis=1) # 沿着列乘法<jupyter_output><empty_output><jupyter_text>这里有一些基本的统计计算方法：![](http://oydgk2hgw.bkt.clouddn.com/pydata-book/9mzrp.png) 3 Methods for Boolean Arrays（布尔数组的方法）sum是用来计算布尔数组中有多少个true的：<jupyter_code>arr = np.random.randn(100)
(arr > 0).sum() # Number of positive values<jupyter_output><empty_output><jupyter_text>有两个其他方法，any和all，对于布尔数组特别有用。any检测数组中只要有一个ture返回就是true，而all检测数组中都是true才会返回true。<jupyter_code>bools = np.array([False, False, True, False])
bools.any()
bools.all()<jupyter_output><empty_output><jupyter_text>4 Sorting（排序）numpy中也有sort方法：<jupyter_code>np.random.randn?
# 返回符合正态分布的数值
arr = np.random.randn(6)
arr
arr.sort()
arr<jupyter_output><empty_output><jupyter_text>如果是多维数组，还可以按axis来排序：<jupyter_code>arr = np.random.randn(5, 3)
arr
arr.sort(1)
arr<jupyter_output><empty_output><jupyter_text>上面是直接调用数组的sort方法，会改变原有数组的顺序。但如果使用`np.sort()`函数的话，会生成一个新的排序后的结果。一个计算分位数的快捷方法是先给数组排序，然后选择某个排名的值：<jupyter_code>large_arr = np.random.randn(1000)
large_arr.sort()
large_arr[int(0.05 * len(large_arr))] # 5% quantile<jupyter_output><empty_output><jupyter_text>5 Unique and Other Set Logic (单一性和其他集合逻辑)Numpy也有一些基本的集合操作用于一维数组。`np.unique`，能返回排好序且不重复的值：<jupyter_code>names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
np.unique(names)
ints = np.array([3, 3, 3, 2, 2, 1, 1, 4, 4])
np.unique(ints)<jupyter_output><empty_output><jupyter_text>如果用纯python代码来实现的话，要这么写：<jupyter_code>sorted(set(names))<jupyter_output><empty_output><jupyter_text>`np.in1d`, 测试一个数组的值是否在另一个数组里，返回一个布尔数组：<jupyter_code>values = np.array([6, 0, 0, 3, 2, 5, 6])
np.in1d(values, [2, 3, 6])<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1630393996247655, 'fraction_numerical': 0.030393996247654785, 'mean_word_length': 11.08843537414966, 'pattern_counts': {'":': 0, '<': 97, '<?xml version=': 0, '>': 101, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '24', 'dir': 'jupyter-structured-clean-dedup', 'id': '136893', 'license': 'MIT', 'n_tokens_mistral': 3166, 'n_tokens_neox': 3222, 'n_words': 269, 'path': 'Chapter-04/4.3 Array-Oriented Programming with Arrays（数组导向编程）.ipynb', 'repo_name': 'hu4012/pydata', 'size': '5330'}