add python

pull/1/head
wanglei 2020-08-09 21:56:03 +08:00
parent bc95cbbee3
commit d58c40d3d6
9 changed files with 1700 additions and 0 deletions

View File

@ -0,0 +1,825 @@
原文链接地址http://liam0205.me/2014/09/11/matplotlib-tutorial-zh-cn/
## 1.介绍
Matplotlib 可能是 Python 2D-绘图领域使用最广泛的套件。它能让使用者很轻松地将数据图形化,并且提供多样化的输出格式。这里将会探索 matplotlib 的常见用法。
## 2.pylab
pylab 是 matplotlib 面向对象绘图库的一个接口。它的语法和 Matlab 十分相近。也就是说,它主要的绘图命令和 Matlab 对应的命令有相似的参数。
## 3.初级绘制
这一节中,我们将从简到繁:先尝试用默认配置在同一张图上绘制正弦和余弦函数图像,然后逐步美化它。
### 1.取得正弦函数和预先函数的值:
```
from matplotlib import pylab
import numpy as np
def getData():
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)
print X
getData()
```
X 是一个 numpy 数组,包含了从 −π到 +π等间隔的 256 个值。C 和 S 则分别是这 256 个值对应的余弦和正弦函数值组成的 numpy 数组。
### 2.使用默认配置
Matplotlib 的默认配置都允许用户自定义。你可以调整大多数的默认配置图片大小和分辨率dpi、线宽、颜色、风格、坐标轴、坐标轴以及网格的属性、文字与字体属性等。不过matplotlib 的默认配置在大多数情况下已经做得足够好,你可能只在很少的情况下才会想更改这些默认配置。
### 3.默认配置的具体内容
下面的代码中,我们展现了 matplotlib 的默认配置并辅以注释说明,这部分配置包含了有关绘图样式的所有配置。代码中的配置与默认配置完全相同,你可以在交互模式中修改其中的值来观察效果。
```
import numpy as np
import matplotlib.pyplot as plt
# 创建一个 8 * 6 点point的图并设置分辨率为 80
plt.figure(figsize=(8,6), dpi=80)
# 创建一个新的 1 * 1 的子图,接下来的图样绘制在其中的第 1 块(也是唯一的一块)
plt.subplot(111)
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)
# 绘制余弦曲线,使用蓝色的、连续的、宽度为 1 (像素)的线条
plt.plot(X, C, color="blue", linewidth=1.0, linestyle="-")
# 绘制正弦曲线,使用绿色的、连续的、宽度为 1 (像素)的线条
plt.plot(X, S, color="green", linewidth=1.0, linestyle="-")
# 设置横轴的上下限
plt.xlim(-4.0,4.0)
# 设置横轴记号
plt.xticks(np.linspace(-4,4,9,endpoint=True))
# 设置纵轴的上下限
plt.ylim(-1.0,1.0)
# 设置纵轴记号
plt.yticks(np.linspace(-1,1,5,endpoint=True))
# 以分辨率 72 来保存图片
# savefig("../figures/exercice_2.png",dpi=72)
# 在屏幕上显示
plt.show()
```
### 4.改变线条的颜色和粗细
首先,我们以蓝色和红色分别表示余弦和正弦函数,而后将线条变粗一点。接下来,我们在水平方向拉伸一下整个图。
```
import numpy as np
import matplotlib.pyplot as plt
plt.figure(figsize=(8,5), dpi=80)
plt.subplot(111)
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)
plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-")
plt.plot(X, S, color="red", linewidth=2.5, linestyle="-")
plt.xlim(-4.0,4.0)
plt.xticks(np.linspace(-4,4,9,endpoint=True))
plt.ylim(-1.0,1.0)
plt.yticks(np.linspace(-1,1,5,endpoint=True))
plt.show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/1.png)
### 5.设置图片边界
当前的图片边界设置得不好,所以有些地方看得不是很清楚。
```
import numpy as np
import matplotlib.pyplot as plt
plt.figure(figsize=(8,5), dpi=80)
plt.subplot(111)
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)
plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-")
plt.plot(X, S, color="red", linewidth=2.5, linestyle="-")
plt.xlim(X.min()*1.1, X.max()*1.1)
plt.ylim(C.min()*1.1,C.max()*1.1)
plt.show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/2.png)
### 6.设置记号
我们讨论正弦和余弦函数的时候,通常希望知道函数在 $±π$和 $±π/2$的值。这样看来,当前的设置就不那么理想了。
```
import numpy as np
import matplotlib.pyplot as plt
plt.figure(figsize=(8,5), dpi=80)
plt.subplot(111)
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)
plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-")
plt.plot(X, S, color="red", linewidth=2.5, linestyle="-")
plt.xlim(X.min()*1.1, X.max()*1.1)
plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi])
plt.ylim(C.min()*1.1,C.max()*1.1)
plt.yticks([-1, 0, +1])
plt.show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/3.png)
### 7.设置记号的标签
记号现在没问题了,不过标签却不大符合期望。我们可以把 3.142当做是$π$,但毕竟不够精确。当我们设置记号的时候,我们可以同时设置记号的标签。注意这里使用了 LaTeX。
```
import numpy as np
import matplotlib.pyplot as plt
plt.figure(figsize=(8,5), dpi=80)
plt.subplot(111)
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)
plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-")
plt.plot(X, S, color="red", linewidth=2.5, linestyle="-")
plt.xlim(X.min()*1.1, X.max()*1.1)
plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
[r'$-\pi$', r'$-\pi/2$', r'$0$', r'$+\pi/2$', r'$+\pi$'])
plt.ylim(C.min()*1.1,C.max()*1.1)
plt.yticks([-1, 0, +1],
[r'$-1$', r'$0$', r'$+1$'])
plt.show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/4.png)
### 8.移动脊柱
坐标轴线和上面的记号连在一起就形成了脊柱Spines一条线段上有一系列的凸起是不是很像脊柱骨啊~),它记录了数据区域的范围。它们可以放在任意位置,不过至今为止,我们都把它放在图的四边。
实际上每幅图有四条脊柱(上下左右),为了将脊柱放在图的中间,我们必须将其中的两条(上和右)设置为无色,然后调整剩下的两条到合适的位置——数据空间的 0 点。
```
import numpy as np
import matplotlib.pyplot as plt
plt.figure(figsize=(8,5), dpi=80)
ax = plt.subplot(111)
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)
plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-")
plt.plot(X, S, color="red", linewidth=2.5, linestyle="-")
plt.xlim(X.min()*1.1, X.max()*1.1)
plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
[r'$-\pi$', r'$-\pi/2$', r'$0$', r'$+\pi/2$', r'$+\pi$'])
plt.ylim(C.min()*1.1,C.max()*1.1)
plt.yticks([-1, 0, +1],
[r'$-1$', r'$0$', r'$+1$'])
plt.show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/5.png)
### 9.添加图例
我们在图的左上角添加一个图例。为此,我们只需要在 plot 函数里以「键 - 值」的形式增加一个参数。
```
import numpy as np
import matplotlib.pyplot as plt
plt.figure(figsize=(8,5), dpi=80)
ax = plt.subplot(111)
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)
plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-", label="cosine")
plt.plot(X, S, color="red", linewidth=2.5, linestyle="-", label="sine")
plt.xlim(X.min()*1.1, X.max()*1.1)
plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
[r'$-\pi$', r'$-\pi/2$', r'$0$', r'$+\pi/2$', r'$+\pi$'])
plt.ylim(C.min()*1.1,C.max()*1.1)
plt.yticks([-1, +1],
[r'$-1$', r'$+1$'])
plt.legend(loc='upper left', frameon=False)
# plt.savefig("../figures/exercice_8.png",dpi=72)
plt.show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/6.png)
### 10.给一些特殊点做注释
我们希望在 2π/3的位置给两条函数曲线加上一个注释。首先我们在对应的函数图像位置上画一个点然后向横轴引一条垂线以虚线标记最后写上标签。
```
import numpy as np
import matplotlib.pyplot as plt
plt.figure(figsize=(8,5), dpi=80)
ax = plt.subplot(111)
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)
plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-", label="cosine")
plt.plot(X, S, color="red", linewidth=2.5, linestyle="-", label="sine")
plt.xlim(X.min()*1.1, X.max()*1.1)
plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
[r'$-\pi$', r'$-\pi/2$', r'$0$', r'$+\pi/2$', r'$+\pi$'])
plt.ylim(C.min()*1.1,C.max()*1.1)
plt.yticks([-1, +1],
[r'$-1$', r'$+1$'])
t = 2*np.pi/3
plt.plot([t,t],[0,np.cos(t)],
color ='blue', linewidth=1.5, linestyle="--")
plt.scatter([t,],[np.cos(t),], 50, color ='blue')
plt.annotate(r'$\sin(\frac{2\pi}{3})=\frac{\sqrt{3}}{2}$',
xy=(t, np.sin(t)), xycoords='data',
xytext=(+10, +30), textcoords='offset points', fontsize=16,
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
plt.plot([t,t],[0,np.sin(t)],
color ='red', linewidth=1.5, linestyle="--")
plt.scatter([t,],[np.sin(t),], 50, color ='red')
plt.annotate(r'$\cos(\frac{2\pi}{3})=-\frac{1}{2}$',
xy=(t, np.cos(t)), xycoords='data',
xytext=(-90, -50), textcoords='offset points', fontsize=16,
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
plt.legend(loc='upper left', frameon=False)
#plt.savefig("../figures/exercice_9.png",dpi=72)
plt.show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/7.png)
### 11.精益求精
坐标轴上的记号标签被曲线挡住了,作为强迫症患者(雾)这是不能忍的。我们可以把它们放大,然后添加一个白色的半透明底色。这样可以保证标签和曲线同时可见。
```
import numpy as np
import matplotlib.pyplot as plt
plt.figure(figsize=(8,5), dpi=80)
ax = plt.subplot(111)
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)
plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-", label="cosine")
plt.plot(X, S, color="red", linewidth=2.5, linestyle="-", label="sine")
plt.xlim(X.min()*1.1, X.max()*1.1)
plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
[r'$-\pi$', r'$-\pi/2$', r'$0$', r'$+\pi/2$', r'$+\pi$'])
plt.ylim(C.min()*1.1,C.max()*1.1)
plt.yticks([-1, +1],
[r'$-1$', r'$+1$'])
plt.legend(loc='upper left', frameon=False)
t = 2*np.pi/3
plt.plot([t,t],[0,np.cos(t)],
color ='blue', linewidth=1.5, linestyle="--")
plt.scatter([t,],[np.cos(t),], 50, color ='blue')
plt.annotate(r'$\sin(\frac{2\pi}{3})=\frac{\sqrt{3}}{2}$',
xy=(t, np.sin(t)), xycoords='data',
xytext=(+10, +30), textcoords='offset points', fontsize=16,
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
plt.plot([t,t],[0,np.sin(t)],
color ='red', linewidth=1.5, linestyle="--")
plt.scatter([t,],[np.sin(t),], 50, color ='red')
plt.annotate(r'$\cos(\frac{2\pi}{3})=-\frac{1}{2}$',
xy=(t, np.cos(t)), xycoords='data',
xytext=(-90, -50), textcoords='offset points', fontsize=16,
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
for label in ax.get_xticklabels() + ax.get_yticklabels():
label.set_fontsize(16)
label.set_bbox(dict(facecolor='white', edgecolor='None', alpha=0.65 ))
#plt.savefig("../figures/exercice_10.png",dpi=72)
plt.show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/8.png)
## 4.图像、子图、坐标轴和记号
到目前为止我们都用隐式的方法来绘制图像和坐标轴。快速绘图中这是很方便的。我们也可以显式地控制图像、子图、坐标轴。Matplotlib 中的「图像」指的是用户界面看到的整个窗口内容。在图像里面有所谓「子图」。子图的位置是由坐标网格确定的,而「坐标轴」却不受此限制,可以放在图像的任意位置。我们已经隐式地使用过图像和子图:当我们调用 plot 函数的时候matplotlib 调用 gca() 函数以及 gcf() 函数来获取当前的坐标轴和图像;如果无法获取图像,则会调用 figure() 函数来创建一个——严格地说,是用 subplot(1,1,1) 创建一个只有一个子图的图像。
### 1.图像
所谓「图像」就是 GUI 里以「Figure #」为标题的那些窗口。图像编号从 1 开始,与 MATLAB 的风格一致,而于 Python 从 0 开始编号的风格不同。以下参数是图像的属性:
<table border="1"><colgroup><col width="17%"><col width="28%"><col width="54%"></colgroup><thead valign="bottom"><tr><th class="head">参数</th><th class="head">默认值</th><th class="head">描述</th></tr></thead><tbody valign="top"><tr><td>num</td><td>1</td><td>图像的数量</td></tr><tr><td>figsize</td><td>figure.figsize</td><td>图像的长和宽(英寸)</td></tr><tr><td>dpi</td><td>figure.dpi</td><td>分辨率(点/英寸)</td></tr><tr><td>facecolor</td><td>figure.facecolor</td><td>绘图区域的背景颜色</td></tr><tr><td>edgecolor</td><td>figure.edgecolor</td><td>绘图区域边缘的颜色</td></tr><tr><td>frameon</td><td>True</td><td>是否绘制图像边缘</td></tr></tbody></table>
这些默认值可以在源文件中指明。不过除了图像数量这个参数,其余的参数都很少修改。
你在图形界面中可以按下右上角的 X 来关闭窗口OS X 系统是左上角。Matplotlib 也提供了名为 close 的函数来关闭这个窗口。close 函数的具体行为取决于你提供的参数:
1.不传递参数:关闭当前窗口;
2.传递窗口编号或窗口实例instance作为参数关闭指定的窗口
3.all关闭所有窗口。
和其他对象一样,你可以使用 setp 或者是 set_something 这样的方法来设置图像的属性。
### 2.子图
你可以用子图来将图样plot放在均匀的坐标网格中。用 subplot 函数的时候你需要指明网格的行列数量以及你希望将图样放在哪一个网格区域中。此外gridspec 的功能更强大,你也可以选择它来实现这个功能。
```
from pylab import *
subplot(2,1,1)
xticks([]), yticks([])
text(0.5,0.5, 'subplot(2,1,1)',ha='center',va='center',size=24,alpha=.5)
subplot(2,1,2)
xticks([]), yticks([])
text(0.5,0.5, 'subplot(2,1,2)',ha='center',va='center',size=24,alpha=.5)
# plt.savefig('../figures/subplot-horizontal.png', dpi=64)
show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/9.png)
```
from pylab import *
subplot(1,2,1)
xticks([]), yticks([])
text(0.5,0.5, 'subplot(1,2,1)',ha='center',va='center',size=24,alpha=.5)
subplot(1,2,2)
xticks([]), yticks([])
text(0.5,0.5, 'subplot(1,2,2)',ha='center',va='center',size=24,alpha=.5)
# plt.savefig('../figures/subplot-vertical.png', dpi=64)
show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/10.png)
```
from pylab import *
subplot(2,2,1)
xticks([]), yticks([])
text(0.5,0.5, 'subplot(2,2,1)',ha='center',va='center',size=20,alpha=.5)
subplot(2,2,2)
xticks([]), yticks([])
text(0.5,0.5, 'subplot(2,2,2)',ha='center',va='center',size=20,alpha=.5)
subplot(2,2,3)
xticks([]), yticks([])
text(0.5,0.5, 'subplot(2,2,3)',ha='center',va='center',size=20,alpha=.5)
subplot(2,2,4)
xticks([]), yticks([])
text(0.5,0.5, 'subplot(2,2,4)',ha='center',va='center',size=20,alpha=.5)
# savefig('../figures/subplot-grid.png', dpi=64)
show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/11.png)
```
from pylab import *
import matplotlib.gridspec as gridspec
G = gridspec.GridSpec(3, 3)
axes_1 = subplot(G[0, :])
xticks([]), yticks([])
text(0.5,0.5, 'Axes 1',ha='center',va='center',size=24,alpha=.5)
axes_2 = subplot(G[1,:-1])
xticks([]), yticks([])
text(0.5,0.5, 'Axes 2',ha='center',va='center',size=24,alpha=.5)
axes_3 = subplot(G[1:, -1])
xticks([]), yticks([])
text(0.5,0.5, 'Axes 3',ha='center',va='center',size=24,alpha=.5)
axes_4 = subplot(G[-1,0])
xticks([]), yticks([])
text(0.5,0.5, 'Axes 4',ha='center',va='center',size=24,alpha=.5)
axes_5 = subplot(G[-1,-2])
xticks([]), yticks([])
text(0.5,0.5, 'Axes 5',ha='center',va='center',size=24,alpha=.5)
#plt.savefig('../figures/gridspec.png', dpi=64)
show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/12.png)
### 3.坐标轴
坐标轴和子图功能类似,不过它可以放在图像的任意位置。因此,如果你希望在一副图中绘制一个小图,就可以用这个功能。
```
from pylab import *
axes([0.1,0.1,.8,.8])
xticks([]), yticks([])
text(0.6,0.6, 'axes([0.1,0.1,.8,.8])',ha='center',va='center',size=20,alpha=.5)
axes([0.2,0.2,.3,.3])
xticks([]), yticks([])
text(0.5,0.5, 'axes([0.2,0.2,.3,.3])',ha='center',va='center',size=16,alpha=.5)
#plt.savefig("../figures/axes.png",dpi=64)
show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/13.png)
```
from pylab import *
axes([0.1,0.1,.5,.5])
xticks([]), yticks([])
text(0.1,0.1, 'axes([0.1,0.1,.8,.8])',ha='left',va='center',size=16,alpha=.5)
axes([0.2,0.2,.5,.5])
xticks([]), yticks([])
text(0.1,0.1, 'axes([0.2,0.2,.5,.5])',ha='left',va='center',size=16,alpha=.5)
axes([0.3,0.3,.5,.5])
xticks([]), yticks([])
text(0.1,0.1, 'axes([0.3,0.3,.5,.5])',ha='left',va='center',size=16,alpha=.5)
axes([0.4,0.4,.5,.5])
xticks([]), yticks([])
text(0.1,0.1, 'axes([0.4,0.4,.5,.5])',ha='left',va='center',size=16,alpha=.5)
# plt.savefig("../figures/axes-2.png",dpi=64)
show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/14.png)
### 4.记号
良好的记号是图像的重要组成部分。Matplotlib 里的记号系统里的各个细节都是可以由用户个性化配置的。你可以用 Tick Locators 来指定在那些位置放置记号,用 Tick Formatters 来调整记号的样式。主要和次要的记号可以以不同的方式呈现。默认情况下每一个次要的记号都是隐藏的也就是说默认情况下的次要记号列表是空的——NullLocator。
下面有为不同需求设计的一些 Locators。
<table border="1"><tr><th class="head">类型</th> <th class="head">说明</th></tr><tr><td><tt>NullLocator</tt></td><td><p>No ticks.</p><img src="http://www.loria.fr/~rougier/teaching/matplotlib/figures/ticks-NullLocator.png"></td></tr><tr><td><tt>IndexLocator</tt></td><td><p>Place a tick on every multiple of some base number of points plotted.</p><img src="http://www.loria.fr/~rougier/teaching/matplotlib/figures/ticks-IndexLocator.png"></td></tr><tr><td><tt>FixedLocator</tt></td><td><p>Tick locations are fixed.</p><img src="http://www.loria.fr/~rougier/teaching/matplotlib/figures/ticks-FixedLocator.png"></td></tr><tr><td><tt>LinearLocator</tt></td><td><p>Determine the tick locations.</p><img src="http://www.loria.fr/~rougier/teaching/matplotlib/figures/ticks-LinearLocator.png"></td></tr><tr><td><tt>MultipleLocator</tt></td><td><p>Set a tick on every integer that is multiple of some base.</p><img src="http://www.loria.fr/~rougier/teaching/matplotlib/figures/ticks-MultipleLocator.png"></td></tr><tr><td><tt>AutoLocator</tt></td><td><p>Select no more than n intervals at nice locations.</p><img src="http://www.loria.fr/~rougier/teaching/matplotlib/figures/ticks-AutoLocator.png"></td></tr><tr><td><tt>LogLocator</tt></td><td><p>Determine the tick locations for log axes.</p><img src="http://www.loria.fr/~rougier/teaching/matplotlib/figures/ticks-LogLocator.png"></td></tr></table>
这些 Locators 都是 matplotlib.ticker.Locator 的子类,你可以据此定义自己的 Locator。以日期为 ticks 特别复杂,因此 Matplotlib 提供了 matplotlib.dates 来实现这一功能。
## 5.其他类型的图
接下来的内容是练习。请运用你学到的知识,从提供的代码开始,实现配图所示的效果。具体的答案可以点击配图下载。
### 1.普通图
```
import numpy as np
import matplotlib.pyplot as plt
n = 256
X = np.linspace(-np.pi,np.pi,n,endpoint=True)
Y = np.sin(2*X)
plt.axes([0.025,0.025,0.95,0.95])
plt.plot (X, Y+1, color='blue', alpha=1.00)
plt.fill_between(X, 1, Y+1, color='blue', alpha=.25)
plt.plot (X, Y-1, color='blue', alpha=1.00)
plt.fill_between(X, -1, Y-1, (Y-1) > -1, color='blue', alpha=.25)
plt.fill_between(X, -1, Y-1, (Y-1) < -1, color='red', alpha=.25)
plt.xlim(-np.pi,np.pi), plt.xticks([])
plt.ylim(-2.5,2.5), plt.yticks([])
# savefig('../figures/plot_ex.png',dpi=48)
plt.show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/15.png)
### 2.散点图
```
import numpy as np
import matplotlib.pyplot as plt
n = 1024
X = np.random.normal(0,1,n)
Y = np.random.normal(0,1,n)
T = np.arctan2(Y,X)
plt.axes([0.025,0.025,0.95,0.95])
plt.scatter(X,Y, s=75, c=T, alpha=.5)
plt.xlim(-1.5,1.5), plt.xticks([])
plt.ylim(-1.5,1.5), plt.yticks([])
# savefig('../figures/scatter_ex.png',dpi=48)
plt.show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/16.png)
### 3.条形图
```
import numpy as np
import matplotlib.pyplot as plt
n = 12
X = np.arange(n)
Y1 = (1-X/float(n)) * np.random.uniform(0.5,1.0,n)
Y2 = (1-X/float(n)) * np.random.uniform(0.5,1.0,n)
plt.axes([0.025,0.025,0.95,0.95])
plt.bar(X, +Y1, facecolor='#9999ff', edgecolor='white')
plt.bar(X, -Y2, facecolor='#ff9999', edgecolor='white')
for x,y in zip(X,Y1):
plt.text(x+0.4, y+0.05, '%.2f' % y, ha='center', va= 'bottom')
for x,y in zip(X,Y2):
plt.text(x+0.4, -y-0.05, '%.2f' % y, ha='center', va= 'top')
plt.xlim(-.5,n), plt.xticks([])
plt.ylim(-1.25,+1.25), plt.yticks([])
# savefig('../figures/bar_ex.png', dpi=48)
plt.show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/17.png)
### 4.等高线图
```
import numpy as np
import matplotlib.pyplot as plt
def f(x,y):
return (1-x/2+x**5+y**3)*np.exp(-x**2-y**2)
n = 256
x = np.linspace(-3,3,n)
y = np.linspace(-3,3,n)
X,Y = np.meshgrid(x,y)
plt.axes([0.025,0.025,0.95,0.95])
plt.contourf(X, Y, f(X,Y), 8, alpha=.75, cmap=plt.cm.hot)
C = plt.contour(X, Y, f(X,Y), 8, colors='black', linewidth=.5)
plt.clabel(C, inline=1, fontsize=10)
plt.xticks([]), plt.yticks([])
# savefig('../figures/contour_ex.png',dpi=48)
plt.show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/18.png)
### 5.灰度图Imshow
```
import numpy as np
import matplotlib.pyplot as plt
def f(x,y):
return (1-x/2+x**5+y**3)*np.exp(-x**2-y**2)
n = 10
x = np.linspace(-3,3,3.5*n)
y = np.linspace(-3,3,3.0*n)
X,Y = np.meshgrid(x,y)
Z = f(X,Y)
plt.axes([0.025,0.025,0.95,0.95])
plt.imshow(Z,interpolation='nearest', cmap='bone', origin='lower')
plt.colorbar(shrink=.92)
plt.xticks([]), plt.yticks([])
# savefig('../figures/imshow_ex.png', dpi=48)
plt.show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/19.png)
### 6.饼状图
```
import numpy as np
import matplotlib.pyplot as plt
n = 20
Z = np.ones(n)
Z[-1] *= 2
plt.axes([0.025,0.025,0.95,0.95])
plt.pie(Z, explode=Z*.05, colors = ['%f' % (i/float(n)) for i in range(n)])
plt.gca().set_aspect('equal')
plt.xticks([]), plt.yticks([])
# savefig('../figures/pie_ex.png',dpi=48)
plt.show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/20.png)
### 7.量场图Quiver Plots
```
import numpy as np
import matplotlib.pyplot as plt
n = 8
X,Y = np.mgrid[0:n,0:n]
T = np.arctan2(Y-n/2.0, X-n/2.0)
R = 10+np.sqrt((Y-n/2.0)**2+(X-n/2.0)**2)
U,V = R*np.cos(T), R*np.sin(T)
plt.axes([0.025,0.025,0.95,0.95])
plt.quiver(X,Y,U,V,R, alpha=.5)
plt.quiver(X,Y,U,V, edgecolor='k', facecolor='None', linewidth=.5)
plt.xlim(-1,n), plt.xticks([])
plt.ylim(-1,n), plt.yticks([])
# savefig('../figures/quiver_ex.png',dpi=48)
plt.show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/21.png)
### 8.网格
```
import numpy as np
import matplotlib.pyplot as plt
ax = plt.axes([0.025,0.025,0.95,0.95])
ax.set_xlim(0,4)
ax.set_ylim(0,3)
ax.xaxis.set_major_locator(plt.MultipleLocator(1.0))
ax.xaxis.set_minor_locator(plt.MultipleLocator(0.1))
ax.yaxis.set_major_locator(plt.MultipleLocator(1.0))
ax.yaxis.set_minor_locator(plt.MultipleLocator(0.1))
ax.grid(which='major', axis='x', linewidth=0.75, linestyle='-', color='0.75')
ax.grid(which='minor', axis='x', linewidth=0.25, linestyle='-', color='0.75')
ax.grid(which='major', axis='y', linewidth=0.75, linestyle='-', color='0.75')
ax.grid(which='minor', axis='y', linewidth=0.25, linestyle='-', color='0.75')
ax.set_xticklabels([])
ax.set_yticklabels([])
# savefig('../figures/grid_ex.png',dpi=48)
plt.show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/22.png)
### 9.多重网格
```
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
fig.subplots_adjust(bottom=0.025, left=0.025, top = 0.975, right=0.975)
plt.subplot(2,1,1)
plt.xticks([]), plt.yticks([])
plt.subplot(2,3,4)
plt.xticks([]), plt.yticks([])
plt.subplot(2,3,5)
plt.xticks([]), plt.yticks([])
plt.subplot(2,3,6)
plt.xticks([]), plt.yticks([])
# plt.savefig('../figures/multiplot_ex.png',dpi=48)
plt.show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/23.png)
### 10.极轴图
```
import numpy as np
import matplotlib.pyplot as plt
ax = plt.axes([0.025,0.025,0.95,0.95], polar=True)
N = 20
theta = np.arange(0.0, 2*np.pi, 2*np.pi/N)
radii = 10*np.random.rand(N)
width = np.pi/4*np.random.rand(N)
bars = plt.bar(theta, radii, width=width, bottom=0.0)
for r,bar in zip(radii, bars):
bar.set_facecolor( plt.cm.jet(r/10.))
bar.set_alpha(0.5)
ax.set_xticklabels([])
ax.set_yticklabels([])
# savefig('../figures/polar_ex.png',dpi=48)
plt.show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/24.png)
### 11.3D 图
```
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = Axes3D(fig)
X = np.arange(-4, 4, 0.25)
Y = np.arange(-4, 4, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=plt.cm.hot)
ax.contourf(X, Y, Z, zdir='z', offset=-2, cmap=plt.cm.hot)
ax.set_zlim(-2,2)
# savefig('../figures/plot3d_ex.png',dpi=48)
plt.show()
```
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/matplot/25.png)
## 参考文献:
1.https://www.jianshu.com/p/dade014011ca Python数字图像处理:图像的绘制
2.https://www.jianshu.com/p/f380169aee6c?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation Matplotlib - 用Python绘制2D和3D图像

View File

@ -0,0 +1,206 @@
这是最受欢迎的Python模块的前200名, 评比的依据是模块在github上开源Python项目中被使用的次数. 看看有没有跌破你的眼镜!
名次 模块名称 被使用项目数
```
1 sys 7858
2 os 6983
3 re 5663
4 time 5268
5 random 3339
6 datetime 3310
7 setuptools 3225
8 logging 3189
9 subprocess 2991
10 unittest 2923
11 json 2865
12 urllib 2641
13 __future__ 2541
14 collections 2295
15 shutil 2255
16 string 2254
17 threading 2220
18 math 2205
19 tempfile 2151
20 urllib2 2095
21 socket 2079
22 traceback 2070
23 copy 2055
24 optparse 2053
25 hashlib 2025
26 StringIO 1812
27 django.db 1780
28 distutils.core 1780
29 struct 1753
30 itertools 1720
31 django.conf 1719
32 types 1667
33 django.core.management 1658
34 django.contrib 1604
35 glob 1582
36 urlparse 1559
37 base64 1555
38 inspect 1523
39 django.http 1510
40 django 1496
41 cStringIO 1447
42 os.path 1432
43 django.shortcuts 1419
44 functools 1395
45 argparse 1379
46 operator 1360
47 warnings 1345
48 codecs 1308
49 django.template 1262
50 django.test 1216
51 pickle 1200
52 errno 1133
53 pprint 1107
54 signal 1102
55 requests 1082
56 cgi 1052
57 django.contrib.auth.models 1018
58 getopt 1010
59 ConfigParser 972
60 django.core.urlresolvers 963
61 httplib 947
62 uuid 938
63 pkg_resources 906
64 imp 901
65 doctest 899
66 csv 893
67 django.db.models 877
68 zipfile 861
69 textwrap 860
70 django.utils 844
71 gzip 817
72 io 804
73 platform 798
74 django.core.exceptions 775
75 md5 755
76 xml.dom 753
77 binascii 751
78 fnmatch 750
79 Queue 744
80 getpass 719
81 select 701
82 utils 699
83 stat 693
84 numpy 685
85 mimetypes 683
86 ctypes 678
87 models 673
88 django.contrib.auth.decorators 669
89 django.core.management.base 664
90 zlib 649
91 simplejson 648
92 thread 644
93 distutils 643
94 django.template.loader 632
95 fcntl 617
96 contextlib 614
97 django.utils.encoding 605
98 decimal 592
99 atexit 576
100 locale 575
101 django.core 572
102 PIL 554
103 cPickle 552
104 calendar 551
105 yaml 547
106 multiprocessing 544
107 hmac 540
108 django.utils.safestring 540
109 django.conf.urls 537
110 weakref 533
111 unicodedata 527
112 mock 517
113 tarfile 504
114 django.contrib.auth 504
115 settings 500
116 smtplib 480
117 htmlentitydefs 475
118 array 474
119 sqlite3 462
120 google.appengine.api 457
121 email 457
122 django.template.defaultfilters 455
123 util 454
124 sha 452
125 flask 452
126 config 444
127 UserDict 440
128 django.contrib.sites.models 439
129 shlex 438
130 lxml 436
131 difflib 432
132 django.core.mail 431
133 BaseHTTPServer 424
134 webbrowser 424
135 gc 419
136 django.forms 417
137 django.contrib.contenttypes.models 413
138 Image 407
139 jinja2 406
140 django.utils.html 396
141 bisect 394
142 twisted.internet 384
143 django.conf.urls.defaults 379
144 commands 375
145 pdb 374
146 pwd 373
147 sqlalchemy 368
148 pytest 366
149 django.core.cache 364
150 BeautifulSoup 359
151 xml.dom.minidom 357
152 django.views.generic.simple 355
153 django.views.generic 355
154 xmlrpclib 355
155 Cookie 355
156 exceptions 353
157 sets 349
158 posixpath 348
159 SocketServer 347
160 code 343
161 django.core.paginator 338
162 gettext 338
163 google.appengine.ext.webapp 336
164 urllib.request 334
165 south.db 332
166 urllib.parse 329
167 new 329
168 pstats 329
169 msvcrt 328
170 __builtin__ 325
171 ez_setup 324
172 gtk 323
173 django.dispatch 321
174 MySQLdb 318
175 HTMLParser 315
176 termios 311
177 scipy 311
178 pkgutil 309
179 abc 309
180 matplotlib 307
181 django.db.models.signals 306
182 six 306
183 xml.sax.saxutils 303
184 xml.sax 301
185 chardet 298
186 heapq 296
187 django.test.client 295
188 cProfile 295
189 bs4 290
190 sgmllib 289
191 django.utils.functional 287
192 xml.etree 286
193 ssl 283
194 tokenize 282
195 django.db.models.query 281
196 xml 281
197 nose.tools 281
198 nose 275
199 pygments 273
200 gobject 270
```

View File

@ -0,0 +1,192 @@
## 1.json是什么
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。json最大的优势就是独立于编程语言 易于人阅读和编写同时也易于机器解析和生成。所以如果我们需要在不同的编程语言之间传递对象或者需要在网络世界中传输数据我们都可以将数据序列化为json格式。当将其序列化为json格式以后可以方便地被所有编程语言读取与解析也可以方便地被存储在磁盘中或者用于网络传输。正因为有这些优点json在实际中使用非常广泛。
JSON构建于两种结构
1.“名称/值”对的集合A collection of name/value pairs。不同的语言中它被理解为对象object纪录record结构struct字典dictionary哈希表hash table有键列表keyed list或者关联数组 associative array
2.值的有序列表An ordered list of values。在大部分语言中它被理解为数组array
## 2.python数据类型与json数据类型的映射关系
Python类型 JSON类型
dict $\hspace{1.3cm}$ {}
list $\hspace{1.5cm}$ []
str(unicode) $\hspace{0.5cm}$ string
int(float,long) $\hspace{0.3cm}$number
True(False) $\hspace{0.7cm}$ true(false)
None $\hspace{1.7cm}$ null
## 3.python中json模块的简单用法
python中内置的json模块就可以完成从python对象到json格式数据的转换。
先来看看怎么把一个python对象变为一个json串
```
>>> import json
>>> dic = dict(name='James',age=18)
>>> dic_to_str = json.dumps(dic)
>>> dic_to_str
'{"age": 18, "name": "James"}'
>>> type(dic_to_str)
<type 'str'>
```
通过dumps方法就把一个dict变为了一个json串返回的是一个str对象。dumps方法相当于一个encoding过程是对简单数据类型的编码。也可以理解是对python对象的一个序列化的过程。
接下来看看如何把一个json串变为一个python对象
```
>>> str_to_dic = json.loads(dic_to_str)
>>> str_to_dic
{u'age': 18, u'name': u'James'}
>>> type(str_to_dic)
<type 'dict'>
```
同理通过loads方法将一个json串变为了一个dict对象返回的是一个dict。loads方法相当于是一个decoding过程是对字符串的一个解码。当然也可以理解为是对python对象的反序列化
## 4.将自己的类转成json串
前面我们看了怎样将python中的内置dict对象转化为json串的过程。在很多时候我们希望将自己定义的类也转化为json串。比如我们自己定义了person类并且希望将其序列化为json串
```
#!/usr/bin/env python
#coding:utf-8
import json
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
person = Person("James",18)
print (json.dumps(person))
```
将上面的代码run起来以后会有以下错误
```
Traceback (most recent call last):
File "./person.py", line 13, in <module>
print (json.dumps(person))
File "/Users/lei.wang/anaconda/lib/python2.7/json/__init__.py", line 244, in dumps
return _default_encoder.encode(obj)
File "/Users/lei.wang/anaconda/lib/python2.7/json/encoder.py", line 207, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/Users/lei.wang/anaconda/lib/python2.7/json/encoder.py", line 270, in iterencode
return _iterencode(o, 0)
File "/Users/lei.wang/anaconda/lib/python2.7/json/encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <__main__.Person object at 0x101a00090> is not JSON serializable
```
很明显可以看出是我们无法将person对象序列化
我们再仔细观察一下dumps()方法:
```
json.dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, encoding="utf-8", default=None, sort_keys=False, **kw)
Serialize obj to a JSON formatted str using this conversion table. If ensure_ascii is false, the result may contain non-ASCII characters and the return value may be a unicode instance.
```
参数default选项就是将一个对象变为一个可序列化的Json对象。前面的Person类就是因为没有指定default选项所以无法序列化。现在我们为Person类写一个专门的序列化方法
```
!/usr/bin/env python
#coding:utf-8
import json
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def person_to_dict(person):
return {
'name': person.name,
'age': person.age
}
person = Person("James",18)
print json.dumps(person,default = person_to_dict)
```
将代码运行起来:
```
{"age": 18, "name": "James"}
```
上面这么做的目的就是通过person_to_dict方法将person对象转化为dict对象然后通过将default选项设置为person_to_dict就可以使用dumps方法将person对象序列化为json对象了
当然如果我们想偷点懒也是可以的。可以不写person_to_dict方法直接调用person类的__dict__方法
```
!/usr/bin/env python
#coding:utf-8
import json
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def person_to_dict(person):
return {
'name': person.name,
'age': person.age
}
person = Person("James",18)
print json.dumps(person,default = lambda obj:obj.__dict__)
print json.dumps(person,default = person_to_dict)
```
让代码run起来
```
{"age": 18, "name": "James"}
{"age": 18, "name": "James"}
```
由此可见print两行代码的效果是一致的
同样的道理既然能将自己定义的类转化为json串同理也能将json串变为类。我们先看看loads方法
```
json.loads(s[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])
Deserialize s (a str or unicode instance containing a JSON document) to a Python object using this conversion table.
object_hook is an optional function that will be called with the result of any object literal decoded (a dict). The return value of object_hook will be used instead of the dict. This feature can be used to implement custom decoders (e.g. JSON-RPC class hinting).
```
仿照上面的思路:
```
#!/usr/bin/env python
#coding:utf-8
import json
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def dic_to_person(dic):
return Person(dic['name'],dic['age'])
json_person = '{"name":"James","age":18}'
print json.loads(json_person,object_hook = dic_to_person)
```
让代码run起来
```
<__main__.Person object at 0x1022071d0>
```
由此可见我们通过loads方法达到了将json字符串反序列化为Person对象的目的

View File

@ -0,0 +1,101 @@
代码中经常有一些生成随机数的需求。特意整理了一下python中random模块的一些相关用法。
## python生成随机数
随机整数:
```
>>> import random
>>> random.randint(0,99)
21
```
随机选取0到100间的偶数
```
>>> import random
>>> random.randrange(0, 101, 2)
42
```
随机浮点数:
```
>>> import random
>>> random.random()
0.85415370477785668 范围0-1.0
>>> random.uniform(1, 10)
5.4221167969800881
```
## 选择一个随机元素
```
>>> random.choice("abc")
'b'
```
## 将一个列表中的元素打乱
```
>>> p = ["Python","is", "powerful","simple", "and so on..."]
>>> random.shuffle(p)
>>> print p
['and so on...', 'Python', 'powerful', 'is', 'simple']
```
## 从指定序列中随机获取指定长度片段
```
>>> list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> a=random.sample(list,5)
>>> a
[5, 2, 9, 1, 3]
>>> list
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```
## 随机字符:
```
>>> import random
>>> random.choice('abcdefg&#%^*f')
'd'
```
## 多个字符中选取特定数量的字符:
```
>>> import random
random.sample('abcdefghij',3)
['a', 'd', 'b']
```
## 多个字符中选取特定数量的字符组成新字符串:
```
>>> import random
>>> import string
>>> string.join(random.sample(['a','b','c','d','e','f','g','h','i','j'], 3)).replace(" ","")
'fih'
```
## 随机选取字符串:
```
>>> import random
>>> random.choice ( ['apple', 'pear', 'peach', 'orange', 'lemon'] )
'lemon'
```
## 洗牌:
```
>>> import random
>>> items = [1, 2, 3, 4, 5, 6]
>>> random.shuffle(items)
>>> items
[3, 2, 5, 6, 4, 1]
```

View File

@ -0,0 +1,155 @@
## 1.set类型用途
在python中dict是一种非常重要的数据结构几乎无处不见。dict是一种典型的k-v结构不管其中的元素多少查找速度是非常快的可以认为是近似的$O(1)$的查找速度而与dict本身的大小无关。
在许多场景中我们只关注dict的key而对value不care目的只是确保这个集合中元素的唯一性。这个时候set就能派上用场了。set中是一系列元素的集合这一点与list很类似。但是set中的元素有最重要的两点性质1.无序这一点与dict很像意味着就不能用索引访问里面的元素2.没有重复元素,保证了里面元素的唯一性。
## 2.set的一些简单用法
先看看如何初始化
```
>>> x1 = set("abc")
>>> x1
set(['a', 'c', 'b'])
>>> x2 = set(['a','b','d','e'])
>>> x2
set(['a', 'b', 'e', 'd'])
>>> x3 = set("hello")
>>> x3
set(['h', 'e', 'l', 'o'])
```
需要稍微注意的一点是,`x2 = set(['a','b','d','e'])`中,`['a','b','d','e']`是指传入的参数是一个list。而x2显示出来的`set(['a', 'b', 'e', 'd'])`只是说明set中有'a','b','c','d'四个元素,这个[]并不是表示一个list。
从x3可以看出重复元素在set中已经自动被干掉
如果要添加元素可以有add或者update
```
>>> y = set("123")
>>> y
set(['1', '3', '2'])
>>> y.add("4")
>>> y
set(['1', '3', '2', '4'])
>>> y.update("456")
>>> y
set(['1', '3', '2', '5', '4', '6'])
```
add不用多解释。update的解释如下
```
Update a set with the union of itself and others.
```
不难看出update是将两个set做并集的操作。或者说是将一个set中的元素添加到原set中而且由set的不重复性可知不管是add操作还是update操作都不会添加进重复元素
如果想要删除元素可以用remove方法
```
>>> y.remove('1')
>>> y
set(['3', '2', '5', '4', '6'])
```
需要注意的是使用remove方法的时候需要先判断元素在不在set中。如果元素不在集合中会报KeyError的错误
```
>>> y.remove('a')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'a'
```
## 3.遍历set
对于任意一种集合类型遍历都是最基本也是最重要的操作。因为set是一种无序集合所以遍历的时候不能通过下标索引的方式。而且不同的机器遍历出来的顺序也不尽相同
```
>>> x = set("abc")
>>> for i in x:
... print i
...
a
c
b
```
## 4.set求交并差集等操作
求两个set的并集
```
>>> x1 = set("abc")
>>> x2 = set("abde")
>>> x1 | x2
set(['a', 'c', 'b', 'e', 'd'])
>>> x1.union(x2)
set(['a', 'c', 'b', 'e', 'd'])
```
求交集:
```
>>> x1 & x2
set(['a', 'b'])
>>> x1.intersection(x2)
set(['a', 'b'])
```
在x1中但不在x2中
```
>>> x1 - x2
set(['c'])
>>> x1.difference(x2)
set(['c'])
```
不同时在x1,x2中出现
```
>>> x1 ^ x2
set(['c', 'e', 'd'])
>>> x1.symmetric_difference(x2)
set(['c', 'e', 'd'])
```
## 5.set(dict)中的key只能为不可变对象
不管是set也好还是dict也罢里面的key只能为不可变对象。这一点非常重要
在python中像数值型(number),字符串(str),元祖(tuple)为不可变类型(immutable),而像列表(list),字典(dict),集合(set)等为可变类型(mutable)。
看一个不可变类型的例子:
```
>>>a = 1 #将名字a与内存中值为1的内存绑定在一起
>>>a = 2 #将名字a与内存中值为2的内存绑定在一起而不是修改原来a绑定的内存中的值这时内存中值为1的内存地址引用计数-1当引用计数为0时内存地址被回收
>>>b = a #变量b执行与a绑定的内存
>>>b = 3 #创建一个内存值为3的内存地址与变量名字b进行绑定。这是a还是指向值为2的内存地址。
>>>a,b
>>>(2,3)
```
再看一个可变类型的例子:
```
def mutable(b = []): #函数使用了缺省变量
b.append(0)
return b
>>>mutable()
[0]
>>>mutable()
[0,0]
>>>mutable()
[0,0,0]
```
对于set类型来说所有的key均为不可变对象。如果添加可变对象会报错
```
>>> x1 = set("abc")
>>> x1.add([1,2])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
```
我们在上面想对一个set添加一个list类型的元素list是可变对象所以unhashable无法添加成功

View File

@ -0,0 +1,44 @@
在所有介绍正则表达式元字符的资料中,都会提到\b表示单词边界的意思。在python里写了一段小测试代码测试一下\b:
```
#!/usr/bin/env python
import re
def t1():
pattern = re.compile("\bprint\b")
search = pattern.search('aaa print 123 hello')
if search:
print search.group(0)
else:
print "NO"
t1()
```
运行此脚本以后,控制台华丽丽地输出一个大大的"NO",瞬间懵逼了。咋回事,难道我理解能力太差。又换了好多种自认为没问题的方式,都华丽丽地跟预期不对头。
经过长时间的google百度你是查不出来滴骚年们终于找到了问题所在。各位同学请先看代码
```
#!/usr/bin/env python
import re
def t2():
pattern = re.compile(r"\bprint\b")
search = pattern.search('aaa print 123 hello')
if search:
print "YES"
print search.group(0)
else:
print "NO"
t2()
```
各位看官看出区别来了么。没错,就"\bprint\b"前头多了个"r"。为什么会酱紫呢。
这是python字符串与正则表达式最糟糕没有之一的冲突。在python字符串中"b"是反斜杠字符ASCII值是8。如果你没有使用 raw 字符串时,那么 Python 将会把 "\b" 转换成一个回退符,你的 RE 将无法象你希望的那样匹配它了。
所以同学们在使用python做正则的时候当你想使用\b元字符的时候一定得注意咯。怎么做不用我再说了吧。
为了解决这个问题,花了大概得有一个半小时查资料。所以虽然时间已经很晚了,还是赶紧记下来再睡觉,心里才踏实。

View File

@ -0,0 +1,85 @@
获取当前路径
```
>>> import os
>>> os.getcwd()
'/home/lei.wang/merge_user_labels'
>>> os.path.abspath('.')
'/home/lei.wang/merge_user_labels'
>>> os.path.abspath(os.curdir)
'/home/lei.wang/merge_user_labels'
```
获取上层路径
```
>>> os.path.abspath('..')
'/home/lei.wang'
```
将path分割成目录和文件名二元组返回。
```
>>> os.path.split('/home/webopa/lei.wang/datas/datas_stable/good_rate')
('/home/webopa/lei.wang/datas/datas_stable', 'good_rate')
```
返回path的目录。其实就是os.path.split(path)的第一个元素。
```
>>> os.path.dirname('/home/webopa/lei.wang/datas/datas_stable/good_rate')
'/home/webopa/lei.wang/datas/datas_stable'
```
返回path最后的文件名。如何path以或\结尾那么就会返回空值。即os.path.split(path)的第二个元素。
```
>>> os.path.basename('/home/webopa/lei.wang/datas/datas_stable/good_rate')
'good_rate'
```
改变路径
```
>>> os.chdir('/home/lei.wang/datas')
>>> os.getcwd()
'/home/lei.wang/datas'
```
这样大部分的文件操作现在是相对于 /home/lei.wang/datas 来了例如fobj = open('Hello.txt'),实际上打开的是/home/lei.wang/datas/Hello.txt
判断是否是文件
```
>>> os.path.isfile('/home/webopa/lei.wang/datas/datas_stable/good_rate')
True
>>> os.path.isfile('/home/webopa/lei.wang/datas/datas_stable')
False
```
判断是否是文件夹
```
>>> os.path.isdir('/home/webopa/lei.wang/datas/datas_stable/good_rate')
False
>>> os.path.isdir('/home/webopa/lei.wang/datas/datas_stable')
True
```
判断路径是否存在(包括文件以及文件夹)
```
>>> os.path.exists('/home/webopa/lei.wang/datas/datas_stable/good_rate')
True
>>> os.path.exists('/home/webopa/lei.wang/datas/datas_stable')
True
```
返回文件的大小
```
>>> os.path.getsize('/home/webopa/lei.wang/datas/datas_stable/good_rate')
751
```
返回path所指向的文件或者目录的最后存取时间
```
>>> os.path.getatime('/home/webopa/lei.wang/datas/datas_stable')
1458617090.3319671
```
返回path所指向的文件或者目录的最后修改时间
```
>>> os.path.getmtime('/home/webopa/lei.wang/datas/datas_stable/good_rate')
1457424457.9110916
```

View File

@ -0,0 +1,24 @@
1.按value对dic进行排序,返回一个列表列表的元素是k-v对
```
list_open = sorted(dic_open_app.items(),key = lambda d:d[1],reverse = True)
```
2.为整个dic设置默认值
```
from collections import defaultdict
dic_device = defaultdict(int)
```
3.用dict函数生成字典
```
>>> a=[1,2,3]
>>> b=['a','b','c']
>>> zip(a,b)
[(1, 'a'), (2, 'b'), (3, 'c')]
>>> dict(zip(a,b))
{1: 'a', 2: 'b', 3: 'c'}
```

View File

@ -0,0 +1,68 @@
现在有如下格式的json串
```
"detail_time":"2016-03-30 16:00:00","device_id":"123456","os":"Html5Wap","session_flow_id":"1d1819f3-8e19-4597-b50d-ba379adcd8e5","user_longitude":0.0000,"user_latitude":0.0000,"search_id":xxx,"search_guid":-543326548,"search_type":7,"AAA":4,"BBB":-1,"CCC":[],"DDD":3,"EEE":2,"FFF":1459267200,"GGG":1459353600,"aaa":90954603,"bbb":[{"xxx":1500848,"x":1,"bf":0,"pp":2,"sroom":2,"ppp":108,"cost":97.2,"coupon":108,"drr":108},{"xxx":1500851,"x":1,"bf":0,"pp":1,"sroom":2,"ppp":108,"cost":97.2,"coupon":108,"drr":108},{"xxx":2336691,"x":1,"bf":1,"pp":1,"sroom":3,"ppp":199,"cost":169.15,"coupon":191,"drr":199},{"xxx":2336692,"x":1,"bf":1,"pp":2,"sroom":4,"ppp":102,"cost":91.8,"coupon":102,"drr":102},{"xxx":1500848,"x":1,"bf":0,"pp":2,"sroom":3,"ppp":118,"cost":106.2,"coupon":118,"drr":118},{"xxx":1500851,"x":1,"bf":0,"pp":1,"sroom":3,"ppp":118,"cost":106.2,"coupon":118,"drr":118},{"xxx":2336693,"x":1,"bf":1,"pp":1,"sroom":5,"ppp":199,"cost":169.15,"coupon":191,"drr":199},{"xxx":2336694,"x":1,"bf":1,"pp":2,"sroom":6,"ppp":112,"cost":100.3,"coupon":112,"drr":112},{"xxx":1500848,"x":1,"bf":0,"pp":2,"sroom":1,"ppp":98,"cost":88.2,"coupon":98,"drr":98},{"xxx":1500851,"x":1,"bf":0,"pp":1,"sroom":1,"ppp":98,"cost":88.2,"coupon":98,"drr":98},{"xxx":2336687,"x":1,"bf":1,"pp":1,"sroom":1,"ppp":189,"cost":160.65,"coupon":182,"drr":189},{"xxx":2336689,"x":1,"bf":1,"pp":2,"sroom":2,"ppp":93,"cost":83.3,"coupon":93,"drr":93},{"xxx":1500848,"x":1,"bf":0,"pp":2,"sroom":4,"ppp":128,"cost":115.2,"coupon":128,"drr":128},{"xxx":1500851,"x":1,"bf":0,"pp":1,"sroom":4,"ppp":128,"cost":115.2,"coupon":128,"drr":128},{"xxx":2336695,"x":1,"bf":1,"pp":1,"sroom":7,"ppp":239,"cost":203.15,"coupon":230,"drr":239},{"xxx":2336696,"x":1,"bf":1,"pp":2,"sroom":8,"ppp":121,"cost":108.8,"coupon":121,"drr":121}],"ppp_min":93.00,"ppp_max":239.00,"ppp_avg":134.88,"ppp_med":118.00,"ppp_min_cost":83.30,"ppp_min_promotion_type":-1,"ppp_min_promotion_amount":-1,"bf_ppp_min":149.00,"bf_ppp_min_cost":83.30,"bf_ppp_min_promotion_type":-1,"bf_ppp_min_promotion_amount":-1}
```
现在想拿到device_id的具体值。最简单的方式就是用解析json串的方式得到代码如下
```
#!/usr/bin/env python
#coding:utf-8
import json
import sys
import collections
import time
def t1():
start = time.clock()
for line in sys.stdin:
try:
line = line.strip()
decoded = json.loads(line)
device_id = decoded["device_id"]
print device_id
except Exception,ex:
pass
end = time.clock()
print "The cost time is: %f" %(end - start)
t1()
```
以上代码能顺利完成任务。
不幸的是现在是大数据时代数据量嘛自然都很大。用了一万条数据做测试耗时达到了惊人的。。。将近10s。
转换下思路,采用正则匹配的方式
```
#!/usr/bin/env python
import re
import sys
import time
def t1():
start = time.clock()
count = 0
for line in sys.stdin:
line = line.strip()
pattern = re.compile("(?:\"device_id\":\")([^\"]+)")
search = pattern.search(line)
if search:
count += 1
#print search.groups()[0]
end = time.clock()
print "The count is: %d" %(count)
print "The cost time is: %f" %(end - start)
t1()
```
注意匹配的时候
`re.compile("(?:\"device_id\":\")([^\"]+)")`
第一个分组表示不捕获,只捕获后面的分组。
同样一万条数据运行耗时是。。。0.05s。效率提高了多少倍,表示算不过来了。