Jupyter Notebook 有两种键盘输入模式。编辑模式,允许你往单元中键入代码或文本;这时的单元框线是绿色的。命令模式,键盘输入运行程序命令;这时的单元框线是灰色。
(按键 Esc 开启)
( Enter 键启动)
简单的魔法指令 %run 运行外部的python文件 %whos 查看声明了那些变量和函数 !ls 查看当前目录下的子文件和子目录 !pwd
#科学计算库
import numpy as np
#画图的,统计学使用的图片表达库 画饼图 折线图 直方图 箱图 极图 可以读取图片和显示图片
import matplotlib.pyplot as plt
#读取图片 图片3维数组 张量
#图片的小知识 彩色图片都是3维的,最后一个维度是RGB 和 黑白图片是二维的
#jpg 0-255,每个颜色以功能更有256种颜色表示法2^8
#png 0-1 一共无限种类的颜色表示 索引png的颜色一般要比jpg鲜艳
gb1 = plt.imread('./guobin.jpg')
gb1
"""
array([[[ 67, 48, 31],
[ 76, 57, 40],
[ 77, 58, 41],
...,
[128, 146, 156],
[141, 159, 169],
[156, 174, 184]],
[[ 71, 52, 35],
[ 80, 61, 44],
[ 80, 61, 44],
...,
[129, 147, 157],
[139, 157, 167],
[150, 168, 178]],
[[ 77, 58, 41],
[ 86, 67, 50],
[ 86, 67, 50],
...,
[134, 152, 162],
[139, 157, 167],
[145, 163, 173]],
...,
[[ 83, 64, 86],
[ 78, 56, 79],
[ 75, 51, 75],
...,
[123, 86, 103],
[127, 90, 107],
[128, 91, 108]],
[[ 81, 62, 84],
[ 75, 56, 78],
[ 75, 53, 76],
...,
[125, 91, 107],
[131, 97, 113],
[135, 101, 117]],
[[ 84, 65, 87],
[ 79, 60, 82],
[ 79, 57, 80],
...,
[128, 96, 111],
[135, 103, 118],
[141, 109, 124]]], dtype=uint8)
"""
#png的图片显示、图片、资源类型
plt.imshow(gb1)
#shape查看多维数组的形状,第一个值代表数组的行数,第二个值是列数量
gb1.shape
#numeric python 数字化的python
#numpy中最重要的一个形式叫ndarray ,多维数组(列表):
n:表示的是n个
d:dimension 维度 array 数组
#Python 本身支持的数值类型有:
`int`(整型,python2 中存在 long 长整型)
`float`(浮点型)
`bool`(布尔型)
`complex`(复数型)。
#而 Numpy 支持比 Python 本身更为丰富的数值类型,细分如下:
1. `bool`:布尔类型,1 个字节,值为 True 或 False。
2. `int`:整数类型,通常为 int64 。
3. `intc`:与 C 里的 int 相同,通常为int64。=mysql bigint 2^64 金融业务中
4. `intp`:用于索引,通常为int64。
5. `int8`:字节(从 -128 到 127) tinyint = 表示年龄最合适的数据类型 (tinyint 1字节 -2 ^7 ~ 2^7-1 (-128~127))
6. `int16`:整数(从 -32768 到 32767) smallint (smallint 2字节 -2 ^15 ~ 2^15-1 (-32768~32765))
7. `int32`:整数(从 -2147483648 到 2147483647) int 做id比较合适 (int 4字节 -2 ^31~ 2^31-1 (-2147483648~2147483647))
8. `int64`:整数(从 -9223372036854775808 到 9223372036854775807) bigint
(bigint 8字节 -2 ^63 ~ 2^63-1)
9. `uint8`:无符号整数(从 0 到 255) unsigned
10. `uint16`:无符号整数(从 0 到 65535)
11. `uint32`:无符号整数(从 0 到 4294967295)
12. `uint64`:无符号整数(从 0 到 18446744073709551615)
13. `float`:float64 的简写。
14. `float16`:半精度浮点,5 位指数,10 位尾数
15. `float32`:单精度浮点,8 位指数,23 位尾数
16. `float64`:双精度浮点,11 位指数,52 位尾数
17. `complex`:complex128 的简写。
18. `complex64`:复数,由两个 32 位浮点表示。
19. `complex128`:复数,由两个 64 位浮点表示。
在 Numpy 中,上面提到的这些数值类型都被归于 `dtype(data-type)` 对象的实例。
我们可以用 `numpy.dtype(object, align, copy)` 来指定数值类型。而在数组里面,可以用 `dtype=` 参数。
>>shape:数组的形状。
>>dtype:数据类型。
buffer:对象暴露缓冲区接口。
offset:数组数据的偏移量。
>>strides:数据步长。
>>order:{'C','F'},以行或列为主排列顺序。
下面,我们来了解创建 ndarray 的一些方法。在 numpy 中,我们主要通过以下 5 种途径创建数组,它们分别是:
1.从 Python 数组结构列表,元组等转换
2.使用 np.arange、np.ones、np.zeros 等 numpy 原生方法。
3.从存储空间读取数组。
4.通过使用字符串或缓冲区从原始字节创建数组。
5.使用特殊函数,如 random。
在 numpy 中,我们使用 numpy.array 将列表或元组转换为 ndarray 数组。其方法为:
numpy.array(object, dtype=None, copy=True, order=None, subok=False, ndmin=0)
其中,参数:
object
:列表、元组等。dtype
:数据类型。如果未给出,则类型为被保存对象所需的最小类型。copy
:布尔来写,默认 True,表示复制对象。下面,通过列表创建一个 ndarray 数组:
import numpy as np
list_ = [1,2,3,4,5,6]
type(list_)
"""
list
"""
#np.array()是将其它的类型强制转换为ndarray类型
type(np.array(list_))
"""
numpy.ndarray
"""
除了直接使用 array 方法创建 ndarray,在 numpy 中还有一些方法可以创建一些有规律性的多维数。首先,我们来看一看 arange()。arange() 的功能是在给定区间内创建一系列均匀间隔的值。方法如下:
numpy.arange(start, stop, step, dtype=None)
你需要先设置值所在的区间,这里为 ``[开始, 停止),你应该能发现这是一个半开半闭区间。然后,在设置
step步长用于设置值之间的间隔。最后的可选参数
dtype可以设置返回
ndarray` 的值类型:
#arange a=array range() 仅仅只有ndarray可以使用
#半闭区间
nd1 = np.arange(0,100,dtype=np.float32)
nd1.dtype
#dtype('float32')
nd1
#array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12.,
# 13., 14., 15., 16., 17., 18., 19., 20., 21., 22., 23., 24., 25.,
# 26., 27., 28., 29., 30., 31., 32., 33., 34., 35., 36., 37., 38.,
# 39., 40., 41., 42., 43., 44., 45., 46., 47., 48., 49., 50., 51.,
# 52., 53., 54., 55., 56., 57., 58., 59., 60., 61., 62., 63., 64.,
# 65., 66., 67., 68., 69., 70., 71., 72., 73., 74., 75., 76., 77.,
# 78., 79., 80., 81., 82., 83., 84., 85., 86., 87., 88., 89., 90.,
# 91., 92., 93., 94., 95., 96., 97., 98., 99.], dtype=float32)
转变数据类型
ndarray.astype(np.float).astype
举个例子:
nd2 = np.arange(0,100,5)
nd2.dtype
#dtype('int32')
nd2.astype(np.float).dtype
#dtype('float64')
nd2.dtype
dtype('int32')
linspace
方法也可以像arange
方法很像,创建数值有规律的数组。inspace
用于在指定的区间内返回间隔均匀的值。其方法如下:
numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
start
:序列的起始值。
stop
:序列的结束值。
num
:生成的样本数。默认值为50。
endpoint
:布尔值,如果为真,则最后一个样本包含在序列内。
retstep
:布尔值,如果为真,返回间距。
dtype
:数组的类型,默认类型为float64
举个例子:
np.linspace(0,500,20,dtype=np.int8)
#array([ 0, 26, 52, 78, 105, -125, -99, -72, -46, -20, 7,
# 33, 59, 86, 112, -118, -91, -65, -39, -12], dtype=int8)
numpy.ones
用于快速创建数值全部为 1 的多维数组。其方法如下:
numpy.ones(shape, dtype=None, order='C')
其中:
shape
:用于指定数组形状,例如(1, 2)或 3。
dtype
:数据类型。
order
:{'C','F'}
,按行或列方式储存数组。
举个例子:
#主要是用来生成矩阵的 张量
#3行3列的矩阵 三维显示白的
np.ones(shape=(3,3))
#array([[1., 1., 1.],
# [1., 1., 1.],
# [1., 1., 1.]])
zeros 方法和上面的 ones 方法非常相似,不同的地方在于,这里全部填充为 0。zeros 方法和 ones 是一致的。
numpy.zeros(shape, dtype=None, order='C')
其中:
shape
:用于指定数组形状,例如(1, 2)
或3
。
dtype
:数据类型。
order
:{'C','F'}
,按行或列方式储存数组。
举个例子:
#零矩阵 三维显示为黑色
np.zeros(shape=(3,3))
#array([[0., 0., 0.],
# [0., 0., 0.],
# [0., 0., 0.]])
numpy.full用于创建一个自定义形状的数组,可以自己指定一个值,该值填满整个矩阵。
numpy.full(shape,fill_value=num)
举个例子:
np.full((2,3),[1,2,3])
#array([[1, 2, 3],
# [1, 2, 3]])
numpy.eye 用于创建一个二维数组,其特点是k
对角线上的值为 1
,其余值全部为0
。方法如下:
numpy.eye(N, M=None, k=0, dtype=<type 'float'>)
#k表示从下标第几个开始
其中:
N
:输出数组的行数。M
:输出数组的列数。k
:对角线索引:0(默认)是指主对角线,正值是指上对角线,负值是指下对角线。举个例子:
# 线代中的 I 表示的是单位矩阵
#单位矩阵 = 1 ,任何同行列的矩阵 * 单位矩阵 = 同行列的矩阵
I = np.eye(5,5)
I
#array([[1., 0., 0., 0., 0.],
# [0., 1., 0., 0., 0.],
# [0., 0., 1., 0., 0.],
# [0., 0., 0., 1., 0.],
# [0., 0., 0., 0., 1.]])
A = np.ndarray(shape=(5,5),dtype=np.uint8)
A
#array([[ 29, 0, 124, 10, 0],
# [ 0, 0, 0, 240, 211],
# [ 66, 8, 0, 0, 0],
# [ 0, 208, 57, 124, 10],
# [ 0, 0, 0, 0, 8]], dtype=uint8)
np.random.randint(low=0,high=150,size=(5,4))
low 表示的是最小值
high 表示最大值
size 是一个元祖类型,也可以是当单个值
size 是一个元祖类型,也可以是一个单个值
举例说明:
import random
a = random.randint(0,100)
b = np.random.randint(0,100,(5,4))
a
#89
b
#array([[65, 9, 40, 90],
# [12, 55, 34, 51],
# [11, 88, 63, 47],
# [28, 20, 5, 95],
# [25, 46, 13, 44]])
np.random.randn(10,5)
没有固定的参数,每多加一个数字,代表多真假一个维度 高斯分布 每个数都在0附近
#符合大部分人的利益叫标准,不符合的就是奇特的
np.random.randn(10)
#array([ 0.73884467, 1.12546145, -0.31875133, 1.23406679, -1.21103754,
# 0.21702192, 0.73010965, 0.51373047, 0.4588801 , -0.33869427])
np.random.random(size=(456,730,3))
np.random.random(size=(5,4))
#array([[0.25779635, 0.25512994, 0.59409125, 0.54831485],
# [0.87926247, 0.51460663, 0.62411483, 0.54362087],
# [0.58742786, 0.69336349, 0.59884695, 0.56414724],
# [0.45239322, 0.41447421, 0.80155812, 0.97997719],
# [0.29203909, 0.78881759, 0.69921901, 0.57236119]])
#使用random生成图片
#405,259,3
im = np.random.random(size=(405,259,3))
plt.imshow(im)#生成很模糊的随机图片
代表数据稳定性
np.random.normal(loc=170,scale=100,size=50)
normal也是一个正太分布的方法,生成一个一维数组
#方差 标准差 求解某一组数据的稳定性
np.random.normal(loc=100,scale=100,size=20)
#array([ 80.59289487, 201.63014756, 21.02589801, 26.43460996,
# 197.49101128, 36.28011324, 284.41359354, 162.45289555,
# 83.77100481, 24.54442235, 64.85440008, 142.06517234,
# 78.50036608, 75.45910752, -8.67749445, 34.43898874,
# 56.17053221, 83.01570787, 128.57554142, 213.71104168])
每一个数据,都是一个维度
rand 和 random 的区别:random 需要 size来描述形状,而rand只需要我们直接给值,通过值的数量来确定形状
np.random.rand(d1,d2,dn)
np.random.rand(5,4)
#array([[0.33992468, 0.76175452, 0.83457972, 0.47401397],
# [0.55375713, 0.15932915, 0.92629493, 0.81815607],
# [0.2395769 , 0.56686094, 0.4643644 , 0.1034782 ],
# [0.3623716 , 0.97566149, 0.08765505, 0.39677394],
# [0.95654468, 0.83481708, 0.02188148, 0.2933859 ]])
linspace是线性生成的,是全闭区间
logspace是线性生成,并且以什么为底
start:从几开始
stop 到数字结尾
num 生成多少个数
base 表示的是底数 默认以10为底
举例:
np.logspace(1,100,10)
#array([1.e+001, 1.e+012, 1.e+023, 1.e+034, 1.e+045, 1.e+056, 1.e+067,
# 1.e+078, 1.e+089, 1.e+100])
np.diag构建对角矩阵 np.diag(v,k=0)参数为列表即可
举例:
#单位矩阵一定是对角矩阵,但是对角矩阵不一定是单位矩阵
np.diag([1,2,3,4,5,6,7])
#array([[1, 0, 0, 0, 0, 0, 0],
# [0, 2, 0, 0, 0, 0, 0],
# [0, 0, 3, 0, 0, 0, 0],
# [0, 0, 0, 4, 0, 0, 0],
# [0, 0, 0, 0, 5, 0, 0],
# [0, 0, 0, 0, 0, 6, 0],
# [0, 0, 0, 0, 0, 0, 7]])
csv,dat是一种常用的数据格式化文件类型,
读取文件数据:numpy.loadtxt('文件路径')
存储文件数据:numpy.savetxt('文件路径',数据变量)
举例:
#.dat它是一个非标准文件格式
Matrix = np.random.randint(-np.e,np.e,size=(5,4))
Matrix
#array([[-1, 0, 0, 0],
# [-2, 1, -2, 1],
# [ 0, -1, 1, 0],
# [-1, -1, 1, -2],
# [-1, -2, 1, -2]])
np.savetxt('./M.dat',Matrix)
np.loadtxt('./M.dat')
#array([[-1., 0., 0., 0.],
# [-2., 1., -2., 1.],
# [ 0., -1., 1., 0.],
# [-1., -1., 1., -2.],
# [-1., -2., 1., -2.]])
使用 numpy.save
与 numpy.load
保存和读取:
A = np.random.randint(0,150,size=(5,4))
A
np.save('./A.npy',A)
np.load('./A.npy')
#array([[ 31, 130, 100, 85],
# [134, 90, 124, 63],
# [ 66, 58, 56, 19],
# [134, 130, 44, 3],
# [ 32, 124, 100, 17]])
[[[1, 2, 3],[1, 2, 3],[1, 2, 3]],[[1, 2, 3],[1, 2, 3],[1, 2, 3]],[[1, 2, 3],[1, 2, 3],[1, 2, 3]]]
举例:
nd3 = 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],[1, 2, 3]]])
nd3.ndim
#3
nd3.shape
#(3, 3, 3)
nd3.size
#27
nd3.dtype
#dtype('int32')
ndarray.T
用于数组的转置(行列交换),与 .transpose()
相同。
举例:
nd4 = np.array([[1,2,3],[3,4,5]])
nd4
#array([[1, 2, 3],
# [3, 4, 5]])
nd4.T
#array([[1, 3],
# [2, 4],
# [3, 5]])
#任何矩阵*自己的转置矩阵都会得到一个方阵
#2*3 3*2 = 2*2
np.dot(nd4,nd4.T)
#array([[14, 26],
# [26, 50]])
coms = np.full(shape=(2,3),fill_value=1+2j)
coms
#array([[1.+2.j, 1.+2.j, 1.+2.j],
# [1.+2.j, 1.+2.j, 1.+2.j]])
ndarray.imag
用来输出数组包含元素的虚部。
imaginary number 虚数
coms.imag
#array([[2., 2., 2.],
# [2., 2., 2.]])
ndarray.real
用来输出数组包含元素的实部。
real number 实数
#imag real 主要的作用是方便做各种波变换
coms.real
#array([[1., 1., 1.],
# [1., 1., 1.]])
ndarray.itemsize
输出一个数组元素的字节数。
one = np.ones(shape=(5,4))
#一共多少个样本,一共20个样本
one
#array([[1., 1., 1., 1.],
# [1., 1., 1., 1.],
# [1., 1., 1., 1.],
# [1., 1., 1., 1.],
# [1., 1., 1., 1.]])
one.size
#20
ndarray.nbytes
用来输出数组的元素总字节数=字节数*8bit。
one.nbytes
#160 #=20*8
ndarray.strides
用来遍历数组时,输出每个维度中步进的字节元组。
#最后一个字表示的是每一个标量占用的字节数,向前一位,4*8
one.strides
#(32, 8)#32维度字节总数 8每位的字节数
一维与列表完全一致
import numpy as np
import matplotlib.pyplot as plt
sanpang = plt.imread('./jinzhengen.png')
#ndarray对比list
li_ = [1,2,3,4,[0,1,2,[2,3,4]]]
li_
#[1, 2, 3, 4, [0, 1, 2, [2, 3, 4]]]
li_[-1][-1][-1]
#4
sanpang[0][0][0]
#0.24313726
#ndarray的索引是取决于维度的,维度越多,索引的值越多
sanpang[0,0,-1]
#0.24705882
### 2.重设形状
`reshape` 可以在不改变数组数据的同时,改变数组的形状。其中,`numpy.reshape()` 等效于 `ndarray.reshape()`。`reshape`方法非常简单:
gb.shape
#(405, 259, 3)
#将三维图片变为2维图片
#改变形状的时候,样本的总个数不能少,二维的图片的是黑白,plt.imshow()方法中有额外的色素
plt.imshow(gb.reshape(405,259*3),cmap=‘gray’)
#改变形状的方法不能处理图片的灰度化
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5IGQU56E-1592462080549)(数据分析图片/重设形状1png)]
```python
#reshape仅仅只能改变数组的形状
gb.reshape(405,-1)
#array([[ 67, 48, 31, ..., 156, 174, 184],
# [ 71, 52, 35, ..., 150, 168, 178],
# [ 77, 58, 41, ..., 145, 163, 173],
# ...,
# [ 83, 64, 86, ..., 128, 91, 108],
# [ 81, 62, 84, ..., 135, 101, 117],
# [ 84, 65, 87, ..., 141, 109, 124]], dtype=uint8)
gb.reshape((405,-1)).shape
#(405, 777)
gb.reshape(405,259*3).shape
#(405, 777)
#将上述的三维数组变成一维的数组
#-1默认将所有的维度自动相乘
gb.reshape(-1)
#array([ 67, 48, 31, ..., 141, 109, 124], dtype=uint8)
ravel
的目的是将任意形状的数组扁平化,变为 1 维数组。ravel
方法如下:
不管是几维的数组都会变成1维的数据
gb.ravel()
#array([ 67, 48, 31, ..., 141, 109, 124], dtype=uint8)
np.concatenate() 级联需要注意的点:
nd1 = np.random.randint(90,100,size=(5,4))
nd1
#array([[95, 90, 91, 99],
# [91, 90, 93, 98],
# [98, 96, 93, 95],
# [98, 96, 92, 98],
# [94, 91, 96, 97]])
nd2 = np.random.randint(0,10,size=(5,3))
nd2
#array([[1, 1, 3],
# [3, 1, 3],
# [5, 6, 0],
# [7, 8, 7],
# [3, 1, 1]])
#0叫做行方向的拼接,1是列方向上的拼接
np.concatenate((nd1,nd2),axis=1)
#array([[95, 90, 91, 99, 1, 1, 3],
# [91, 90, 93, 98, 3, 1, 3],
# [98, 96, 93, 95, 5, 6, 0],
# [98, 96, 92, 98, 7, 8, 7],
# [94, 91, 96, 97, 3, 1, 1]])
nd1 = np.random.randint(90,100,size=(5,4))
nd1
#array([[95, 90, 91, 99],
# [91, 90, 93, 98],
# [98, 96, 93, 95],
# [98, 96, 92, 98],
# [94, 91, 96, 97]])
nd3 = np.random.randint(30,40,size=(4,4))
nd3
#array([[32, 34, 35, 38],
# [38, 37, 39, 39],
# [30, 34, 33, 35],
# [36, 39, 32, 35]])
np.concatenate((nd3,nd1),axis=0)
#array([[32, 34, 35, 38],
# [38, 37, 39, 39],
# [30, 34, 33, 35],
# [36, 39, 32, 35],
# [95, 90, 91, 99],
# [91, 90, 93, 98],
# [98, 96, 93, 95],
# [98, 96, 92, 98],
# [94, 91, 96, 97]])
重点:图片切割为行高或者列宽相等、和图片格式的转换
sanpang = plt.imread('./jinzhengen.png')
sanpang.shape
#(273, 411, 3)
dog = plt.imread('./dog.jpg')
dog.shape
#(300, 313, 3)
#将jpg格式图片转换为png格式
dog = dog/255
dog_ = dog.copy()
#切为y轴方向点数相同:dog_[:273]
people_dog=np.concatenate((dog_[:273],sanpang),axis=1)
plt.imshow(people_dog)
图片格式转换:
#png转为jpg格式,指定数据类型
sanpang = plt.imread('./jinzhengen.png')
jpg_image=(sanpang*255).astype(np.uint8)
#将jpg格式图片转换为png格式
dog = plt.imread('./dog.jpg')
png_image = dog/255
numpy.hstack()水平|numpy.vstack()垂直
分别代表水平级联与垂直级联,填入的参数必须被小括号或中括号包裹
vertical垂直的:
horizontal水平的
stack层积
这两个函数的值也是一个list或tuple
plt.imshow(np.hstack((dog_[:273],sanpang)))
numpy.split(array,[index1,index2,…],axis)
axis
默认值为0,表示垂直轴,如果值为1,表示水平的轴
注意:indices_or_sections ->[100,200]列表中有两个值,第一个值代表0:100,第二个值代表100:200,后面还有一个值200: 会产生三个值,三个值需要三个变量来接受。
例题:将人垂直切成3份
sanpang = plt.imread('./jinzhengen.png')
#序列 list tuple
#当axis=1时候将是水平分割
k1,k2,k3,k4 = np.split(sanpang,[50,100,200],axis=0)
#jupyter 默认只打印最低端的变量
plt.imshow(k1)
plt.show()
plt.imshow(k2)
plt.show()
plt.imshow(k3)
plt.show()
plt.imshow(k4)
所有赋值运算不会为ndarray的任何元素创建副本。对赋值后的对象的操作也对原来的对象生效。
可使用ndarray.copy()函数创建副本(对象.copy())
fish_ = plt.imread('fish.png')
fish_Backup = fish_.copy()
#副本的作用是在开发的时候,对不了解的数据结构做一个备份,防止在后续的处理中操作失误
for i in range(10):
fish_Backup[i]=0
plt.imshow(fish_Backup)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tfLVNjRX-1592462080554)(数据分析图片/覆盖png)]
plt.imshow(fish_)
ndarray.sum(axis)
,axis不写则为所有的元素求和,为0表示行求和,1表示列求和
nd4 = np.ones(shape=(5,4))
nd4
#array([[1., 1., 1., 1.],
# [1., 1., 1., 1.],
# [1., 1., 1., 1.],
# [1., 1., 1., 1.],
# [1., 1., 1., 1.]])
nd4.sum(axis=0)#==nd4.sum(axis=-2)
#array([5., 5., 5., 5.])
np.sum(nd4,axis=1)#==np.sum(nd4,axis=-1)
#array([4., 4., 4., 4., 4.])
nd5 = np.ones(shape=(5,4,3))
nd5
#array([[[1., 1., 1.],
# [1., 1., 1.],
# [1., 1., 1.],
# [1., 1., 1.]],
#
# [[1., 1., 1.],
# [1., 1., 1.],
# [1., 1., 1.],
# [1., 1., 1.]],
#
# [[1., 1., 1.],
# [1., 1., 1.],
# [1., 1., 1.],
# [1., 1., 1.]],
#
# [[1., 1., 1.],
# [1., 1., 1.],
# [1., 1., 1.],
# [1., 1., 1.]],
#
# [[1., 1., 1.],
# [1., 1., 1.],
# [1., 1., 1.],
# [1., 1., 1.]]])
nd5.sum(axis=-1)
#array([[3., 3., 3., 3.],
# [3., 3., 3., 3.],
# [3., 3., 3., 3.],
# [3., 3., 3., 3.],
# [3., 3., 3., 3.]])
求4维矩阵中最后两维的和
nd6 = np.ones(shape=(6,5,4,3))
nd6
nd6.sum(-1).sum(-1)#==nd6.sum((-1,-2))
#array([[12., 12., 12., 12., 12.],
# [12., 12., 12., 12., 12.],
# [12., 12., 12., 12., 12.],
# [12., 12., 12., 12., 12.],
# [12., 12., 12., 12., 12.],
# [12., 12., 12., 12., 12.]])
nd7 = np.random.randint(0,100,size=(5,4))
nd7
#array([[93, 79, 65, 70],
# [96, 35, 92, 85],
# [25, 86, 78, 85],
# [25, 55, 18, 28],
# [12, 33, 54, 4]])
nd7.max()
#96
nd7.min()
#4
nd7.max(axis=0)#各列的最大值
#array([96, 86, 92, 85])
nd7.min(axis=1)#各行的最小值
#array([65, 35, 25, 18, 4])
nd7 = np.random.randint(0,100,size=(5,4))
nd7
#array([[93, 79, 65, 70],
# [96, 35, 92, 85],
# [25, 86, 78, 85],
# [25, 55, 18, 28],
# [12, 33, 54, 4]])
nd7.mean()
#55.9
nd7.mean(axis=0)#各列的平均值
#array([50.2, 57.6, 61.4, 54.4])
nd7.mean(axis=1)#各行的平均值
#array([76.75, 77. , 68.5 , 31.5 , 25.75])
Function Name NaN-safe Version Description
np.sum np.nansum Compute sum of elements
np.prod np.nanprod Compute product of elements
np.mean np.nanmean Compute mean of elements
np.std np.nanstd Compute standard deviation
np.var np.nanvar Compute variance
np.min np.nanmin Find minimum value
np.max np.nanmax Find maximum value
np.argmin np.nanargmin Find index of minimum value 找到最小数的下标
np.argmax np.nanargmax Find index of maximum value 找到最大数的下标
np.median np.nanmedian Compute median of elements
np.percentile np.nanpercentile Compute rank-based statistics of elements
np.any N/A Evaluate whether any elements are true
np.all N/A Evaluate whether all elements are true
np.power 幂运算
np.argwhere(nd1<0)
NaN举例:
n = np.array([[1,2,3],[np.NaN,2,3]])
n
#array([[ 1., 2., 3.],
# [nan, 2., 3.]])
#任何数值+NaN返回的都是NaN
n.sum()
#nan
#带有nan的函数都会将nan视为0
np.nansum(n)
11.0
返回的是最大值的下标,在使用argmax的时候最好把数组展开
nd9 = np.random.randint(0,150,size=(10,8))
nd9
# array([[128, 129, 12, 55, 148, 145, 127, 89],
# [ 46, 110, 48, 114, 30, 2, 7, 139],
# [ 4, 140, 134, 127, 121, 143, 145, 30],
# [129, 15, 95, 26, 59, 123, 68, 95],
# [ 47, 64, 15, 144, 36, 75, 110, 21],
# [ 29, 98, 93, 71, 108, 131, 60, 120],
# [ 83, 34, 108, 56, 144, 16, 19, 86],
# [141, 88, 4, 94, 132, 80, 96, 2],
# [105, 26, 69, 82, 110, 14, 131, 97],
# [ 89, 85, 115, 94, 55, 90, 4, 54]])
nd9.ravel()#将为一维列表
# array([128, 129, 12, 55, 148, 145, 127, 89, 46, 110, 48, 114, 30,
# 2, 7, 139, 4, 140, 134, 127, 121, 143, 145, 30, 129, 15,
# 95, 26, 59, 123, 68, 95, 47, 64, 15, 144, 36, 75, 110,
# 21, 29, 98, 93, 71, 108, 131, 60, 120, 83, 34, 108, 56,
# 144, 16, 19, 86, 141, 88, 4, 94, 132, 80, 96, 2, 105,
# 26, 69, 82, 110, 14, 131, 97, 89, 85, 115, 94, 55, 90,
# 4, 54])
#找到最大值的下标,argmax在查找最大值的时候,会默认将数组扁平化
nd9.ravel()[[np.argmax(nd9.ravel())]]
#array([148])
#能不写变量的地方尽量不谢,因为变量一旦定义,就需要消耗内存空间,垃圾回收需要多处理一些垃圾变量
#小于100的值
nd9.ravel()[np.argwhere(nd9.ravel()<100).ravel()]
moveaxis
可以将数组的轴移动到新的位置。其方法如下:
numpy.moveaxis(a, source, destination)
其中:
a
:数组。source
:要移动的轴的原始位置。destination
:要移动的轴的目标位置。举例:
nd10 = np.random.randint(0,10,size=(5,4))
nd10
# array([[0, 6, 3, 7],
# [5, 6, 5, 8],
# [0, 2, 5, 1],
# [0, 8, 9, 1],
# [9, 5, 0, 7]])
#转置
nd10.T
# array([[0, 6, 3, 7],
# [5, 6, 5, 8],
# [0, 2, 5, 1],
# [0, 8, 9, 1],
# [9, 5, 0, 7]])
nd11 = np.random.randint(0,10,size=(3,3,3))
nd11
# array([[[7, 1, 2],
# [3, 7, 7],
# [3, 1, 5]],
# [[0, 0, 4],
# [0, 8, 7],
# [9, 4, 7]],
# [[0, 2, 8],
# [2, 3, 9],
# [5, 2, 3]]])
nd11.T
# array([[[7, 0, 0],
# [3, 0, 2],
# [3, 9, 5]],
# [[1, 0, 2],
# [7, 8, 3],
# [1, 4, 2]],
# [[2, 4, 8],
# [7, 7, 9],
# [5, 7, 3]]])
np.moveaxis(np.moveaxis(nd11,0,-1),0,1)
# array([[[7, 0, 0],
# [3, 0, 2],
# [3, 9, 5]],
# [[1, 0, 2],
# [7, 8, 3],
# [1, 4, 2]],
# [[2, 4, 8],
# [7, 7, 9],
# [5, 7, 3]]])
和 moveaxis
不同的是,swapaxes
可以用来交换数组的轴。其方法如下:
numpy.swapaxes(a, axis1, axis2)
其中:
a
:数组。axis1
:需要交换的轴 1 位置。axis2
:需要与轴 1 交换位置的轴 1 位置。nd11 = np.random.randint(0,10,size=(3,3,3))
nd11
# array([[[7, 1, 2],
# [3, 7, 7],
# [3, 1, 5]],
# [[0, 0, 4],
# [0, 8, 7],
# [9, 4, 7]],
# [[0, 2, 8],
# [2, 3, 9],
# [5, 2, 3]]])
nd11.T
#array([[[7, 0, 0],
# [3, 0, 2],
# [3, 9, 5]],
# [[1, 0, 2],
# [7, 8, 3],
# [1, 4, 2]],
# [[2, 4, 8],
# [7, 7, 9],
# [5, 7, 3]]])
np.swapaxes(nd11,0,-1)
#array([[[7, 0, 0],
# [3, 0, 2],
# [3, 9, 5]],
# [[1, 0, 2],
# [7, 8, 3],
# [1, 4, 2]],
# [[2, 4, 8],
# [7, 7, 9],
# [5, 7, 3]]])
transpose
类似于矩阵的转置,它可以将 2 维数组的水平轴和垂直交换。其方法如下:
numpy.transpose(a, axes=None)
其中:
a
:数组。axis
:该值默认为 none
,表示转置。如果有值,那么则按照值替换轴。nd11.transpose()
#array([[[7, 0, 0],
# [3, 0, 2],
# [3, 9, 5]],
# [[1, 0, 2],
# [7, 8, 3],
# [1, 4, 2]],
# [[2, 4, 8],
# [7, 7, 9],
# [5, 7, 3]]])
数组元素的循环tile
与 repeat
nd13 = np.random.randint(0,10,3)
nd13
#array([6, 6, 8])
np.tile(nd13,5)
#array([6, 6, 8, 6, 6, 8, 6, 6, 8, 6, 6, 8, 6, 6, 8])
np.repeat(nd13,6)
#array([6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 8, 8, 8, 8])
nd14 = np.random.randint(0,10,(5,4))
nd14
# array([[8, 0, 9, 3],
# [6, 0, 5, 0],
# [5, 2, 7, 6],
# [6, 5, 0, 9],
# [6, 0, 9, 2]])
np.repeat(nd14,3,axis=1)
#array([[8, 8, 8, 0, 0, 0, 9, 9, 9, 3, 3, 3],
# [6, 6, 6, 0, 0, 0, 5, 5, 5, 0, 0, 0],
# [5, 5, 5, 2, 2, 2, 7, 7, 7, 6, 6, 6],
# [6, 6, 6, 5, 5, 5, 0, 0, 0, 9, 9, 9],
# [6, 6, 6, 0, 0, 0, 9, 9, 9, 2, 2, 2]])
(1) 算术运算符(加减乘除):
nd15 = np.random.randint(10,100,size=(5,4))
nd16 = np.random.randint(1,10,size=(5,4))
display(nd15,nd16)
# array([[11, 75, 42, 82],
# [24, 75, 26, 87],
# [21, 36, 14, 88],
# [90, 68, 37, 28],
# [77, 25, 37, 95]])
# array([[3, 5, 1, 7],
# [3, 1, 8, 7],
# [9, 7, 4, 3],
# [2, 7, 4, 4],
# [1, 8, 5, 6]])
nd15 + nd16
# array([[ 14, 80, 43, 89],
# [ 27, 76, 34, 94],
# [ 30, 43, 18, 91],
# [ 92, 75, 41, 32],
# [ 78, 33, 42, 101]])
nd15 - nd16
#array([[ 8, 70, 41, 75],
# [21, 74, 18, 80],
# [12, 29, 10, 85],
# [88, 61, 33, 24],
# [76, 17, 32, 89]])
nd15 * nd16
# array([[ 33, 375, 42, 574],
# [ 72, 75, 208, 609],
# [189, 252, 56, 264],
# [180, 476, 148, 112],
# [ 77, 200, 185, 570]])
nd15 / nd16
#array([[ 3.66666667, 15. , 42. , 11.71428571],
# [ 8. , 75. , 3.25 , 12.42857143],
# [ 2.33333333, 5.14285714, 3.5 , 29.33333333],
# [45. , 9.71428571, 9.25 , 7. ],
# [77. , 3.125 , 7.4 , 15.83333333]])
不对原来的数组产生影响
np.add(nd15,nd16)
# array([[ 14, 80, 43, 89],
# [ 27, 76, 34, 94],
# [ 30, 43, 18, 91],
# [ 92, 75, 41, 32],
# [ 78, 33, 42, 101]])
不对原来的结果产生影响,同位相乘
np.multiply(nd15,nd16)
# array([[ 33, 375, 42, 574],
# [ 72, 75, 208, 609],
# [189, 252, 56, 264],
# [180, 476, 148, 112],
# [ 77, 200, 185, 570]])
nd15 = np.random.randint(10,100,size=(5,4))
nd16 = np.random.randint(1,10,size=(5,4))
display(nd15,nd16)
# array([[94, 10, 71, 39],
# [79, 72, 77, 38],
# [51, 46, 87, 22],
# [41, 29, 47, 46],
# [19, 26, 43, 80]])
# array([[7, 5, 1, 2],
# [1, 4, 3, 5],
# [2, 8, 9, 2],
# [7, 3, 1, 4],
# [8, 3, 1, 6]])
np.dot(nd15,nd16.T)
# array([[ 857, 542, 985, 915, 1087],
# [1066, 788, 1503, 998, 1153],
# [ 718, 606, 1297, 670, 765],
# [ 571, 528, 829, 605, 738],
# [ 466, 652, 793, 574, 753]])
三维乘以一维:np.dot(nd17,nd18) 降维 二维
三维乘以二维:np.dot(nd17,nd19) 还是三维
【重要】ndarray广播机制的两条规则
规则一:为缺失的维度补1
规则二:假定缺失元素用已有值填充
例1: m = np.ones((2, 3)) a = np.arange(3) 求M+a
#nd18=array([0, 3, 1])
nd18+3
#array([3, 6, 4])
m = np.ones((2, 3))
a = np.arange(3)
display(m,a)
#array([[1., 1., 1.],
# [1., 1., 1.]])
#array([0, 1, 2])
a+m
#array([[1., 2., 3.],
# [1., 2., 3.]])
小测验: 使用以上所学numpy的知识,对一个ndarray对象进行选择排序。
代码越短越好
array([9, 4, 5, 7, 6, 0, 0, 3, 0, 2])
num = 0
for i in range(res.size-1):
for j in range(res.size-i-1):
if res[j] > res[j+1]:
res[j],res[j+1] = res[j+1],res[j]
num+=1
res
#array([0, 0, 0, 2, 3, 4, 5, 6, 7, 9])
array([8, 6, 3, 1, 5, 5, 1, 2, 4, 8])
#一个循环搞定排序 argmin argmax
def sort_nd(nd):
for i in range(nd.size):
min_index = nd[i:].argmin()+ i
nd[i],nd[min_index] = nd[min_index],nd[i]
sort_nd(result)
result
#array([1, 1, 2, 3, 4, 5, 5, 6, 8, 8])
np.sort()与ndarray.sort()都可以,但有区别:
np.sort(a, axis=-1, kind='quicksort', order=None)
#kind : {'quicksort', 'mergesort', 'heapsort'}, optional
Sorting algorithm. Default is 'quicksort'.
res_ = np.random.randint(0,10,size=10)
res_
#array([3, 3, 0, 3, 5, 4, 0, 2, 7, 2])
np.sort(res_)[::-1]
#array([7, 5, 4, 3, 3, 3, 2, 2, 0, 0])
python np.partition(a,k)
有的时候我们不是对全部数据感兴趣,我们可能只对最小或最大的一部分感兴趣。
res_1 = np.random.randint(0,10000,size=100)
res_1
# array([1709, 2665, 3007, 3526, 3646, 864, 9796, 148, 8290, 505, 9249,
# 6741, 8795, 7064, 5812, 5241, 9618, 3818, 6721, 1333, 7715, 2093,
# 4247, 8537, 1161, 6773, 2475, 6879, 4275, 9834, 1403, 4711, 9187,
# 9607, 7247, 797, 8479, 149, 8054, 445, 3059, 6399, 9792, 1711,
# 4836, 4363, 7772, 7030, 1791, 6757, 2366, 5251, 6828, 5969, 7670,
# 1450, 5393, 6859, 3347, 2385, 3326, 2409, 2554, 8362, 1114, 5436,
# 399, 4108, 5116, 4582, 2345, 3580, 5788, 3676, 7640, 7906, 644,
# 62, 1050, 7893, 7372, 8485, 5739, 9402, 6608, 6070, 8869, 6203,
# 1471, 7006, 7344, 1466, 1788, 5421, 6811, 7126, 3724, 9810, 510,
# 2374])
np.partition(res_1,-5)
# #array([ 148, 62, 149, 399, 445, 505, 510, 644, 797, 864, 1050,
# 1114, 1161, 1333, 1403, 1450, 1466, 1471, 1709, 1711, 1788, 1791,
# 2093, 2345, 2366, 2374, 2385, 2409, 2475, 2554, 2665, 3007, 3059,
# 3326, 3347, 3526, 3580, 3646, 3676, 3724, 3818, 4108, 4247, 4275,
# 4363, 4582, 4711, 4836, 5116, 5241, 5393, 5251, 5421, 5436, 5739,
# 5788, 5812, 5969, 6070, 6203, 6399, 6608, 6721, 6741, 6757, 6773,
# 6811, 6828, 6859, 6879, 7006, 7030, 7064, 7126, 7247, 7372, 7344,
# 7640, 7670, 7715, 7772, 7893, 7906, 8054, 8290, 8362, 8479, 8485,
# 8795, 8537, 8869, 9187, 9249, 9402, 9607, 9618, 9792, 9796, 9810,
# 9834])
np.partition(res_1,4)
# array([ 148, 62, 149, 399, 445, 505, 510, 644, 797, 864, 1050,
# 1114, 1161, 1333, 1403, 1450, 1466, 1471, 1709, 1711, 1788, 1791,
# 2093, 2345, 2366, 2374, 2385, 2409, 2475, 2554, 2665, 3007, 3059,
# 3326, 3347, 3526, 3580, 3646, 3676, 3724, 3818, 4108, 4247, 4275,
# 4363, 4582, 4711, 4836, 5116, 5241, 5251, 5393, 5421, 5436, 5739,
# 5788, 5812, 5969, 6070, 6203, 6399, 6608, 6721, 6741, 6757, 6773,
# 6811, 6828, 6859, 6879, 7006, 7030, 7064, 7126, 7247, 7344, 7372,
# 7640, 7670, 7715, 7772, 7893, 7906, 8054, 8290, 8362, 8479, 8485,
# 8537, 8795, 8869, 9187, 9249, 9402, 9607, 9618, 9792, 9796, 9810,
# 9834])
np.sort(res_1)[::-1][:5]
array([9834, 9810, 9796, 9792, 9618])
#opencv open 开源的 computer 计算机 vision视觉
import cv2
import matplotlib.pyplot as plt
#plt读取图片是rgb、cv2读取图片是bgr
sanpang=cv2.imread('./jinzhengen.png')
plt.imshow(sanpang[:,:,::-1])
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sDb0gPyg-1592462080560)(数据分析图片/jinzhengenpng)]
#xml中封装一个算法
#CascadeClassifier分类器返回的是一个算法的shili对象
fact_det=cv2.CascadeClassifier('./haarcascade_frontalface_default.xml')
#返回的是一个ndarray,第一个值表示的x轴的起始值,第二个表示y轴的起始值,第三、第四分表表示其偏移量
fact_det.detectMultiScale(sanpang)
#array([[182, 62, 61, 61]], dtype=int32)
plt.imshow(sanpang[62:62+61,182:182+61][:,:,::-1])
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VWstuSFm-1592462080561)(数据分析图片/人脸识别png)]
import os, math
from PIL import Image
g=Image.open('./guobin.jpg')
#返回一个元祖 第一个值x表示宽度 第二个值Y表示高度
g.size
def circle(ima):
#读取图片 convert转换 rgb rgba alpha透明度
#ima = Image.open("test.jpg").convert("RGBA")
#获取图片的尺寸
size = ima.size
# 因为是要圆形,所以需要正方形的图片 r2表示直径
r2 = min(size[0], size[1])
if size[0] != size[1]:
ima = ima.resize((r2, r2), Image.ANTIALIAS)
#创建一个画布
imb = Image.new('RGBA', (r2, r2),(255,255,255,0))
#读取图片数据
pima = ima.load()
#读取画布数据
pimb = imb.load()
r = float(r2/2) #圆心横坐标
for i in range(r2):
for j in range(r2):
lx = abs(i-r+0.5) #到圆心距离的横坐标
ly = abs(j-r+0.5)#到圆心距离的纵坐标
l = pow(lx,2) + pow(ly,2)
if l <= pow(r, 2):
pimb[i,j] = pima[i,j]
imb.save("test_circle.png")
plt.imshow(imb)
circle(g)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eNsj0Lbh-1592462080562)(数据分析图片/原图圆图png)]
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from pandas import Series,DataFrame
Series是一种类似与一维数组的对象,由下面两个部分组成:
两种创建方式:
默认索引为0到N-1的整数型索引
nd1 = np.random.randint(0,10,(5,4)).ravel()
nd1
#array([0, 0, 3, 0, 6, 2, 4, 8, 1, 2, 7, 4, 9, 3, 8, 1, 9, 9, 2, 2])
通过设置index参数指定索引
#在python中str就是object,但是object不一定是str 关联型索引
#有关联型索引的同时,也可以使用枚举型索引,也可以使用面向对象的方式取值
s1=Series(list('abcd'),index=list('东南西北'))
s1['东']#s1[0]、s1.东
#'a'
s1
#东 a
#南 b
#西 c
#北 d
#dtype: object
name参数
#将当前的Series定义为数据表中的一列
s3=Series(list('abcd'),index=list('东南西北'),name='id')
s3
#东 a
#南 b
#西 c
#北 d
#dtype: object
注意:特别地,由ndarray创建的是引用,而不是副本。对Series元素的改变也会改变原来的ndarray对象中的元素。(列表没有这种情况)
d = {'a':1,'b':2,'c':3,'d':4}
Series(d)#强制转换
# a 1
# b 2
# c 3
# d 4
# dtype: int64
可以使用中括号取单个索引(此时返回的是元素类型),或者中括号里一个列表取多个索引(此时返回的仍然是一个Series类型)。分为显示索引和隐式索引:
- 使用index中的元素作为索引值
- 使用.loc[](推荐)
可以理解为pandas是ndarray的升级版,但是Series也可是dict的升级版
注意,此时是闭区间。
s3=Series(list('abcd'),index=list('东南西北'))
s3
#东 a
#南 b
#西 c
#北 d
#dtype: object
s3[0:2]#左开右闭
#东 a
#南 b
#Name: id, dtype: object
s3['东':'西']#闭区间
# 东 a
# 南 b
# 西 c
# Name: id, dtype: object
#如果索引类型是一个列表,那么可以同时取多个值
s3[['东','东','南']]
# 东 a
# 东 a
# 南 b
# Name: id, dtype: object
s3.loc['东']#s3['东']、s3[0]、s3.loc[0]
#'a'
**补充查询:**查询小于50的数下标以及数值
nd1= np.random.randint(0,100,100)
cond = np.argwhere(nd1<50).ravel()#返回符合条件数据下标
nd1[cond]
- 使用整数作为索引值
- 使用.iloc[](推荐)
iloc[ ] 只能使用枚举型([数字:数字])的索引。
s3.iloc[0]
#'a'
s3.iloc[0:4] #左闭右开
# 东 a
# 南 b
# 西 c
# 北 d
# Name: id, dtype: object
s3.loc['南':'北'] #全闭
# 南 b
# 西 c
# 北 d
# Name: id, dtype: object
可以把Series看成一个定长的有序字典
可以通过shape,ndim,size,index,values等得到series的属性。
s3=Series(list('abcd'),index=list('东南西北'))
s3.dtypes
#dtype('O')
s3.size
#4
s3.index
#Index(['东', '南', '西', '北'], dtype='object')
s3.values
#array(['a', 'b', 'c', 'd'], dtype=object)
s3.keys()
#Index(['东', '南', '西', '北'], dtype='object')
可以通过head(),tail()快速查看Series对象的样式
共同都有一个参数n,默认值为5
Series.head() DataFrame.tail()
#使用pandas读取CSV文件
k50 = pd.read_csv('./500_Cities__Local_Data_for_Better_Health.csv')
默认查看前五条数据,索引从零开始。
k50.head()
# Year StateAbbr StateDesc CityName GeographicLevel DataSource Category UniqueID Measure Data_Value_Unit ... High_Confidence_Limit Data_Value_Footnote_Symbol Data_Value_Footnote PopulationCount GeoLocation CategoryID MeasureId CityFIPS TractFIPS Short_Question_Text
#0 2014 US United States NaN US BRFSS Prevention 59 Current lack of health insurance among adults ... % ... 15.2 NaN NaN 308745538.0 NaN PREVENT ACCESS2 NaN NaN Health Insurance
#1 2014 US United States NaN US BRFSS Prevention 59 Current lack of health insurance among adults ... % ... 14.3 NaN NaN 308745538.0 NaN PREVENT ACCESS2 NaN NaN Health Insurance
#2 2014 US United States NaN US BRFSS Health Outcomes 59 Arthritis among adults aged >=18 Years % ... 23.7 NaN NaN 308745538.0 NaN HLTHOUT ARTHRITIS NaN NaN Arthritis
#3 2014 US United States NaN US BRFSS Health Outcomes 59 Arthritis among adults aged >=18 Years % ... 25.9 NaN NaN 308745538.0 NaN HLTHOUT ARTHRITIS NaN NaN Arthritis
#4 2014 US United States NaN US BRFSS Unhealthy Behaviors 59 Binge drinking among adults aged >=18 Years % ... 17.1 NaN NaN 308745538.0 NaN UNHBEH BINGE NaN NaN Binge Drinking
#5 rows × 24 columns
k50.head(n=1)#查看第一条数据
# Year StateAbbr StateDesc CityName GeographicLevel DataSource Category UniqueID Measure Data_Value_Unit ... High_Confidence_Limit Data_Value_Footnote_Symbol Data_Value_Footnote PopulationCount GeoLocation CategoryID MeasureId CityFIPS TractFIPS Short_Question_Text
#0 2014 US United States NaN US BRFSS Prevention 59 Current lack of health insurance among adults ... % ... 15.2 NaN NaN 308745538.0 NaN PREVENT ACCESS2 NaN NaN Health Insurance
#1 rows × 24 columns
默认查看最后五条数据,索引从-1开始。
k50.tail()
# Year StateAbbr StateDesc CityName GeographicLevel DataSource Category UniqueID Measure Data_Value_Unit ... High_Confidence_Limit Data_Value_Footnote_Symbol Data_Value_Footnote PopulationCount GeoLocation CategoryID MeasureId CityFIPS TractFIPS Short_Question_Text
# 810098 2014 WY Wyoming Cheyenne Census Tract BRFSS Health Outcomes 5613900-56021001401 All teeth lost among adults aged >=65 Years % ... 19.8 NaN NaN 3961.0 (41.1585056144, -104.777631834) HLTHOUT TEETHLOST 5613900.0 5.602100e+10 Teeth Loss
# 810099 2014 WY Wyoming Cheyenne Census Tract BRFSS Health Outcomes 5613900-56021001402 All teeth lost among adults aged >=65 Years % ... 27.8 NaN NaN 1913.0 (41.1717764805, -104.788212134) HLTHOUT TEETHLOST 5613900.0 5.602100e+10 Teeth Loss
# 810100 2014 WY Wyoming Cheyenne Census Tract BRFSS Health Outcomes 5613900-56021001501 All teeth lost among adults aged >=65 Years % ... 19.7 NaN NaN 3312.0 (41.1603741708, -104.756560525) HLTHOUT TEETHLOST 5613900.0 5.602100e+10 Teeth Loss
# 810101 2014 WY Wyoming Cheyenne Census Tract BRFSS Health Outcomes 5613900-56021001502 All teeth lost among adults aged >=65 Years % ... 27.7 NaN NaN 4518.0 (41.1506339283, -104.755675636) HLTHOUT TEETHLOST 5613900.0 5.602100e+10 Teeth Loss
# 810102 2014 WY Wyoming Cheyenne Census Tract BRFSS Health Outcomes 5613900-56021002000 All teeth lost among adults aged >=65 Years % ... 23.9 NaN NaN 214.0 (41.1336167952, -104.719053785) HLTHOUT TEETHLOST 5613900.0 5.602100e+10 Teeth Loss
# 5 rows × 24 columns
k50.tail(n=1)#查看最后一条数据
# Year StateAbbr StateDesc CityName GeographicLevel DataSource Category UniqueID Measure Data_Value_Unit ... High_Confidence_Limit Data_Value_Footnote_Symbol Data_Value_Footnote PopulationCount GeoLocation CategoryID MeasureId CityFIPS TractFIPS Short_Question_Text
#810102 2014 WY Wyoming Cheyenne Census Tract BRFSS Health Outcomes 5613900-56021002000 All teeth lost among adults aged >=65 Years % ... 23.9 NaN NaN 214.0 (41.1336167952, -104.719053785) HLTHOUT TEETHLOST 5613900.0 5.602100e+10 Teeth Loss
#1 rows × 24 columns
当索引没有对应的值时,可能出现缺失数据显示NaN(not a number)的情况,可以使用pd.isnull(),pd.notnull(),或自带isnull(),notnull()函数检测缺失数据
#NaN可以认为是MySql中的Null not null default
#在数据分析当中NaN也是一个不被需要的特殊数据类型
#numpy当中的NaN是float类型,当None碰到除数值类型以为的对象的时候,None不会转变成NaN
dict_ = {'a':1,'b':2,'c':None,'d':np.NaN}
s4 = Series(dict_)
c = pd.isnull(s4)
c
# a False
# b False
# c True
# d True
# dtype: bool
#numpy类型序列,支持bool型,并且只返回为True的数据部分
s4[c]
# c NaN
# d NaN
# dtype: float64
c1 = pd.notnull(s4)
c1
# a True
# b True
# c False
# d False
# dtype: bool
s4[c1]
#a 1.0
#b 2.0
#dtype: float64
s5 = Series([1,2,3,43,57])
s5
#0 1
#1 2
#2 3
#3 43
#4 57
#dtype: int64
#广播机制
s5 * 0
# 0 0
# 1 0
# 2 0
# 3 0
# 4 0
# dtype: int64
s6 = Series([6,5,4,3])
s6
#s5 有5个值 s6 4个值 把位数短缺的用NaN来填补(加法类似)
s5*s6
# 0 6.0
# 1 10.0
# 2 12.0
# 3 129.0
# 4 NaN
# dtype: float64
nansum()
s5 = Series([1,2,3,43,57])
np.nansum(s5)
#106
add()
s5.add(s6)
# 0 7.0
# 1 7.0
# 2 7.0
# 3 46.0
# 4 NaN
# dtype: float64
DataFrame是一个【表格型】的数据结构,可以看做是【由Series组成的数据集】(共用同一个行索引)。DataFrame由按一定顺序排列的多列数据组成。设计初衷是将Series的使用场景从一维拓展到多维。DataFrame既有行索引,也有列索引。
我们的 训练集(一些二维的数据)都是二维的,那么Series满足不了这个条件,xy轴,轴上的一点(0,0)
df = DataFrame(data={ '数学':list(range(100,105)),
'语文':list(range(110,115)),
'python':list(range(80,85))},
index=['马云','刘强东','马化腾','雷布斯','罗太君'],
columns=['数学','语文','python'])
df
# 数学 语文 python
# 马云 100 110 80
# 刘强东 101 111 81
# 马化腾 102 112 82
# 雷布斯 103 113 83
# 罗太君 104 114 84
最常用的方法是传递一个字典来创建。DataFrame以字典的键作为每一【列】的名称,以字典的值(一个数组)作为每一列。
此外,DataFrame会自动加上每一行的索引(和Series一样)。
同Series一样,若传入的列与字典的键不匹配,则相应的值为NaN。
#如果数据是字典类型,那么columns只有一个排序的作用,给列排序
#列的数量可以不一致,但是行的数量必须与原数据一致,不可以增加,也不可以减少
df1 = DataFrame(data={'数学':list(range(100,105)),
'语文':list(range(110,115)),
'python':list(range(80,85))},
index=['马云','刘强东','马化腾','雷布斯','罗太君'],
columns=['python','数学','语文'])
df1
# python 数学 语文
# 马云 80 100 110
# 刘强东 81 101 111
# 马化腾 82 102 112
# 雷布斯 83 103 113
# 罗太君 84 104 114
values、columns、index、shape、ndim、dtypes
df1.values
# array([[ 80, 100, 110],
# [ 81, 101, 111],
# [ 82, 102, 112],
# [ 83, 103, 113],
# [ 84, 104, 114]], dtype=int64)
df1.columns
#Index(['python', '数学', '语文'], dtype='object')
df1.index
#Index(['马云', '刘强东', '马化腾', '雷布斯', '罗太君'], dtype='object')
df1.shape
#(5, 3)
df1.ndim
#2
df1.dtypes
#python int64
#数学 int64
#语文 int64
#dtype: object
- 通过类似字典的方式
- 通过属性的方式
可以将DataFrame的列获取为一个Series。返回的Series拥有原DataFrame相同的索引,且name属性也已经设置好了,就是相应的列名。
df1[['python','语文']]
# python 语文
# 马云 80 110
# 刘强东 81 111
# 马化腾 82 112
# 雷布斯 83 113
# 罗太君 84 114
df1.T['马云']
# python 80
# 数学 100
# 语文 110
# Name: 马云, dtype: int64
- 使用.loc[]加index来进行行索引
- 使用.iloc[]加整数来进行行索引
同样返回一个Series,index为原来的columns。
#在dataframe中 显示索引和隐式索引默认是取行的
df1.loc['罗太君'] #关联型
# python 84
# 数学 104
# 语文 114
# Name: 罗太君, dtype: int64
#使用显示索引 查找列
df1.loc[:,'python']
# 马云 80
# 刘强东 81
# 马化腾 82
# 雷布斯 83
# 罗太君 84
# Name: python, dtype: int64
#索引多行取一列
df1.loc['马云':'罗太君','python':'数学']
# python 数学
# 马云 80 100
# 刘强东 81 101
# 马化腾 82 102
# 雷布斯 83 103
# 罗太君 84 104
df1.loc['马云','python']
#列索引和行索引都必须是枚举型
df1.iloc[0,0]
#80
df1.iloc[[0,2,4],[0,-1]]
# python 语文
# 马云 80 110
# 马化腾 82 112
# 罗太君 84 114
同Series一样:
#首先DataFrame是一个二维的
#在开发当中不会用df*df
np.dot(df1,df1.T)
# array([[28500, 28790, 29080, 29370, 29660],
# [28790, 29083, 29376, 29669, 29962],
# [29080, 29376, 29672, 29968, 30264],
# [29370, 29669, 29968, 30267, 30566],
# [29660, 29962, 30264, 30566, 30868]], dtype=int64)
df1/0.1
# python 数学 语文
# 马云 800.0 1000.0 1100.0
# 刘强东 810.0 1010.0 1110.0
# 马化腾 820.0 1020.0 1120.0
# 雷布斯 830.0 1030.0 1130.0
# 罗太君 840.0 1040.0 1140.0
下面是Python 操作符与pandas操作函数的对应表:
Python Operator | Pandas Method(s) |
---|---|
+ |
add() |
- |
sub() , subtract() |
* |
mul() , multiply() |
/ |
truediv() , div() , divide() |
// |
floordiv() |
% |
mod() |
** |
pow() |
重要】
使用Python操作符:以行为单位操作(参数必须是行),对所有行都有效。(类似于numpy中二维数组与一维数组的运算,但可能出现NaN)
使用pandas操作函数:
axis=0:以列为单位操作(参数必须是列),对所有列都有效。
axis=1:以行为单位操作(参数必须是行),对所有行都有效。
类似矩阵相乘(行乘以列)。
#NaN就算是丢失的数据,最主要的是NaN的数据拖效率的后退
#在Mysql中某一列含有Null的数据,那么这一列的查询速度会变慢,NUll越多越慢
df1
# python 数学 语文
# 马云 80 100 110
# 刘强东 81 101 111
# 马化腾 82 102 112
# 雷布斯 83 103 113
# 罗太君 84 104 114
df1.dtypes
#python int64
#数学 int64
#语文 int64
#dtype: object
df1.数学.雷布斯 = np.NaN
df1
# python 数学 语文
# 马云 80 100.0 110
# 刘强东 81 101.0 111
# 马化腾 82 102.0 112
# 雷布斯 83 NaN 113
# 罗太君 84 104.0 114
df1.isnull()
# python 数学 语文
# 马云 False False False
# 刘强东 False False False
# 马化腾 False False False
# 雷布斯 False True False
# 罗太君 False False False
df1.notnull()
# python 数学 语文
# 马云 True True True
# 刘强东 True True True
# 马化腾 True True True
# 雷布斯 True False True
# 罗太君 True True True
dropna():过滤NAN
#在开发中,如果有数据空缺,我们应当是删除行还是列?
#删除行 只有一行数据受影响了,删除列 影响了每一条数据
df1.dropna(axis=0)
# python 数学 语文
# 马云 80 100.0 110
# 刘强东 81 101.0 111
# 马化腾 82 102.0 112
# 罗太君 84 104.0 114
fillna() :填充数据
df1.fillna(value=0)
# python 数学 语文
# 马云 80 100.0 110
# 刘强东 81 101.0 111
# 马化腾 82 102.0 112
# 雷布斯 83 0.0 113
# 罗太君 84 104.0 114df1.fillna(value=0)
最常见的方法是给DataFrame构造函数的index参数传递两个或更多的数组
s = Series(data=np.random.randint(0,100,6),index=[['a','a','b','b','c','c'],['期中','期末','期中','期末','期中','期末']])
s
# a 期中 52
# 期末 28
# b 期中 27
# 期末 79
# c 期中 86
# 期末 0
# dtype: int32
s['a','期中']
#52
#4*6
df = DataFrame(np.random.randint(0,100,(4,6)),
list('东南西北'),
['python','python','ruby','ruby','golang','golang'],
['期中','期末','期中','期末','期中','期末'],
['甲','乙','丙','丁','戊','己']]
)
df
# python ruby golang
# 期中 期末 期中 期末 期中 期末
# 甲 乙 丙 丁 戊 己
# 东 51 43 89 8 20 89
# 南 42 10 35 54 30 47
# 西 1 40 17 98 80 19
# 北 3 21 61 49 78 36
df['python','期中','甲']
#东 51
#南 42
#西 1
#北 3
#Name: (python, 期中, 甲), dtype: int32
#使用隐式索引取下标,取的是最内层索引的下标值
#关联性索引只能一层一层去取(显示索引)
df.iloc[:,2]
#东 89
#南 35
#西 17
#北 61
#Name: (ruby, 期中, 丙), dtype: int32
pd.MultiIndex
使用来创建DataFrame的多层索引
df1 = DataFrame(np.random.randint(0,150,(4,6)),
list('甲乙丙丁'),
pd.MultiIndex.from_arrays([['python','python','ruby','ruby','golang','golang'],['期中','期末','期中','期末','期中','期末']]))
df1
# python ruby golang
# 期中 期末 期中 期末 期中 期末
# 甲 57 8 133 78 139 146
# 乙 93 130 119 90 4 57
# 丙 84 56 135 42 136 109
# 丁 57 92 44 126 10 13
df2 = DataFrame(np.random.randint(0,150,(4,6)),
list('甲乙丙丁'),
pd.MultiIndex.from_tuples([('python','期中'),('python','期末'),
('ruby','期中'),('ruby','期末'),
('golang','期中'),('golang','期末')]))
df2
# python ruby golang
# 期中 期末 期中 期末 期中 期末
# 甲 121 110 70 115 51 129
# 乙 13 70 10 136 85 92
# 丙 23 14 19 64 125 88
# 丁 12 1 130 11 12 57
df3 = DataFrame(np.random.randint(0,150,(4,6)),
list('甲乙丙丁'),
pd.MultiIndex.from_product([['python','ruby','golang'],['期中','期末']]))
df3
# python ruby golang
# 期中 期末 期中 期末 期中 期末
# 甲 128 67 139 89 127 116
# 乙 80 73 101 85 89 45
# 丙 75 122 61 56 141 137
# 丁 82 94 4 13 32 11
除了行索引index,列索引columns也能用同样的方法创建多层索引
#3层索引 行索引是8 2*2*2 列2层索引 2*5 10列
df4 = DataFrame(np.random.randint(0,150,(8,10)),
pd.MultiIndex.from_product([['期中','期末'],['李斌','何小鹏'],['测试一','测试二']]),
pd.MultiIndex.from_product([['上学期','下学期'],['体育','音乐','计算机','数学','语文']]))
df4
# 上学期 下学期
# 体育 音乐 计算机 数学 语文 体育 音乐 计算机 数学 语文
# 期中 李斌 测试一 39 116 36 9 132 116 104 43 107 35
# 测试二 95 7 54 32 122 88 44 134 85 135
# 何小鹏 测试一 27 14 21 132 48 90 119 79 145 107
# 测试二 35 79 7 40 79 144 83 148 109 18
# 期末 李斌 测试一 131 144 138 127 148 35 95 141 50 70
# 测试二 136 149 29 23 74 37 1 131 78 0
# 何小鹏 测试一 47 71 87 128 64 69 132 30 100 53
# 测试二 146 43 38 65 40 123 27 12 66 58
【重要】对于Series来说,直接中括号[]与使用.loc()完全一样,因此,推荐使用中括号索引和切片。
索引:
s = Series(data=np.random.randint(0,100,6),index=[['a','a','b','b','c','c'],['期中','期末','期中','期末','期中','期末']])
s
#a 期中 37
# 期末 9
#b 期中 40
# 期末 47
#c 期中 43
# 期末 8
#dtype: int32
s.c.期末
#0
s[-1]
#0
(1) 可以直接使用列名称来进行列索引
(2) 使用行索引需要用ix(),loc()等函数
【极其重要】推荐使用loc()函数
注意在对行索引的时候,若一级行索引还有多个,对二级行索引会遇到问题!也就是说,无法直接对二级索引进行索引,必须让二级索引变成一级索引后才能对其进行索引!
#3层索引 行索引是8 2*2*2 列2层索引 2*5 10列
df4 = DataFrame(np.random.randint(0,150,(8,10)),
pd.MultiIndex.from_product([['期中','期末'],['李斌','何小鹏'],['测试一','测试二']]),
pd.MultiIndex.from_product([['上学期','下学期'],['体育','音乐','计算机','数学','语文']]))
df4
# 上学期 下学期
# 体育 音乐 计算机 数学 语文 体育 音乐 计算机 数学 语文
# 期中 李斌 测试一 39 116 36 9 132 116 104 43 107 35
# 测试二 95 7 54 32 122 88 44 134 85 135
# 何小鹏 测试一 27 14 21 132 48 90 119 79 145 107
# 测试二 35 79 7 40 79 144 83 148 109 18
# 期末 李斌 测试一 131 144 138 127 148 35 95 141 50 70
# 测试二 136 149 29 23 74 37 1 131 78 0
# 何小鹏 测试一 47 71 87 128 64 69 132 30 100 53
# 测试二 146 43 38 65 40 123 27 12 66 58
#使用[]查找李斌 期末考试 测试二 上学期的体育成绩
df4['上学期','体育']['期末','李斌','测试二']
#136
#什么时候用隐式,什么时候用显示?
#答:在搜索关键字的时候使用显示索引
#在切片的时候用隐式
df4.loc['期末','李斌','测试二']['上学期','体育']136
#136
df4.iloc[5,0]
136
stack() #stack()将列索引变行索引
unstack()
Series.stack() DataFrame.unstack()
#在pandas当中stack不是级联,而是索引的转变
df4 = DataFrame(np.random.randint(0,150,(2,2)),
pd.MultiIndex.from_product([['期中'],['李斌'],['测试一','测试二']]),
pd.MultiIndex.from_product([['上学期'],['体育','音乐']]))
df4
# 上学期
# 体育 音乐
# 期中 李斌 测试一 20 100
# 测试二 104 137
【小技巧】使用stack()的时候,level等于哪一个,哪一个就消失,出现在行里。
#stack()将列索引变行索引
#-代表的是最能层的索引
df4.stack(level=0)
# 体育 音乐
#期中 李斌 测试一 上学期 20 100
# 测试二 上学期 104 137
#将所用的列索引变成行索引
df4.stack((-2,-1))
#期中 李斌 测试一 上学期 体育 20
# 音乐 100
# 测试二 上学期 体育 104
# 音乐 137
#dtype: int32
df4.stack().stack()
#期中 李斌 测试一 体育 上学期 20
# 音乐 上学期 100
# 测试二 体育 上学期 104
# 音乐 上学期 137
【小技巧】使用unstack()的时候,level等于哪一个,哪一个就消失,出现在列里。
#在查找关键字的时候非常有用,但是非常繁琐,效率又低下
df4.unstack([-1,-2,-3])
#上学期 体育 测试一 期中 李斌 20
# 测试二 期中 李斌 104
# 音乐 测试一 期中 李斌 100
# 测试二 期中 李斌 137
#dtype: int32
【注意】
所谓的聚合操作:平均数,标准差,最大值,最小值……
df4 = DataFrame(np.random.randint(0,150,(2,2)),
pd.MultiIndex.from_product([['期中'],['李斌'],['测试一','测试二']]),
pd.MultiIndex.from_product([['上学期'],['体育','音乐']]))
df4
# 上学期
# 体育 音乐
# 期中 李斌 测试一 20 100
# 测试二 104 137
df4.mean(axis=1)#平均数
df4.std()#标准差
df4.max(axis=1)#最大值
df4.min(axis=0)#最小值
pandas 和 mysql 非常的相似,
mysql可以对数据进行统计
pandas主要作用就是对数据进行一个统计 pandas 也有类似于 left join 的操作 select union select
pandas的拼接分为两种:
#生成DataFrame data index columns
def make_df(indexs,cols):
data = {col:[str(col)+str(inds) for inds in indexs] for col in cols}
return DataFrame(data=data,index=indexs,columns=cols)
pandas使用pd.concat函数,与np.concatenate函数类似,只是多了一些参数:
pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,
keys=None, levels=None, names=None, verify_integrity=False,
copy=True)
df1 = make_df([0,1,2],list('abc'))
df1
# a b c
#0 a0 b0 c0
#1 a1 b1 c1
#2 a2 b2 c2
df2 = make_df([3,4,5],list('abc'))
df2
# a b c
#3 a3 b3 c3
#4 a4 b4 c4
#5 a5 b5 c5
和np.concatenate一样,优先增加行数(默认axis=0)
pd.concat((df1,df2))
# a b c
# 0 a0 b0 c0
# 1 a1 b1 c1
# 2 a2 b2 c2
# 3 a3 b3 c3
# 4 a4 b4 c4
# 5 a5 b5 c5
可以通过设置axis来改变级联方向
pd.concat((df1,df2,df1),axis=1)
# a b c a b c a b c
# 0 a0 b0 c0 NaN NaN NaN a0 b0 c0
# 1 a1 b1 c1 NaN NaN NaN a1 b1 c1
# 2 a2 b2 c2 NaN NaN NaN a2 b2 c2
# 3 NaN NaN NaN a3 b3 c3 NaN NaN NaN
# 4 NaN NaN NaN a4 b4 c4 NaN NaN NaN
# 5 NaN NaN NaN a5 b5 c5 NaN NaN NaN
注意index在级联时可以重复
r1 = pd.concat((df1,df3))
r1
# a b c
# 0 a0 b0 c0
# 1 a1 b1 c1
# 2 a2 b2 c2
# 1 a1 b1 c1
# 2 a2 b2 c2
# 3 a3 b3 c3
r1.loc[1]
# a b c
#1 a1 b1 c1
#1 a1 b1 c1
也可以选择忽略ignore_index,重新建立索引(也就是mysql中的id)
r2 = pd.concat((df1,df3),ignore_index=True)
r2
# a b c
# 0 a0 b0 c0
# 1 a1 b1 c1
# 2 a2 b2 c2
# 3 a1 b1 c1
# 4 a2 b2 c2
# 5 a3 b3 c3
或者使用多层索引 keys:concat([x,y],keys=[‘x’,‘y’])
r3 = pd.concat((df1,df3),keys=['df1','df3'])
r3
# a b c
# df1 0 a0 b0 c0
# 1 a1 b1 c1
# 2 a2 b2 c2
# df3 1 a1 b1 c1
# 2 a2 b2 c2
# 3 a3 b3 c3
r3.loc['df1',1]
#a a1
#b b1
#c c1
#Name: (df1, 1), dtype: object
df.set_index() 设置指定的字段为行号
r4 = DataFrame(res)
r4
# age city seat sex sid sname
# 0 21 上海 10 男 1 郭斌
# 1 20 北京 2 男 2 小京
# 2 22 北京 3 男 3 小强
# 3 20 上海 4 男 4 小力
# 4 21 上海 5 女 5 小丽
# 5 42 北京 6 女 6 小芳
# 6 65 俄国 7 男 7 普大帝
# 7 70 美利坚 100 男 11 特朗普
# 8 70 美利坚 100 男 12 三胖
# 9 70 美利坚 100 男 13 三胖1
#在python中如果某个函数是有返回值,说明该函数不对原数据产生影响
r4.set_index('sid',inplace=True)
r4
# age city seat sex sname
# sid
# 1 21 上海 10 男 郭斌
# 2 20 北京 2 男 小京
# 3 22 北京 3 男 小强
# 4 20 上海 4 男 小力
# 5 21 上海 5 女 小丽
# 6 42 北京 6 女 小芳
# 7 65 俄国 7 男 普大帝
r4.loc[7]
# age 65
# city 俄国
# seat 7
# sex 男
# sname 普大帝
# Name: 7, dtype: object
不匹配指的是级联的维度的索引不一致。例如纵向级联时列索引不一致,横向级联时行索引不一致
有3种连接方式:
pd.concat((df1,df2),axis=1,join='outer') #outer join
# a b c a b c
# 0 a0 b0 c0 NaN NaN NaN
# 1 a1 b1 c1 NaN NaN NaN
# 2 a2 b2 c2 NaN NaN NaN
# 3 NaN NaN NaN a3 b3 c3
# 4 NaN NaN NaN a4 b4 c4
# 5 NaN NaN NaN a5 b5 c5
pd.concat((df1,df2),axis=1,join='inner')
#a b c a b c
df4 = make_df([0,1,2],list('cde'))
df4
# c d e
#0 c0 d0 e0
#1 c1 d1 e1
#2 c2 d2 e2
df1
# a b c
#0 a0 b0 c0
#1 a1 b1 c1
#2 a2 b2 c2
pd.concat((df1,df4),join='inner')
# ``c
#0 c0
#1 c1
#2 c2
#0 c0
#1 c1
#2 c2
#行和列是可以重复的、或者以谁为列属性
pd.concat((df1,df4),axis=1,join='inner')
# a b c c d e
#0 a0 b0 c0 c0 d0 e0
#1 a1 b1 c1 c1 d1 e1
#2 a2 b2 c2 c2 d2 e2
pd.concat([df1,df4],join_axes=[df1.columns]) #轴面
# a b c
#0 a0 b0 c0
#1 a1 b1 c1
#2 a2 b2 c2
#0 NaN NaN c0
#1 NaN NaN c1
#2 NaN NaN c2
r5 = pd.concat([df1,df4])
r5
# a b c d e
# 0 a0 b0 c0 NaN NaN
# 1 a1 b1 c1 NaN NaN
# 2 a2 b2 c2 NaN NaN
# 0 NaN NaN c0 d0 e0
# 1 NaN NaN c1 d1 e1
# 2 NaN NaN c2 d2 e2
r5.drop(labels='d',axis=1)
# a b c e
# 0 a0 b0 c0 NaN
# 1 a1 b1 c1 NaN
# 2 a2 b2 c2 NaN
# 0 NaN NaN c0 e0
# 1 NaN NaN c1 e1
# 2 NaN NaN c2 e2
r5.drop(labels=['d','e'],axis=1)
# a b c
#0 a0 b0 c0
#1 a1 b1 c1
#2 a2 b2 c2
#0 NaN NaN c0
#1 NaN NaN c1
#2 NaN NaN c2
a = r5.T
a
# 0 1 2 0 1 2
# a a0 a1 a2 NaN NaN NaN
# b b0 b1 b2 NaN NaN NaN
# c c0 c1 c2 c0 c1 c2
# g 1 2 2 3 3 4
# d NaN NaN NaN d0 d1 d2
# e NaN NaN NaN e0 e1 e2
a.insert(1,3,[1,2,3,4,5,6])
a.T
# a b c g d e
# 0 a0 b0 c0 1 NaN NaN
# 3 1 2 3 4 5 6
# 1 a1 b1 c1 2 NaN NaN
# 2 a2 b2 c2 2 NaN NaN
# 0 NaN NaN c0 3 d0 e0
# 1 NaN NaN c1 3 d1 e1
# 2 NaN NaN c2 4 d2 e2
df4 = make_df([0,1,2],list('cde'))
df4
# c d e
#0 c0 d0 e0
#1 c1 d1 e1
#2 c2 d2 e2
df1
# a b c
#0 a0 b0 c0
#1 a1 b1 c1
#2 a2 b2 c2
#outer join
df1.append(df4)
# a b c d e
# 0 a0 b0 c0 NaN NaN
# 1 a1 b1 c1 NaN NaN
# 2 a2 b2 c2 NaN NaN
# 0 NaN NaN c0 d0 e0
# 1 NaN NaN c1 d1 e1
# 2 NaN NaN c2 d2
df1.T.append(df4.T,ignore_index=True)
# 0 1 2
# 0 a0 a1 a2
# 1 b0 b1 b2
# 2 c0 c1 c2
# 3 c0 c1 c2
# 4 d0 d1 d2
# 5 e0 e1 e2
merge与concat的区别在于,merge需要依据某一共同的行或列来进行合并
使用pd.merge()合并时,会自动根据两者相同column名称的那一列,作为key来进行合并。
concat:一次性可以融合多张表,默认使用的全外连接
merge:一次性可以融合两张表,默认使用内连接,并且可以使用左外和右外连接,merge和mysql的sql是相似的、自动会将相同的字段合并
注意每一列元素的顺序不要求一致
全外连接
df1
# a b c
#0 a0 b0 c0
#1 a1 b1 c1
#2 a2 b2 c2
df2
# a b c
#3 a3 b3 c3
#4 a4 b4 c4
#5 a5 b5 c5
pd.merge(df2,df1,how='outer')
# a b c
#0 a3 b3 c3
#1 a4 b4 c4
#2 a5 b5 c5
#3 a0 b0 c0
#4 a1 b1 c1
#5 a2 b2 c2
等值连接
df5
# c d e
#1 c1 d1 e1
#2 c2 d2 e2
#3 c3 d3 e3
df1
# a b c
#0 a0 b0 c0
#1 a1 b1 c1
#2 a2 b2 c2
pd.merge(df1,df5) #inner
# a b c d e
#0 a1 b1 c1 d1 e1
#1 a2 b2 c2 d2 e2
左、右外连接
df5
# c d e
#1 c1 d1 e1
#2 c2 d2 e2
#3 c3 d3 e3
df1
# a b c
#0 a0 b0 c0
#1 a1 b1 c1
#2 a2 b2 c2
pd.merge(df1,df5,how='left')
# a b c d e
#0 a0 b0 c0 NaN NaN
#1 a1 b1 c1 d1 e1
#2 a2 b2 c2 d2 e2
pd.merge(df1,df5,how='right')
# a b c d e
#0 a1 b1 c1 d1 e1
#1 a2 b2 c2 d2 e2
#2 NaN NaN c3 d3 e3
df6 = make_df([1,1,1,2,2,0],list('cde'))
display(df1,df6)
# a b c
#0 a0 b0 c0
#1 a1 b1 c1
#2 a2 b2 c2
# c d e
#1 c1 d1 e1
#1 c1 d1 e1
#1 c1 d1 e1
#2 c2 d2 e2
#2 c2 d2 e2
#0 c0 d0 e0
pd.merge(df1,df6,how='right')
# a b c d e
#0 a0 b0 c0 d0 e0
#1 a1 b1 c1 d1 e1
#2 a1 b1 c1 d1 e1
#3 a1 b1 c1 d1 e1
#4 a2 b2 c2 d2 e2
#5 a2 b2 c2 d2 e2
df7 = make_df([0,0,1,2,2,2],list('abc'))
display(df6,df7)
# c d e
#1 c1 d1 e1
#1 c1 d1 e1
#1 c1 d1 e1
#2 c2 d2 e2
#2 c2 d2 e2
#0 c0 d0 e0
# a b c
#0 a0 b0 c0
#0 a0 b0 c0
#1 a1 b1 c1
#2 a2 b2 c2
#2 a2 b2 c2
#2 a2 b2 c2
pd.merge(df6,df7,how='left')
# c d e a b
#0 c1 d1 e1 a1 b1
#1 c1 d1 e1 a1 b1
#2 c1 d1 e1 a1 b1
#3 c2 d2 e2 a2 b2
#4 c2 d2 e2 a2 b2
#5 c2 d2 e2 a2 b2
#6 c2 d2 e2 a2 b2
#7 c2 d2 e2 a2 b2
#8 c2 d2 e2 a2 b2
#9 c0 d0 e0 a0 b0
#10 c0 d0 e0 a0 b0
#mysql取出来的关联表的字段大部分都不是同名字段
df4
# c d e
#0 c0 d0 e0
#1 c1 d1 e1
#2 c2 d2 e2
#修改字段名**
df4.columns = list('wde')
df4
# w d e
#0 c0 d0 e0
#1 c1 d1 e1
#2 c2 d2 e2
df1
# a b c
#0 a0 b0 c0
#1 a1 b1 c1
#2 a2 b2 c2
#使用on=显式指定哪一列为key,当有多个key相同时使用
pd.merge(df1,df4,on=[df1.c,df4.w])
# a b c w d e
#0 a0 b0 c0 c0 d0 e0
#1 a1 b1 c1 c1 d1 e1
#2 a2 b2 c2 c2 d2 e2
#使用left_on和right_on指定左右两边的列作为key,当左右两边的key都不想等时使用
pd.merge(df1,df4,left_on='c',right_on='w') # on df1.c=df4.w
# a b c w d e
#0 a0 b0 c0 c0 d0 e0
#1 a1 b1 c1 c1 d1 e1
#2 a2 b2 c2 c2 d2 e2
内合并:只保留两者都有的key(默认模式)
外合并 how=‘outer’:补NaN
左合并、右合并:how=‘left’,how=‘right’,
display(df1,df3)
# a b c
#0 a0 b0 c0
#1 a1 b1 c1
#2 a2 b2 c2
# a b c
#1 a1 b1 c1
#2 a2 b2 c2
#3 a3 b3 c3
pd.merge(df1,df3)
# a b c
#0 a1 b1 c1
#1 a2 b2 c2
pd.merge(df1,df3,how='left')
#a b c
#0 a0 b0 c0
#1 a1 b1 c1
#2 a2 b2 c2
pd.merge(df1,df3,how='right')
# a b c
#0 a1 b1 c1
#1 a2 b2 c2
#2 a3 b3 c3
#outer join = left join + righe join 所有数据
pd.merge(df1,df3,how='outer')
# a b c
#0 a0 b0 c0
#1 a1 b1 c1
#2 a2 b2 c2
#3 a3 b3 c3
当列冲突时,即有多个列名称相同时,需要使用on=来指定哪一个列作为key,配合suffixes指定冲突列名,
可以使用suffixes=自己指定后缀
#比如说mysql中有A,B表 A=[aa,bb,cc,dd] B=[cc,dd,ee,pp] cc dd数据类型是一致的,含义也一致
df8 = make_df([0,1,2],list('bcd'))
display(df1,df8)
# a b c
#0 a0 b0 c0
#1 a1 b1 c1
#2 a2 b2 c2
# b c d
#0 b0 c0 d0
#1 b1 c1 d1
#2 b2 c2 d2
pd.merge(df1,df8,left_on='b',right_on='b', suffixes=('_df1', '_df8'))
#有两个字段名完全相同的时候,merge会自动的给非指定关联的同名字段拼接一个后缀名
#两张表的中字段名一样,数据类型也一样,但是含义不一样
# a b c_df1 c_df8 d
#0 a0 b0 c0 c0 d0
#1 a1 b1 c1 c1 d1
#2 a2 b2 c2 c2 d2
美国各州人口数据分析:
#
#
#
#
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from pandas import Series,DataFrame
使用duplicated()函数检测重复的行,返回元素为布尔类型的Series对象,每个元素对应一行,如果该行不是第一次出现,则元素为True
df = DataFrame({'color':['white','pink','green','blue','white'],'size':[255,250,123,222,255]})
df
# color size
#0 white 255
#1 pink 250
#2 green 123
#3 blue 222
#4 white 255
#df.duplicated() 返回bool型的值,如果不重复返回false ,有重复值返回Ture
df.duplicated(keep='first')
#0 False
#1 False
#2 False
#3 False
#4 True
#dtype: bool
#使用drop_duplicates()函数删除重复的行
#假如某一列是重复的,怎么删
df.drop_duplicates()
# color size
#0 white 255
#1 pink 250
#2 green 123
#3 blue 222
df1 = pd.concat((df,df),axis=1)
df1
# color size color size
#0 white 255 white 255
#1 pink 250 pink 250
#2 green 123 green 123
#3 blue 222 blue 222
#4 white 255 white 255
df1.drop_duplicates()
# color size color size
#0 white 255 white 255
#1 pink 250 pink 250
#2 green 123 green 123
#3 blue 222 blue 222
#怎么去除重复的列
df1.T.drop_duplicates().T
# color size
#0 white 255
#1 pink 250
#2 green 123
#3 blue 222
#4 white 255
映射的含义:创建一个映射关系列表,把values元素和一个特定的标签或者字符串绑定
需要使用字典:
map = { 'label1':'value1',
'label2':'value2',
...
}
包含三种操作:
使用一种数据类型dict:使用replace()函数,对values进行替换操作
df
# color size
#0 white 255
#1 pink 250
#2 green 123
#3 blue 222
#4 white 255
dict_ = {'blue':222,'red':200}
#将默写值替换成你想要的值
df.replace(dict_)
# color size
#0 white 255
#1 pink 250
#2 green 123
#3 222 222
#4 white 255
replace还经常用来替换NaN元素
df2 = DataFrame({'name':['tom',np.nan,'hanmeimei','lilei',np.nan]})
df2
# name
#0 tom
#1 NaN
#2 hanmeimei
#3 lilei
#4 NaN
#恶意字符 ? @、fillna()只认识NaN
#用的很多,在机器学习中,
#特征工程,特征工程的步骤当中,有一步就是填充空缺值,
#np.nan, mysql中的空缺值??
ds = {'?':0,np.nan:0,'@':0}
df2.replace(ds)
# name
#0 tom
#1 0
#2 hanmeimei
#3 lilei
#4 0
使用map()函数,由已有的列生成一个新列
适合处理某一单独的列。
df3 = DataFrame(np.random.randint(0,150,(4,2)),
list('甲乙丙丁'),
['python','java'])
df3
# python java
#甲 2 134
#乙 74 74
#丙 69 59
#丁 54 119
#我想要增加一列数学,数学的成绩是python的1.5倍
#map中的参数应当是一个函数
df3['math'] = df3['python'].map(lambda x : x * 1.5)
df3
# python java math
#甲 2 134 3.0
#乙 74 74 111.0
#丙 69 59 103.5
#丁 54 119 81.0
df3['python']['甲'] = np.NaN
df3['java']['乙'] = np.NaN
def con(x):
if str(x) == 'nan':
return 0
else:
return x
for k in df3.columns:
df3[k]=df3[k].map(con)
df3
# python java math
#甲 0.0 134.0 3.0
#乙 74.0 0.0 111.0
#丙 69.0 59.0 103.5
#丁 54.0 119.0 81.0
transform是变形的意思
transform中的值只能是一个function
df3
# python java math
#甲 0.0 134.0 3.0
#乙 74.0 0.0 111.0
#丙 69.0 59.0 103.5
#丁 54.0 119.0 81.0
#将数据成绩大于60的合格,70中等,80良好,90优秀
def level(x):
if x >= 90:
return '优秀'
elif x>=80:
return '良好'
elif x>=70:
return '中等'
elif x>=60:
return '合格'
else:
return '养猪去吧'
df3['level'] = df3['math'].transform(level)
df3
# python java math level
#甲 0.0 134.0 3.0 养猪去吧
#乙 74.0 0.0 111.0 优秀
#丙 69.0 59.0 103.5 优秀
#丁 54.0 119.0 81.0 良好
仍然是新建一个字典
使用rename()函数替换行索引
#行号我想要做替换
index_dict_ = {'甲':'东邪','乙':'西毒','丙':'南帝','丁':'北丐','中':'中神通'}
df3.rename(index_dict_)
# python java math level
#东邪 0.0 134.0 3.0 养猪去吧
#西毒 74.0 0.0 111.0 优秀
#南帝 69.0 59.0 103.5 优秀
#北丐 54.0 119.0 81.0 良好
使用describe()函数查看每一列的描述性统计量
#姚明 中国男性 身高的异常值 std 标准差的数值越大 表明数据的波动就越大
df4 = DataFrame(np.random.randint(0,150,(10,4)),
columns=['数学','语文','英语','物理'])
df4
# 数学 语文 英语 物理
#0 119 66 71 44
#1 65 120 61 36
#2 27 148 93 106
#3 27 140 105 121
#4 38 149 54 125
#5 137 82 50 42
#6 16 86 80 5
#7 109 61 116 81
#8 122 80 106 132
#9 8 33 54 120
df4.std()#矩阵标准差
#数学 50.021773
#语文 40.371194
#英语 24.608038
#物理 45.914897
#dtype: float64
#%50表示这组数据的高斯分布中间值
#归一化 标准化
#看std就可以看出数据中是否有异常值,标准范围是有指定的
df4.describe()
# 数学 语文 英语 物理
#count 10.000000 10.000000 10.000000 10.000000
#mean 66.800000 96.500000 79.000000 81.200000
#std 50.021773 40.371194 24.608038 45.914897
#min 8.000000 33.000000 50.000000 5.000000
#25% 27.000000 69.500000 55.750000 42.500000
#50% 51.500000 84.000000 75.500000 93.500000
#75% 116.500000 135.000000 102.000000 120.750000
#max 137.000000 149.000000 116.000000 132.000000
he_ = np.array([165,185])
std_ = np.array([140,122,175,175,180,181,190,195,226])
he_.std()
#10.0
std_.std()
#28.50341110190927
if std_.std() > he_.std():
print('有异常值')
#有异常值
使用std()函数可以求得DataFrame对象每一列的标准差
根据每一列的标准差,对DataFrame元素进行过滤。
借助any()函数, 测试是否有True,有一个或以上返回True,反之返回False
对每一列应用筛选条件,去除标准差太大的数据
sort_values() sort_index()
df3.sort_values('python')
# python java math level
#甲 0.0 134.0 3.0 养猪去吧
#丁 54.0 119.0 81.0 良好
#丙 69.0 59.0 103.5 优秀
#乙 74.0 0.0 111.0 优秀
df3.sort_index()
# python java math level
#丁 54.0 119.0 81.0 良好
#丙 69.0 59.0 103.5 优秀
#乙 74.0 0.0 111.0 优秀
#甲 0.0 134.0 3.0 养猪去吧
使用.take()函数排序
可以借助np.random.permutation()函数随机排序
#x表示输入一个int 代表数量
#permutation+take可是做随即排序
r = np.random.permutation(4)
r
#array([1, 0, 2, 3])
df3
# python java math level
#甲 0.0 134.0 3.0 养猪去吧
#乙 74.0 0.0 111.0 优秀
#丙 69.0 59.0 103.5 优秀
#丁 54.0 119.0 81.0 良好
df3.take(r)
# python java math level
#乙 74.0 0.0 111.0 优秀
#甲 0.0 134.0 3.0 养猪去吧
#丙 69.0 59.0 103.5 优秀
#丁 54.0 119.0 81.0 良好
#阳光普照奖 杯具
#5个人,10,20
df5 = DataFrame({'id':np.arange(0,100),'name':np.arange(1,101)})
res = np.random.permutation(100)#随机排列一个序列,或者返回一个置换的范围。
res
#array([80, 20, 83, 64, 77, 90, 48, 11, 51, 87, 53, 62, 75, 92, 32, 96, 68,
# 10, 46, 69, 24, 14, 37, 66, 26, 43, 18, 4, 60, 70, 82, 8, 9, 59,
# 78, 16, 28, 79, 15, 73, 35, 74, 84, 85, 45, 22, 55, 52, 95, 93, 98,
# 3, 47, 17, 19, 12, 36, 86, 30, 99, 57, 25, 34, 7, 63, 33, 54, 50,
# 0, 44, 21, 41, 2, 61, 23, 91, 38, 89, 58, 13, 49, 42, 56, 88, 39,
# 67, 27, 40, 1, 6, 81, 71, 65, 72, 31, 76, 94, 29, 97, 5])
one = df5.take(res)[:5]
one
# id name
#80 80 81
#20 20 21
#83 83 84
#64 64 65
#77 77 78
two = df5.take(res)[5:15]
two
# id name
#90 90 91
#48 48 49
#11 11 12
#51 51 52
#87 87 88
#53 53 54
#62 62 63
#75 75 76
#92 92 93
#32 32 33
数据聚合是数据处理的最后一步,通常是要使每一个数组生成一个单一的数值。
数据分类处理:
数据分类处理的核心: groupby()函数,groupby()在pandas中也担任分组的重担
如果想使用color列索引,计算price1的均值,可以先获取到price1列,然后再调用groupby函数,用参数指定color这一列,使用.groups属性查看各行的分组情况:
df6 = DataFrame({'item':['萝卜','白菜','大蒜','洋葱','韭菜','萝卜','白菜','大蒜','洋葱','韭菜'],
'seller':['赵大妈','赵大妈','李大妈','李大妈','李大妈','张大妈','张大妈','张大妈','詹大妈','詹大妈'],
'price':np.random.randint(1,14,10)})
df6
# item seller price
#0 萝卜 赵大妈 7
#1 白菜 赵大妈 8
#2 大蒜 李大妈 13
#3 洋葱 李大妈 2
#4 韭菜 李大妈 11
#5 萝卜 张大妈 9
#6 白菜 张大妈 9
#7 大蒜 张大妈 10
#8 洋葱 詹大妈 11
#9 韭菜 詹大妈 11
#groupby返回的结果是一个可迭代对象
for i in df6.groupby(['item']):
print(i)
#('大蒜', item seller price
#2 大蒜 李大妈 13
#7 大蒜 张大妈 10)
#('洋葱', item seller price
#3 洋葱 李大妈 2
#8 洋葱 詹大妈 11)
#('白菜', item seller price
#1 白菜 赵大妈 8
#6 白菜 张大妈 9)
#('萝卜', item seller price
#0 萝卜 赵大妈 7
#5 萝卜 张大妈 9)
#('韭菜', item seller price
#4 韭菜 李大妈 11
#9 韭菜 詹大妈 11)
add_prefix()添加前缀#求各个蔬菜的平均值,并把平均的价格添加为一列
mean_=df6.groupby(['item']).mean().add_prefix('mean_')
mean_
# mean_price
#item
#大蒜 11.5
#洋葱 6.5
#白菜 8.5
#萝卜 8.0
#韭菜 11.0
将各个蔬菜的平均价格融合到原表当中
df7 = pd.merge(df6,mean_,left_on='item',right_index=True)
df7.sort_index()#根据行号重新排序
# item price seller mean_price
#0 萝卜 12 赵大妈 11.5
#1 白菜 8 赵大妈 4.5
#2 大蒜 5 李大妈 6.5
#3 洋葱 2 李大妈 5.0
#4 韭菜 1 李大妈 3.5
#5 萝卜 11 张大妈 11.5
#6 白菜 1 张大妈 4.5
#7 大蒜 8 张大妈 6.5
#8 洋葱 8 詹大妈 5.0
#9 韭菜 6 詹大妈 3.5
#蔬菜波动 .std()
std_= df6.groupby(['item']).std().add_prefix('std_')
std_
# std_price
#item
#大蒜 2.121320
#洋葱 4.242641
#白菜 4.949747
#萝卜 0.707107
#韭菜 3.535534
#将波动融合到原表当中
df8 = pd.merge(df7,std_,left_on='item',right_index=True)
df8
# item price seller mean_price std_price
#0 萝卜 12 赵大妈 11.5 0.707107
#5 萝卜 11 张大妈 11.5 0.707107
#1 白菜 8 赵大妈 4.5 4.949747
#6 白菜 1 张大妈 4.5 4.949747
#2 大蒜 5 李大妈 6.5 2.121320
#7 大蒜 8 张大妈 6.5 2.121320
#3 洋葱 2 李大妈 5.0 4.242641
#8 洋葱 8 詹大妈 5.0 4.242641
#4 韭菜 1 李大妈 3.5 3.535534
#9 韭菜 6 詹大妈 3.5 3.535534
可以使用pd.merge()函数将聚合操作的计算结果添加到df的每一行
使用groupby分组后调用加和等函数进行运算,让后最后可以调用add_prefix(),来修改列名
可以使用transform和apply实现相同功能:在transform或者apply中传入函数即可
transform()与apply()函数还能传入一个函数或者lambda
df8
# item price seller mean_price std_price
#0 萝卜 12 赵大妈 11.5 0.707107
#5 萝卜 11 张大妈 11.5 0.707107
#1 白菜 8 赵大妈 4.5 4.949747
#6 白菜 1 张大妈 4.5 4.949747
#2 大蒜 5 李大妈 6.5 2.121320
#7 大蒜 8 张大妈 6.5 2.121320
#3 洋葱 2 李大妈 5.0 4.242641
#8 洋葱 8 詹大妈 5.0 4.242641
#4 韭菜 1 李大妈 3.5 3.535534
#9 韭菜 6 詹大妈 3.5 3.535534
#对蔬菜的价格求个和
#pandas用的不多 在mysql中用的非常的多
df8.groupby(['item'])['price'].sum()
# item
#大蒜 23
#洋葱 13
#白菜 17
#萝卜 16
#韭菜 22
#Name: price, dtype: int32
#得到的是一个Series
df8.groupby(['item'])['price'].transform(sum).drop_duplicates()
#std_0 16
#std_1 17
#std_2 23
#std_3 13
#std_4 22
#Name: price, dtype: int32
#apply的操作对象,也就是传给lambda的参数是整列的数组
#sum() np.sum()
df8.groupby(['item'])['price'].apply(np.sum)
# item
#大蒜 13
#洋葱 10
#白菜 9
#萝卜 23
#韭菜 7
#Name: price, dtype: int64
Series和DataFrame都有一个生成各类图标的plot方法,默认情况下锁生成的都是线形图
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
折线 抛物线
s = Series(np.random.randint(0,10000,10))
#plt是一个类对象
plt.plot(s)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xa0lXx4X-1592462080564)(数据分析图片/折线图png)]
#是一个Series的实例对象
#plot()函数是matplotlib的一个函数库
#为什么pandas的实例对象可以使用plot()? 因为pandas和matplotlib互相依赖,plt不引入,plot()函数将不打印图像
s.plot()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1AntKXsI-1592462080565)(数据分析图片/折线图png)]
df = DataFrame(np.random.randint(0,10,(5,4)),columns=['python','java','golang','ruby'])
df
# python java golang ruby
#0 4 1 0 8
#1 5 5 3 5
#2 5 0 1 8
#3 0 8 2 2
#4 9 1 0 1
df.plot()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XrXFa3uZ-1592462080566)(数据分析图片/折线成绩png)]
#使用plt.plot()画出的图像是没有图例的,plt的图例需要自己去创建
plt.plot(df)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O2Xb5DNt-1592462080567)(数据分析图片/折线无图例成绩png)]
DataFrame柱状图例
s1 = Series(np.random.randint(1,10,10))
s1
#0 2
#1 1
#2 8
#3 2
#4 9
#5 6
#6 1
#7 5
#8 7
#9 4
#dtype: int3
s1.plot(kind='bar')
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NCv21tGO-1592462080568)(数据分析图片/柱状图png)]
df
# python java golang ruby
#0 4 1 0 8
#1 5 5 3 5
#2 5 0 1 8
#3 0 8 2 2
#4 9 1 0 1
df.plot(kind='barh')
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OVFuvfXd-1592462080569)(数据分析图片/多柱形图png)]
读取tips.csv,查看每天聚会人数,每天各种聚会规模的比例 求和并df.sum(),灵活使用axis()
#是一个国外餐馆的每天人数统计,行是日期,列是人数
tips = pd.read_csv('tips.csv')
tips
# day 1 2 3 4 5 6
#0 Fri 1 16 1 1 0 0
#1 Stat 2 53 18 13 1 0
#2 Sun 0 39 15 18 3 1
#3 Thur 1 48 4 5 1 3
#set_index()
tips.set_index('day',inplace=True)#线性图 or 直方图
tips.plot(kind='bar')
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OK0g6AhW-1592462080570)(数据分析图片/营业额柱状图png)]
#1个人来 和 6个人来 数据量很小
#把数量比较小的行或列认为是不重要的,可以忽略不计的
#500W 50几块 50几块占用的比例非常的小
tips.drop(['1','6'],axis=1).plot(kind='bar')
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8TSeP2cC-1592462080571)(数据分析图片/营业额修正png)]
random生成随机直方图,调用hist()方法
#都是做统计的,但是直方图是只认识一维的数据,而柱状图只认识二维的
S3 = Series(np.random.randint(0,10,10))
S3
#0 1
#1 1
#2 9
#3 0
#4 0
#5 5
#6 0
#7 7
#8 6
#9 6
#dtype: int32
#bins表示的是图片的宽度,值越小越宽,越大越窄
S3.hist(bins=20)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AvtRjNCb-1592462080571)(数据分析图片/直方图png)]
【饼图也只有一个参数x!】
pie()
饼图适合展示各部分占总体的比例,条形图适合比较各部分的大小
#显示比例的
b = np.array([0.3,0.2,0.35,0.4])
plt.pie(b)
plt.axis('equal')
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q71bONln-1592462080572)(数据分析图片/饼图png)]
普通未占满饼图
饼图阴影、分裂等属性设置
#labels参数设置每一块的标签;labeldistance参数设置标签距离圆心的距离(比例值)
#autopct参数设置比例值的显示格式(%1.1f%%);pctdistance参数设置比例值文字距离圆心的距离
#explode参数设置每一块顶点距圆形的长度(比例值);colors参数设置每一块的颜色;
#shadow参数为布尔值,设置是否绘制阴影
#gdp
gdp = np.array([0.2,0.8,0.5,0.3,0.15,0.4,0.05])
labels = np.array(['AnHui','JiangSu','ZheJiang','FuJian','HuNan','HeNan','SanXi'])
plt.pie(gdp,labels=labels,autopct='%.2f%%',explode=[0.1,0,0.2,0,0,0,0.1])
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AQdIK6Wz-1592462080573)(数据分析图片/飞饼图png)]
S3 = Series(np.random.randint(0,10,10))
S3.plot(kind='kde')
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-90SuMFxX-1592462080573)(数据分析图片/随机百分比密度图png)]
这两张表经常会被画在一起,直方图以规格形式给出(以便画出密度图),然后在再其上绘制核密度估计。
接下来看看一个由两个不同de 标准正太正太分布组成的双峰分布。
np.random.normal()正太分布函数
直方图hist,函数中心必须添加属性normed = True
S3.plot(kind='kde')
S3.hist(normed=True) #归一化的 将数据按比例压缩在0-1之间,是数据统计的常用手段
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AuFmVJLx-1592462080574)(数据分析图片/柱状密度图png)]
df5 = DataFrame(np.random.randint(0,100,(10,3)),columns=list('ABC'))
df5
# A B C
#0 61 71 98
#1 26 59 52
#2 48 31 64
#3 42 13 8
#4 48 88 6
#5 77 15 39
#6 33 22 30
#7 56 72 94
#8 6 15 43
#9 13 98 83
#在df5当中添加一个新的列,新的列叫D和C列的关系是两倍 .map()
df5['D'] = df5['C'].map(lambda x : x * 2)
df5
# A B C D
#0 61 71 98 196
#1 26 59 52 104
#2 48 31 64 128
#3 42 13 8 16
#4 48 88 6 12
#5 77 15 39 78
#6 33 22 30 60
#7 56 72 94 188
#8 6 15 43 86
#9 13 98 83 166
#散点图是一个二维的图形,用x轴的坐标和y轴的坐标交汇形成
#df5是一个二维的数据,一共有4列,但是这4列对于散点图来说叫4个维度
#从df5当中抽选两列代表X和Y轴
df5.plot(kind='scatter',x='C',y='D')
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tGx4lMrM-1592462080575)(数据分析图片/散点图png)]
#B和C之间是没有关系
df5.plot(kind='scatter',x='B',y='C')
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9N8WM7O7-1592462080576)(数据分析图片/散点图2png)]
散布图矩阵,当有多个时,两两点之间的联系
函数:pd.plotting.scatter_matrix(),注意参数diagnol:对角线
#定义显示图片的尺寸的 但是英寸 第一个值代表的是宽度,第二个值代表的高度
pd.plotting.scatter_matrix(df5,figsize=(18,12),diagonal='kde')
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wpseILTJ-1592462080577)(数据分析图片/散布图矩阵png)]
#引入3D图形库
from mpl_toolkits.mplot3d.axes3d import Axes3D
#生成数据
x = np.linspace(0,2*np.pi,100)
y = np.linspace(0,2*np.pi,100)
#z的值根据x和y来获取 meshgrid返回一个两个数组
xx,yy = np.meshgrid(x,y)
display(xx,yy)
#把两组坐标值交汇起来,形成点
z = np.sin(xx) +np.sin(yy)
#Axes3D依赖于matplotlib
plt.figure(figsize=(12,6))
axes3d = plt.subplot(1,2,1,projection='3d')
axes3d.plot_surface(xx,yy,z)
#3d热图
axes3d = plt.subplot(1,2,2,projection='3d')
pic = axes3d.plot_surface(xx,yy,z,cmap='rainbow')
#shrink
plt.colorbar(pic,shrink=0.5)
#SVM
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VMS93HPg-1592462080578)(数据分析图片/3Dpng)]
#线性s 图
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from pandas import Series,DataFrame
#1.导入数据
apple = pd.read_csv('./AAPL.csv')
#将数据转为线性图
apple.plot()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jBw6exG1-1592462080579)(数据分析图片/苹果线性图png)]
#3.Date没什么太大用,但是可以作为行号,也就是,将其转为纵坐标,显示每天的变化值
apple.set_index('Date',inplace=True)
#4.Volume的数值太大,影响整个图形结构,暂时先删除它
apple.drop(labels='Volume',axis=1,inplace=True)
#调整图片的大小
#AxesSubplot 表示的是一个画布对象
apple_axes = apple.plot()
#获取当前画布的大小
fig = apple_axes.get_figure()
#设置新的尺寸 inches 设置画布的单位是英寸,第一个值是x轴的宽度,第二个值是y轴的高度
fig.set_size_inches(18,10)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6qaXnjK9-1592462080580)(数据分析图片/苹果股票历史涨跌png)]
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from pandas import Series,DataFrame
#月份
months = {'JAN' : 1, 'FEB' : 2, 'MAR' : 3, 'APR' : 4, 'MAY' : 5,
'JUN' : 6,'JUL' : 7, 'AUG' : 8, 'SEP' : 9, 'OCT': 10,
'NOV': 11, 'DEC' : 12}
#候选人
of_interest = ['Obama, Barack', 'Romney, Mitt',
'Santorum, Rick', 'Paul, Ron', 'Gingrich, Newt']
#党派
parties = {
'Bachmann, Michelle': 'Republican',
'Romney, Mitt': 'Republican',
'Obama, Barack': 'Democrat',
"Roemer, Charles E. 'Buddy' III": 'Reform',
'Pawlenty, Timothy': 'Republican',
'Johnson, Gary Earl': 'Libertarian',
'Paul, Ron': 'Republican',
'Santorum, Rick': 'Republican',
'Cain, Herman': 'Republican',
'Gingrich, Newt': 'Republican',
'McCotter, Thaddeus G': 'Republican',
'Huntsman, Jon': 'Republican',
'Perry, Rick': 'Republican'
}
#读取文件
ele = pd.read_csv('./usa_election.csv')
#查看文件样式以及基本信息
ele.head()
#【知识点】使用map函数+字典,新建一列各个候选人所在党派party
#map()直接写字典也是可以可以使用的,传进的值会被当做是字典的键
ele['party'] = ele['cand_nm'].map(parties)
ele.head()
#使用np.unique()函数查看colums:party这一列中有哪些元素
#怎么查看摸一个数值的唯一代表
ele['party'].unique()
#使用value_counts()函数,统计party列中各个元素出现次数
#整张表当中都是圈钱的数据
#每个党派接受圈钱的次数
ele['party'].value_counts() #统计关于不同党派的总记录数
#【知识点】使用groupby(),查看各个党派收到的政治献金总数contb_receipt_amt
ele.groupby(['party'])['contb_receipt_amt'].sum()
#查看具体每天各个党派收到的政治献金总数contb_receipt_amt
#使用groupby([多个分组参数])contb_receipt_dt
ele.groupby(['party','contb_receipt_dt'])['contb_receipt_amt'].sum()
#查看日期格式,并将其转换为Pandas的日期格式,通过函数加map方式进行转换
ele.dtypes
#在mysql中时间用什么格式 datetimes timestamp
#我现在要把contb_receipt_dt字段的格式转变为datetimes
def convert(x):
#字符串分割split()
day,month,year = x.split('-')
mon = months[month]
return '20'+year+'-'+str(mon)+'-'+day
#使用map函数
ele['contb_receipt_dt'] = ele['contb_receipt_dt'].map(convert)
ele.head()
#查看是否转换成功
ele.dtypes
#时间字段的数据格式没有转变
#将时间转换为时间数据类型
#根据时间进行排序
#pd.to_datetime(某一列) 将其它类型转变为时间类型
ele['contb_receipt_dt'] = pd.to_datetime(ele['contb_receipt_dt'])
ele
#得到转换后的,每天各政党所收政治献金数目。
#考察知识点:groupby(多个字段)
ele.groupby(['party','contb_receipt_dt'])['contb_receipt_amt'].sum()
#【知识点】使用unstack()将上面所得数据中的party从一级索引变成列索引,
#unstack('party')
ele.unstack('party')
#使用上面获取的数据
#画出各党派累计政治献金,cumsum()累加函数
#把时间作为行索引,党派作为行来观察
ele.columns
ele.set_index('contb_receipt_dt',inplace=True)
ele2 = ele.groupby(['cand_nm','contbr_occupation'])['contb_receipt_amt'].sum()
#将分布情况显示成DataFrmae
ele2.unstack
ele3 = ele2.unstack(level=0,fill_value=0)
ele3
#查看老兵主要支持谁:DISABLED VETERAN
#考察Series索引
ele3.loc['DISABLED VETERAN']
#把行索引变成列,Series.reset_index()
#找出各个候选人的捐赠者中,捐赠金额最大的人的职业以及捐献额
#通过query("查询条件来查找捐献人职业")
ele.columns
#找到捐赠金额最大的人 contbr_occupation
ele.groupby(['cand_nm'])['contb_receipt_amt'].max()
ele.query("cand_nm == 'Obama, Barack' & contb_receipt_amt == 1944042.43")
#处理音频 图片
#波 正弦波
#山峦
#符合 频域 时域 超弦
#傅里叶变换就是把 时域的东西变成频域
原图片:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eszVjnQt-1592462080582)(…/…/python%E7%AC%AC%E5%9B%9B%E9%98%B6%E6%AE%B5/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E5%9B%BE%E7%89%87/%E5%82%85%E9%87%8C%E5%8F%B6%E5%8F%98%E6%8D%A2%E5%8E%9F%E5%9B%BEpng)]
#傅里叶把图片变模糊,显示它的轮廓 噪音
#007 窃听->在菜市场
import numpy as np
import matplotlib.pyplot as plt
from numpy.fft import fft,ifft
#读取图片
cat = plt.imread('cat.jpg').copy()
#转换为频率
cat_fft = fft(cat)
#条件判断,将傅里叶数变为正数
cond = abs(cat_fft)<1e2
#将其赋值为0,也就是筛选出来的值将其转变为黑色
cat_fft[cond] = 0
#将傅里叶数转换回来
cat_ifft = ifft(cat_fft)
#去除虚数部分
cat_ = np.real(cat_ifft)
#显示图片
plt.imshow(cat_)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GNNGm7Oz-1592462080584)(…/…/python%E7%AC%AC%E5%9B%9B%E9%98%B6%E6%AE%B5/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E5%9B%BE%E7%89%87/%E5%82%85%E9%87%8C%E5%8F%B6%E5%8F%98%E6%8D%A2%E4%B9%8B%E5%90%8Epng)]
import numpy as np
import matplotlib.pyplot as plt
from scipy.fftpack import fft2,ifft2
from PIL import Image
#画布放大
plt.figure(figsize=(18,10))
#1.先引入图片
moon = plt.imread('./moonlanding.png')
plt.imshow(moon)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gAic7JhO-1592462080585)(数据分析图片/登月原图png)]
#2.进行傅里叶变换
moon_fft2 = fft2(moon)
#3.消除噪点
cond = np.abs(moon_fft2) > 1e4
moon_fft2[cond] = 0
#3.将频率变换回去
moon_ifft2 = ifft2(moon_fft2)
moon_ifft2
#4.去除虚数
res = np.real(moon_ifft2)
res
#5.显示效果
plt.figure(figsize=(18,10))
plt.imshow(res,cmap='gray')
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K0bNDvJL-1592462080585)(数据分析图片/登月傅里叶消噪png)]
#把PIL的图片数据和ndarray变的相同
#将PIL类型的数据转变为ndarray
moon1 = Image.open('./moonlanding.png')
#PIL图片属性
type(moon)
moon.shape
type(moon1)
moon1.tobytes()
#开始转换 变成jpg
moon1_ = np.fromstring(moon1.tobytes(),np.uint8).reshape(474,630)
#将jpg转变为png
moon1_ = moon1_/255
moon1_
plt.figure(figsize=(18,10))
plt.imshow(moon1_,cmap='gray')
#把ndarray怎么变成PIL?
#PIL格式的图片先变成二进制的,后转成图片
#把moon转变为jpg
moon_ = (moon*255).astype(np.uint8)
moon_ = moon.ravel()
moon.shape[::-1]
#要把PIL类型转变成ndarray需要shiyong numpy
#要把ndarray转成成PIL 需要使用PIL.image.frombytes()
#frombytes() 第一个参数mode指的是图片的显示方式, RGB RGBA
#第二个参数size 表达式是图片的大小 ,和ndarray表示方式相反,第一个是x轴的数字,第二个是y轴的数值
Image.frombytes(mode='RGBA',size=moon.shape[::-1],data=moon_)
scipy是基于numpy的
import numpy as np
import matplotlib.pyplot as plt
import scipy.integrate as integrate #积分呢运算模块
#画个圆
# x^2+y^2=r^2
#y = (r^2 - x^2)^0.5
X = np.linspace(-1,1,100) #半径是已知的条件
y = (1 - X**2)**0.5
#把图片改为正方形
plt.figure(figsize=(4,4))
plt.plot(X,y)
plt.plot(X,-y)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UU3NEEbB-1592462080586)(数据分析图片/画圆png)]
使用scipy.integrate进行积分,调用quad()方法,求圆周率
#func代表的是要进行积分求解的函数,a和b是已知数的取值范围
fx = lambda x : (1 - x**2)**0.5
#当前x不知道是多少吧,可以用a和b来定义 a=-1 b=1
pi_,basic_ = integrate.quad(fx,-1,1)
#返回的是半圆的数据,第一个值是半圆的圆周率,第二个值是计算偏差
print('计算得到的圆周率是:%s,误差是%s'%(pi_*2,basic_*2))
#计算得到的圆周率是:3.141592653589797,误差是2.000471344132393e-09
#傅里叶变换消噪获取最后的图片数据
from scipy.fftpack import fft2,ifft2
moon = plt.imread('./moonlanding.png')
moon_fft2 = fft2(moon)
cond = np.abs(moon_fft2) > 1e4
moon_fft2[cond] = 0
moon_ifft2 = ifft2(moon_fft2)
res = np.real(moon_ifft2)
import scipy.io as io
#输出,也就是将数据保存 .mat数据是数据分析中常用的一种数据格式
#mdict 被保存的数据必须是一个字典类型的 res是一个ndarray类型
io.savemat('./moon_clear.mat',{'moon':res})
#输入,将数据导入进来
io.loadmat('./moon_clear.mat')['moon']
import cv2
cv2.imread('./moonlanding.png')
#cv2读取到的图片BGR
#cv2.resize()改变图片大小
plt.imshow(cv2.resize(moon,(520,400)),cmap='gray')
(1)图片读取、保存
#misc 各式各样,这个库种种什么样的函数都有,乱七八糟
#读写图片使用scipy中misc.imread()/imsave()
import scipy.misc as misc
#读取图片
misc.imread('./moonlanding.png')
#保存图片
misc.imsave('./666.jpg',_6)
(2)图片旋转 、改变大小 、滤波
imrotate、imresize、imfilter 旋转 改变大小 滤波
#图片的旋转
plt.imshow(misc.imrotate(moon,60),cmap='gray')
#改变图片的大小
#int 100
moon_r = misc.imresize(moon,50)
#把被压缩的数据给保存成图片
misc.imsave('moon_r.png',moon_r)
plt.imshow(moon_r,cmap='gray')
#上传图片,qq的头像,某些网站的头像,像素越高,占用的磁盘的越大,在http协议中传输的就越慢,get请求生成的缓存就越大
#头像类的图片在上传以后,一般都会在生成一个缩略图
#0.5表示压缩成原来的50%
plt.imshow(misc.imresize(moon,0.5),cmap='gray')
#图片过滤
cat = plt.imread('./cat.jpg').copy()
plt.imshow(cat)
# 'blur', 'contour', 'detail', 'edge_enhance', 'edge_enhance_more',
# 模糊 轮廓 细节 边缘_增强 边缘_增强_更多
# 'emboss', 'find_edges', 'smooth', 'smooth_more', 'sharpen'.
# 浮雕 发现边缘 平滑 平滑的更多 锐化
#模糊的(也就是将上面参数填写到方法中)
plt.imshow(misc.imfilter(cat,'blur'))
使用scipy.misc.face(gray=True)获取图片,
使用ndimage移动坐标、旋转图片、切割图片、缩放图片导包,读取图片显示图片
import scipy.ndimage as ndimage
face=misc.face(gray=True)
plt.imshow(face,cmap='gray')
#input 表示的是数组
#shift 表示的是移动坐标的值,黑白图片是二维的,只有两个值
#'constant', 'nearest', 'reflect', 'mirror' or 'wrap'
# 平常的 相近的 反射 镜子 包裹
plt.imshow(ndimage.shift(face,[100,0],mode='nearest'),cmap='gray')、
#彩图(重点注意三维规律)
face_ = misc.face()
plt.imshow(face_)
#移动坐标
plt.imshow(ndimage.shift(face_,[768,1024,4],mode='mirror'))
#misc.imresize 50
#如果是一个int,那就将图片放大几倍
#(0.5,0.8) 将y压缩50% 将x压缩80%
#misc.imresize() cv2.resize()
plt.imshow(ndimage.zoom(face,(0.5,0.5)),cmap='gray')
#zoom进行压缩彩图
#不管压缩什么维度,只要图片颜色都不能压缩,参数写1,表示不变
plt.imshow(ndimage.zoom(face_,(0.5,0.5,1)))
gaussian_filter
np.random.randn(face.shape[0],face.shape[1]) * face.std()
#给face中添加一些噪点
face_blur = face + np.random.randn(face.shape[0],face.shape[1]) * face.std()
plt.imshow(face_blur,cmap='gray')
#使用高斯滤波进行过滤
#同时打印三张图片 原图片 模糊以后的图片 打印高斯滤波过滤的图片
#先定义图片的尺寸
plt.figure(figsize=(18,12))
#subplot() 第一个值代表几行 第二个值代表几列 第三个值代表图片的编号,默认从1开始,每张图片的编号不能重复
#显示原图片
axes = plt.subplot(1,3,1)
axes.imshow(face,cmap='gray')
#显示噪点处理图片
axes = plt.subplot(132)
axes.imshow(face_blur,cmap='gray')
#高斯滤波过滤以后的图片
axes = plt.subplot(133)
axes.imshow(ndimage.gaussian_filter(face_blur,1),cmap='gray')
中值滤波参数size:给出在每个元素上从输入数组中取出的形状位置,定义过滤器功能的输入:median_filter
#使用高斯滤波进行过滤
#同时打印三张图片 原图片 模糊以后的图片 打印高斯滤波过滤的图片
#先定义图片的尺寸
plt.figure(figsize=(18,12))
#subplot() 第一个值代表几行 第二个值代表几列 第三个值代表图片的编号,默认从1开始,每张图片的编号不能重复
axes = plt.subplot(1,3,1)
axes.imshow(face,cmap='gray')
axes = plt.subplot(132)
axes.imshow(face_blur,cmap='gray')
axes = plt.subplot(133)
#中值滤波过滤以后的图片
#size是过滤选择的像素个数
axes.imshow(ndimage.median_filter(face_blur,size=4),cmap='gray')
signal维纳滤波mysize:滤镜尺寸的标量
import scipy.signal as signal
plt.figure(figsize=(18,12))
# subplot第一参数的第一个值 代表几行 第二个值代表几列
# 第三个值代表图片的编号 默认从1开始 每张图片的编号不能重复
axes = plt.subplot(1,3,1)
axes.imshow(face,cmap='gray')
axes = plt.subplot(1,3,2)
axes.imshow(face_blur,cmap='gray')
axes = plt.subplot(1,3,3)
axes.imshow(signal.wiener(face_blur,5),cmap='gray')
moon=plt.imread('./moonlanding.png')
moon_gaus = ndimage.gaussian_filter(moon,2)
plt.figure(figsize=(12,9))
plt.imshow(moon_gaus,cmap='gray')
import PIL.Image as Image
import PIL.ImageFilter as ImageFilter
plt.imshow(cat)
_1,_2 = np.split(cat,[int(cat.shape[1]/2)],axis=1)
#data应当是一维数据
#PIL.Image.Image的shape是与ndarray的shape的长宽相反
_2.shape[::-1]
cat_r = Image.frombytes(mode='RGB',size=(365,456),data=_2.ravel())
#开始高斯模糊
cat_r_blur = cat_r.filter(ImageFilter.GaussianBlur(radius=10))
#转换成ndarray类型
_res = np.fromstring(cat_r_blur.tobytes(),np.uint8).reshape(_2.shape)
#将左右两张图片进行级联
result = np.concatenate([_1,_res],axis=1)
result.shape
#显示(可做保存)
plt.imshow(result)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vZyqO3hS-1592462080588)(数据分析图片/高斯半模糊 png)]
import PIL.Image as Image
import PIL.ImageFilter as ImageFilter
#高斯模糊只能处理PIL类型的数据
c = Image.open('./cat.jpg')
type(c)
c.filter(ImageFilter.GaussianBlur(radius=10))
数据分析第7天的学习内容(主要画图)
- 一、【重点】Matplotlib基础知识
- 二、设置plot的风格和样式
- 1、【重点】点和线的样式
- 2、X、Y轴坐标刻度
- 三、2D图形
- 1、示例
- 2、【重点】直方图
- 3、【重点】条形图
- 4、【重点】饼图
- 5、【重点】散点图
=============以上为重点=================
以下自学
- 四、图形内的文字、注释、箭头
- 1、图形内的文字
- 2、注释
- 3、箭头
- 五、3D图
- 1、曲面图
Matplotlib中的基本图表包括的元素
x轴和y轴
水平和垂直的轴线
x轴和y轴刻度
刻度标示坐标轴的分隔,包括最小刻度和最大刻度
x轴和y轴刻度标签
表示特定坐标轴的值
绘图区域
实际绘图的区域
import numpy as np
import matplotlib.pyplot as plt
#线性图是二维,x轴和y轴
#正弦波
x = np.linspace(-5,5,100)
y = np.sin(x)
plt.plot(x,y)
1、可以使用多个plot函数(推荐),在一个图中绘制多个曲线
x = np.linspace(-5,5,100)
y = np.sin(x)
y2 = np.cos(x)
plt.plot(x,y)
plt.plot(x,y2)
#如果在一个plot中画多条曲线,那么数据必须成对出现
plt.plot(x,y,x,y2)
x = np.linspace(-5,5,100)
y = np.sin(x)
y2 = np.cos(x)
plt.plot(x,y,x,y2)
plt.grid()
设置grid参数(参数与plot函数相同),使用plt面向对象的方法,创建多个子图显示不同网格线
lw代表linewidth,线的粗细
alpha表示线的明暗程度
color代表颜色
#绘制三张图
#第一张图 是xy都有网格线 第二张图 x轴有网格线 第三张图 y轴有网格线
plt.figure(figsize=(3*4,4))
axes= plt.subplot(1,3,1)
axes.plot(x,y)
axes.grid(color='pink')
#x走的网格线在横向柱状图的时候经常用到
axes= plt.subplot(132)
axes.plot(x,y)
axes.grid(color='orange',linestyle='--',axis='x')
#y轴的网格线在画柱状图的时候很有效果
axes= plt.subplot(133)
axes.plot(x,y)
axes.grid(color='green',ls='-.',axis='y')
plt.axis() 修改界限
plt.plot(x,y,x,y2)
#plt.axis('off') #取消刻度
#plt.axis([-5,5,-2,3]) #自定义刻度轴,值是一个序列类型的,数值必须要成对出现
#plt.axis('equal') #画员的时候很有用
#plt.axis('image') #压缩图片,将空白区域全部取出
#plt.axis('scaled') #压缩图片,将空白区域全部取出
#plt.axis('normal') #标准的
plt.axis('auto') #自动的
#圆形
X = np.linspace(-1,1,100)
f = lambda x : (1 - X**2)**0.5
plt.plot(X,f(X),X,-f(X))
plt.axis('equal')
plt.xlabel() plt.ylabel()
X = np.linspace(-1,1,100)
f = lambda x : (1 - X**2)**0.5
plt.plot(X,f(X),X,-f(X))
plt.axis('equal')
#自定义x和y走的刻度
plt.xlim([-3,2])
plt.ylim([-3,2])
#给可独奏设置标题
plt.xlabel('X',fontsize=30,color='red')
#rotation 旋转 值是整数型 代表旋转多少角度
plt.ylabel('f(X) = (1-X^2)^0.5',fontsize=20,color='orange',rotation=90)
plt.xlim() plt.ylim()
title() set_title()
X = np.linspace(-1,1,100)
f = lambda x : (1 - X**2)**0.5
plt.plot(X,f(X),X,-f(X))
plt.axis('equal')
#自定义x和y走的刻度
plt.xlim([-3,2])
plt.ylim([-3,2])
#给可独奏设置标题
plt.xlabel('X',fontsize=30,color='red')
#rotation 旋转 值是整数型 代表旋转多少角度
plt.ylabel('f(X) = (1-X^2)^0.5',fontsize=20,color='orange',rotation=90)
#设置图片的标题
plt.title('this is circle',fontsize=40,color='cyan',rotation=10)
两种传参方法:
【推荐使用】在plot函数中增加abel参数
在legend方法中传入字符串列表
x = np.linspace(-np.pi,np.e,100)
y = np.sin(x)
y2 = np.cos(x)
plt.plot(x,y,x,y2)
#legend 传入的值是一个列表 ,列表中第一个值是x轴的图例,第二个值是y轴的图例
plt.legend(['sin(x)','cos(x)'])
label是plot()的属性,label是标签的意思,在plt中代表图例的名称
定义label以后,不调用legend()图例依然不会显示
plt.plot(x,y,label='sin(x)')
plt.plot(x,y2,label='cos(x)')
plt.legend(loc=0)
plot中,label的值前面加上一个下划线就不显示,表示隐藏:
plt.plot(x,y2,_label='cos(x)')
loc参数:
loc 是控制图例的位置的
best 是最好的位置
default :upper right 右上角
字符串 | 数值 | 字符串 | 数值 |
---|---|---|---|
best | 0 | center left | 6 |
upper right | 1 | center right | 7 |
upper left | 2 | lower center | 8 |
lower left | 3 | upper center | 9 |
lower right | 4 | center | 10 |
right | 5 |
loc参数可以是序列类型,表示图例左下角的坐标:
plt.legend(loc=[0.4,1])
loc 序列中写int类型对应的是图片的尺寸比例
ncol参数:
plt.legend(loc=[0,1],ncol=4)
loc 序列中写int类型对应的是图片的尺寸比例,ncol表示一列几个图例
figure.savefig的选项
x = np.linspace(-4,4,100)
y = np.sin(x)
y2 = np.cos(x)
#画三条线
plt.plot(x,y,label='sin(x)',linestyle='-.',color='pink')
plt.plot(x,y2,label='cos(x)',linestyle=':',color='#FF0000',linewidth=10)
plt.plot(x,y*2+y2/2,label='complex',marker='o')
plt.legend()
#保存图片
plt.savefig('./fig.png',dpi=100,facecolor='orange')
参数color或c,图形中线段颜色
plt.plot(x,y,color='r',c='c')
#全字母参数的优先级更加高
色值的方式:
别名
合法的HTML颜色名
颜色 | 别名 | HTML颜色名 | 颜色 | 别名 | HTML颜色名 |
---|---|---|---|---|---|
蓝色 | b | blue | 绿色 | g | green |
红色 | r | red | 黄色 | y | yellow |
青色 | c | cyan | 黑色 | k | black |
洋红色 | m | magenta | 白色 | w | white |
HTML十六进制字符串
归一化到[0, 1]的RGB元组
alpha参数
plt.plot(x,y,color='cyan',alpha=0.1)
#其中的最后的0.5指的是透明度
plt.plot(x,y,color=(0.0001,0.9999,0.5555,0.5))
设置背景色,通过plt.subplot()方法传入facecolor参数,来设置坐标轴的背景色
#subplot()是画布的对象
axes=plt.subplot(facecolor='k')
axes.plot(x,y,color=(0.0001,0.9999,0.5555),linewidth=50)
参数linestyle或ls
线条风格 | 描述 | 线条风格 | 描述 |
---|---|---|---|
‘-’ | 实线 | ‘:’ | 虚线 |
‘–’ | 破折线 | ‘steps’ | 阶梯线 |
‘-.’ | 点划线 | ‘None’ / ‘,’ | 什么都不画 |
x = np.linspace(-np.e,np.e,10)
y = np.sin(x)
y2 = np.cos(x)
axes=plt.subplot(facecolor='k')
axes.plot(x,y2,color=(0.0001,0.9999,0.5555),linewidth=10,ls=':')
linewidth或lw参数
axes=plt.subplot(facecolor='k')
axes.plot(x,y2,color=(0.0001,0.9999,0.5555),lw=5,ls='steps')
axes=plt.subplot(facecolor='k')
axes.plot(x,y2,color=(0.0001,0.9999,0.5555),linewidth=2,ls='-.',dashes=[10,5,2,8])
#dashes将虚线线段范围四段,比例是10:5:2:8
marker参数
标记 | 描述 | 标记 | 描述 |
---|---|---|---|
‘1’ | 一角朝下的三脚架 | ‘3’ | 一角朝左的三脚架 |
‘2’ | 一角朝上的三脚架 | ‘4’ | 一角朝右的三脚架 |
plt.figure(figsize=(12,6))
x = np.linspace(-np.pi,np.pi,100)
y = np.sin(x)
axes=plt.subplot(facecolor='k')
#markersize
axes.plot(x,y,color=(0.0001,0.9999,0.5555),marker=1,markersize=150)
标记 | 描述 | 标记 | 描述 |
---|---|---|---|
‘s’ | 正方形 | ‘p’ | 五边形 |
‘h’ | 六边形1 | ‘H’ | 六边形2 |
‘8’ | 八边形 |
plt.figure(figsize=(12,6))
x = np.linspace(-np.pi,np.pi,7)
y = np.sin(x)
axes=plt.subplot(facecolor='k')
#markersize
axes.plot(x,y,color=(0.0001,0.9999,0.5555),marker='8')
标记 | 描述 | 标记 | 描述 |
---|---|---|---|
‘.’ | 点 | ‘x’ | X |
‘*’ | 星号 | ‘+’ | 加号 |
‘,’ | 像素 |
plt.figure(figsize=(12,6))
x = np.linspace(-np.pi,np.pi,7)
y = np.sin(x)
axis = plt.subplot(facecolor='k')
axis.plot(x,y,color=(0.0001,0.9999,0.5555),marker='*',markersize=20)
标记 | 描述 | 标记 | 描述 |
---|---|---|---|
‘o’ | 圆圈 | ‘D’ | 菱形 |
‘d’ | 小菱形 | ‘’,‘None’,’ ',None | 无 |
plt.figure(figsize=(12,6))
x = np.linspace(-np.pi,np.pi,7)
y = np.sin(x)
axis = plt.subplot(facecolor='k')
axis.plot(x,y,color=(0.0001,0.9999,0.5555),marker='d',markersize=20)
标记 | 描述 | 标记 | 描述 |
---|---|---|---|
‘_’ | 水平线 | ‘|’ | 垂直线 |
plt.figure(figsize=(12,6))
x = np.linspace(-np.pi,np.pi,7)
y = np.sin(x)
axis = plt.subplot(facecolor='k')
axis.plot(x,y,color=(0.0001,0.9999,0.5555),marker='|',markersize=20)
标记 描述 标记 描述 ‘v’ 一角朝下的三角形 ‘<’ 一角朝左的三角形 ‘^’ 一角朝上的三角形 ‘>’ 一角朝右的三角形
颜色、点型、线型
x = np.linspace(-4,4,10)
y = np.sin(x)
y2 = np.cos(x)
plt.plot(x,y,'cD--',x,y2,'ko:')
参数 | 描述 | 参数 | 描述 |
---|---|---|---|
color或c | 线的颜色 | linestyle或ls | 线型 |
linewidth或lw | 线宽 | marker | 点型 |
markeredgecolor | 点边缘的颜色 | markeredgewidth | 点边缘的宽度 |
markerfacecolor | 点内部的颜色 | markersize | 点的大小 |
x = np.linspace(0,10,10)
y = x
plt.plot(x,y,c='r',ls='--',marker='o',markersize=10,markeredgecolor='g',markeredgewidth=3)
plt.savefig('line.png',dpi=100)
属性名声明
plt.plot(x1, y1, x2, y2, fmt, …)
x = np.linspace(-5,5,100)
y = np.sin(x)
y2 = np.cos(x)
plt.plot(x,y,x,y2,c='r',ls='--')
多个都进行设置时,无需声明属性 plt.plot(x1, y1, fmt1, x2, y2, fmt2, …)
plt.plot(x,y,'b+--',x,y2,'ro:')
line1,line2 = plt.plot(x,y,x,y2)
line1.set_color('r')
line1.set_linestyle('--')
line1.set_marker('D')
或者:使用plt.setp()方法
line1,line2 = plt.plot(x,y,x,y2)
plt.setp(line1,c='r',ls='--',marker='d')
xticks()和yticks()方法
x = np.arange(10)
y = np.sin(x)
plt.plot(x,y)
#xticks 第一个参数,代表是我们刻度轴的原来的数字,第二个参数是需要做映射的字符列表
plt.xticks(np.arange(10),list('abcdefghij'),fontsize=20,color='r',rotation=60)
#正弦波 min 0 max
plt.yticks([-1,0,1],['min',0,'max'],size=20,color='orange',rotation=30)
plt.savefig('sin(x).pdf')
面向对象方法
set_xticks、set_yticks、set_xticklabels、set_yticklabels方法
#刻度是不是线条可以控制的范围
axes = plt.subplot()
line = plt.plot(x,y)
plt.setp(line,c='r')
axes.set_xticks(np.arange(10))
axes.set_xticklabels(list('abcdefghij'),color='green',size=20,rotation=20)
12.正弦余弦(π)
LaTex语法,用ππ等表达式在图表上写上希腊字母
x = np.linspace(-np.pi,np.pi,100)
y = np.sin(x)
y2 = np.cos(x)
axes = plt.subplot()
plt.plot(x,y,x,y2)
pi = np.pi
axes.set_xticks([-pi,-pi/2,0,pi/2,pi])
#plt的实体标签 $\pi$
axes.set_xticklabels(['-$\pi$','-$\pi$/2',0,'$\pi$/2','$\pi$'],size=20)
众所周知,电影可以按照题材分类,然而题材本身是如何定义的?由谁来判定某部电影属于哪 个题材?也就是说同一题材的电影具有哪些公共特征?这些都是在进行电影分类时必须要考虑的问 题。没有哪个电影人会说自己制作的电影和以前的某部电影类似,但我们确实知道每部电影在风格 上的确有可能会和同题材的电影相近。那么动作片具有哪些共有特征,使得动作片之间非常类似, 而与爱情片存在着明显的差别呢?动作片中也会存在接吻镜头,爱情片中也会存在打斗场景,我们 不能单纯依靠是否存在打斗或者亲吻来判断影片的类型。但是爱情片中的亲吻镜头更多,动作片中 的打斗场景也更频繁,基于此类场景在某部电影中出现的次数可以用来进行电影分类。
简单地说,K-近邻算法采用测量不同特征值之间的距离方法进行分类。
存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据
与所属分类的对应关系。输人没有标签的新数据后,将新数据的每个特征与样本集中数据对应的
特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。一般来说,我们
只选择样本数据集中前K个最相似的数据,这就是K-近邻算法中K的出处,通常*K是不大于20的整数。
最后 ,选择K个最相似数据中出现次数最多的分类,作为新数据的分类*。
knn = KNeighborsClassifier() #将knn算法实例化
knn.fit(X_train,y_train) #将数据训练,返回的是算法的模型
y_ = knn.predict(X_test)#进行数据的预测
knn.score(X_train,y_train)#模型的评估,对于分类算法来说,就是给模型打分
knn.score(X_test,y_test)#给测评结果打分
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
moive = pd.read_excel('./tests.xlsx',sheet_name=1)
moive
电影名称 | 武打镜头 | 接吻镜头 | 分类情况 | |
---|---|---|---|---|
0 | 大话西游 | 36 | 1 | 动作片 |
1 | 杀破狼 | 43 | 2 | 动作片 |
2 | 前任3 | 0 | 10 | 爱情片 |
3 | 战狼2 | 59 | 1 | 动作片 |
4 | 泰坦尼克号 | 1 | 15 | 爱情片 |
5 | 星语心愿 | 2 | 19 | 爱情片 |
#1.数据的预处理
#X_train这个变量在机器学习中代表训练数据,特征数据是二维的
X_train = moive.iloc[:,1:-1]
#y_train代表的是训练数据的目标值,目标值都是一维的
y_train = moive['分类情况']
display(X_train,y_train)
武打镜头 | 接吻镜头 | |
---|---|---|
0 | 36 | 1 |
1 | 43 | 2 |
2 | 0 | 10 |
3 | 59 | 1 |
4 | 1 | 15 |
5 | 2 | 19 |
#0 动作片
#1 动作片
#2 爱情片
#3 动作片
#4 爱情片
#5 爱情片
#Name: 分类情况, dtype: object
#2.模型的建立
from sklearn.neighbors import KNeighborsClassifier #分类器
#n_neighbors=5 默认计算最近的五个数据,属于哪一类最多,它就是哪一类
knn = KNeighborsClassifier() #将knn算法实例化
#对数据进行训练
knn.fit(X_train,y_train) #将数据训练,返回的是算法的模型
#3.对模型进行评估和预测
#首先我们需要数据集,我们自己先创建数据集
new_moive = DataFrame(np.array([['千星之城',50,10],['邪不压正',30,2],['僵尸先生',100,2],['咒怨',0,0]]),
columns=['电影名称','武打镜头','接吻镜头'])
new_moive #预测数据
X_test = new_moive.iloc[:,1:]
X_test
#进行数据的预测
y_ = knn.predict(X_test)
y_#显示预测结果 array(['动作片', '动作片', '动作片', '爱情片'], dtype=object)
#模型的评估,对于分类算法来说,就是给模型打分
knn.score(X_train,y_train)
#给预测数据定义目标值
y_test=np.array(['动作片', '动作片', '动作片', '惊悚片'])
#为什么评估的时候要打分两次?
#给训练数据可以观测到数据的拟合性,给预测数据打分可以得到当前模型的泛化性
knn.score(X_test,y_test)
练习 人类动作识别 步行,上楼,下楼,坐着,站立和躺着
人类动作识别
步行,上楼,下楼,坐着,站立和躺着
数据采集每个人在腰部穿着智能手机,进行了六个活动(步行,上楼,下楼,坐着,站立和躺着)。采用嵌入式加速度计和陀螺仪,以50Hz的恒定速度捕获3轴线性加速度和3轴(3维空间的XYZ轴)角速度(时间转一圈多少时间),来获取数据
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
label = {1:'walking',2:'upstairs',3:'downstairs',4:'siting',5:'standing',6:'lying'}
我们导入几个包x_test.npy x_train.npy y_test.npy y_train.npy ,这些都是numpy保存的数据
#导入数据集
X_train = np.load('./knn_test/x_train.npy')
y_train = np.load('./knn_test/y_train.npy')
X_test = np.load('./knn_test/x_test.npy')
y_test = np.load('./knn_test/y_test.npy')
#分类 频率
knn = KNeighborsClassifier()
knn.fit(X_train,y_train)
#测试
y_ = knn.predict(X_test)
y_
#评分
knn.score(X_train,y_train)
knn.score(X_test,y_test)
#将6种动作的图片通过plt绘制线性图,每个动作随即取自取一个样本,所有的图一起打印
#一共2行,每行3张图片 每张图片的大小为6*6
plt.figure(figsize=(3*6,2*6))
for i in range(6):
#编号
axes = plt.subplot(2,3,i+1)
#执行随即抽样 np,argwhere()
nd_index = np.argwhere(y_test == i+1).ravel()
#随即获取一个样 只能random
index = nd_index[np.random.randint(0,nd_index.size,1)[0]]
axes.plot(X_test[index])
#添加标题
axes.set_title(label[i+1])
#标题更换为真实的值和预测
#y_test y_
axes.set_title('True:%s\nPredict:%s'%(label[y_test[index]],label[y_[index]]))
图片略
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
zero = plt.imread('./knn_num_data/0/0_1.bmp')
plt.imshow(zero,cmap='gray')
zero.shape
path = './knn_num_data/%d/%d_%d.bmp'
#首先引入所有的数据集
#使用循环
data = []
target = []
for i in range(10):
for j in range(500):
im_data = plt.imread(path%(i,i,j+1))
data.append(im_data)
target.append(i)
data = np.array(data)
data.shape
#机器学习的数据必须是二维的
data_ = data.reshape(5000,-1)
data_.shape#(5000, 28*28)
len(target)
#分割数据
X_train,X_test,y_train,y_test = train_test_split(data_,target,test_size=0.01)
#1.建立模型
knn = KNeighborsClassifier()
knn.fit(X_train,y_train)
#2.评估和预测
knn.score(X_train,y_train)
#进行预测
y_ = knn.predict(X_test)
knn.score(X_test,y_test)
#将刚才的50张预测全部打印 设置标题,写一个真实的值,写一个预测的值 ,看出那些数字的写法容易让分类识别错误
#图片的大小为3*3的 10行 5列
plt.figure(figsize=(3*5,4*10))
for i in range(50):
#图片的编号已经显示方式
axes = plt.subplot(10,5,i+1)
#打印图片
axes.imshow(X_test[i].reshape(28,28))
#取消刻度
axes.axis('off')
#设置标题
axes.set_title('True:%s\nPredict:%s'%(y_test[i],y_[i]))
图片略
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import KNeighborsClassifier
import sklearn.datasets as datasets
data = datasets.load_iris()['data']
target = datasets.load_iris()['target']
#画一个散点图
data_ = data[:,:2] #花萼的散点图
plt.scatter(data_[:,0],data_[:,1],c=target,cmap='cool')
petal = data[:,2:]#花瓣的散点图
plt.scatter(petal[:,0],petal[:,1],c=target)
给分类线制造一些数据
生成40000点,用点把整个画布全部覆盖,然后将这些点进行机器学习,最终会得到预测值,根据预测结果画图
x = np.linspace(4,8.2,200)
y = np.linspace(1.8,4.5,200)
#绘制网格线
xx,yy = np.meshgrid(x,y)
#将xx,yy的数据合并成点 np.c_[]:将两个一维的数据合并成一个两维的数据
X_test = np.c_[xx.ravel(),yy.reshape(-1)]
X_test
#建立knn的模型
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(data_,target)
#进行预测取结果
y_ = knn.predict(X_test)
plt.scatter(X_test[:,0],X_test[:,1],c=y_)
plt.scatter(data_[:,0],data_[:,1],c=target,cmap='cool')
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JVXGhW7V-1592462080590)(数据分析图片/边界散点图.png)]
特征工程就是将原始的数据转换为更好地代表预测模型的潜在问题的特征过程,从而提高对未知数据的预测准确率(增加了模型的泛化能力)
比如资讯APP要对文章进行分类,那么直接把文章拿过去学习,那机器怎么能认识了。我们可以将文字映射成数字,然后提取关键的字,提高分类的准确性
直接影响预测的结果
from sklearn.feature_extraction import DictVectorizer
def dictvec():
#sparse 稀松矩阵 大部分是0 小部分数据位置是其他值
dict_ = DictVectorizer(sparse=False)
data = [
{'city':'北京','temperature':100},
{'city':'上海','temperature':60},
{'city':'深圳','temperature':40},
]
#处理数据
data_=dict_.fit_transform(data)
print(data_)
print(dict_.transform(data))
#反转数据用什么类型值
print(dict_.inverse_transform(data_))
#返回特征值名称
print(dict_.get_feature_names())
dictvec()
词频=某一个词语在文章中出现的次数
from sklearn.feature_extraction.text import CountVectorizer
def countvec():
cv_= CountVectorizer()
data=['life is short small,use python','life is is long,not need python']
#处理数据
res=cv_.fit_transform(data)
print(res)
#返回特征值名称
print(cv_.get_feature_names())
#词频
print(res.toarray())
countvec()
from sklearn.feature_extraction.text import CountVectorizer
def countvec_zn():
cv_= CountVectorizer()
data=['人生苦短我做python','人生苦长不用python']
#处理数据
res=cv_.fit_transform(data)
print(res)
#返回特征值名称
print(cv_.get_feature_names())
#词频
print(res.toarray())
countvec_zn()
import jieba
def cutword():
#中文文本
con1 =jieba.cut('长得,长得,丑怎么了,我自己又看不到,恶心的是你们')
con2 =jieba.cut('时间是把杀猪刀,这句话只适用于长得好看的人')
con3 =jieba.cut('你在知乎领悟了什么?领悟到小时候不好好学习,长大了只会给被人点赞')
print(con1)
#返回一个迭代器对象
content1=list(con1)
content2=list(con2)
content3=list(con3)
print(content1)
#拼接 ‘ ’.join()
c1 = ' '.join(content1)
c2 = ' '.join(content2)
c3 = ' '.join(content3)
print(c1)
return [c1,c2,c3]
def hanzivec():
cv_=CountVectorizer()
list_=cutword()
#中文转变为词向量 单个字符的字不提示
res=cv_.fit_transform(list_)
print(res)
#获取中文分词特征
print(cv_.get_feature_names())
#转变为词向量 这是一个稀松矩阵相加的值
print(res.toarray())
hanzivec()
from sklearn.feature_extraction.text import TfidfVectorizer
def tfidfvec():
list_ = cutword()
tf = TfidfVectorizer()
#处理数据
res=tf.fit_transform(list_)
#返回特征值名称
print(1,tf.get_feature_names())
#计数
print(res.toarray())
print(res)
tfidfvec()
通过特定的统计方法(数学方法)将数据转换成算法要求的数据
import numpy as np
nd = np.array([[90,2,10,40],[60,4,15,45],[75,3,13,46]])
nd
目的:让某一列数值非常大的数值不对其它列造成过大的影响
特点:通过对原始数据进行变换把数据映射到 (默认为)0-1 之间
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EmqCvOej-1592462080592)(数据分析图片/归一化.jpg)]
注意:归一化的作用范围是每一列,max是每一列中的最大值,min是每一列中的最小值,那么X‘’为最终的结果。mx,mi分别是指定范围的值,默认mx为1,mi为0
归一化的缺点:对数据中含有异常值的处理非常不理想
归一化总结:在特定场景下最大值和最小值是变化的,另外,在最大值最小值非常容易受异常点影响,所以这种方法的鲁棒性(稳定性)较差,只适合传统精确小数据场景。
from sklearn.preprocessing import MinMaxScaler
def normal():
nd = np.array([[90,2,10,40],[60,4,15,45],[75,3,13,46]])
#实例化归一化方法(归一化数据范围)
nm=MinMaxScaler(feature_range=(0,1))
#处理数据
result=nm.fit_transform(nd)
print(result)
normal()
# 归一化 将每一列数据重要性变得相同
标准化是 是列中的每一个元素 减去 该列的平均值 除以该列的标准差 因为均值,大部分数据是正常的,只有小部分的数据是异常值。不影响数据波动 除以标准差的作用是将值压缩的更小,方差、标准差的计算也是受到均值的影响的。
特点:通过对原始数据进行变换把数据变换到均值为0,方差为1的范围内
标准化总结:在已有样本足够多的情况下比较稳定,适合现代嘈杂大数据的场景。
对于归一化来说:如果出现异常点,影响了最大值和最小值,那么结果显然会发生改变
对于标准化来说:如果出现异常点,由于具有一定的数据量,少量的异常点对于平均值得影响不大,方差的改变也比较的小
删除:如果某一列或者某一行数据缺失值的比例较大,建议放弃整行或者整列
插补:通过每行或者每列的平均值,或者中位数(中值)来填充,在特定的情况也可以补0
from sklearn.preprocessing import StandardScaler
def stand():
std_ = StandardScaler()
#创建标准化处理对象
nd = np.array([[90,2,10,40],[60,4,15,45],[75,3,13,46]])
#标准化处理数据
result = std_.fit_transform(nd)
#输出标准化处理结果
print(result)
#数据的平均值
print(std_.mean_)
#方差(标准差std_.var_**0.5)
print()
stand()
NaN就是缺失值
from sklearn.preprocessing import Imputer
import pandas as pd
def im(X):
#Imputer和pandas.fillna()只能识别NaN,不能识别其他类型特殊字符
im = Imputer(missing_values='NaN', strategy='median', axis=1)
X_ = pd.DataFrame(X)
dict_={'??':np.nan,'?':np.nan}
X_=X_.replace(dict_)
result = im.fit_transform(X_)
print(result)
nd_ = np.array([[1,2,3,4],[2,'??',3,7],[9,10,'?',0]])
im(nd_)
特征选择就是单纯地从提取到的所有特征中选择部分特征作为训练集特征在选择前和选择后可以改变值,也可以不改变值,但是在选择后的特征维度肯定要比选择之前小,毕竟我们只选择了其中的一部分特征。
特征冗余:部分特征的相关度高,容易消耗计算性能
噪音:部分特征对预测的结果会产生比较大的影响
from sklearn.feature_selection import VarianceThreshold
def var_():
#PCA在实际工作中,用的都比较少,因为可以用经验来判断
vt = VarianceThreshold()
#data = pd.DataFrame({'数学':[100,101,102,103],'语文':np.random.randint(0,100,4)})
#data['物理'] = data['数学'].map(lambda x : x*1.2)
data=np.array([[1,2,3,4],[1,3,2,4],[1,2,3,4]])
result = vt.fit_transform(data)
print(result)
var_()
PCA叫做主成分分析,主成分就是各个特征
降维,在机器学习中一列就是一个维度,降维就是减少特征数量
结构化数据 相当于mysql的表类型
半结构化数据 xml html
非结构化数据 图片 28*28
PCA对于非结构化的数据非常有用,人脸识别,图片越清晰,像素就越高,维度越多计算的越慢
9w维度降成300维度,每列之间多多少少都会有某一种关系,协方差矩阵,协方差值越高,说明关系越密切,线性代数中的正交基,基变换以后是值放大了的稀松矩阵
被pca降维以后的特征,我们认为这些特征之间的关系是独立不相关
本质:PCA是一种简化,分析数据的一种技术
目的:是数据维度数量的压缩,尽可能降低原数据的维度数量,减少重合数据的损失(维度数量越少,数据的复杂度就越低)
作用:减少特征的数量,减少特征之间的相关性,提高准确度和计算效率
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
def pca():
cat = plt.imread('./cat.jpg')
print(cat.reshape(-1).shape)
pca_ = PCA(n_components=150, copy=True, whiten=True)
#pca处理的数据应当是二维的
X_train = cat.reshape(456,-1)
print(X_train.shape)
res = pca_.fit_transform(X_train)
print(res.shape)
#降维要求所有的图片大小必须一致
#人脸识别
pca()
y(x)= ax1 + bx2 + …… + zxn + num,也就是给定训练数据X_train=(x1,x2,x3……)和正确值y_train=y(x)一一对应的值去做训练,求取x1,x2,等前面系数的值,以及num常数项的值。
使用线性回归分析糖尿病数据,不可评估
from sklearn.linear_model import LinearRegression
import sklearn.datasets as datasets
import numpy as np
#获取数据
diabetes = datasets.load_diabetes()
#age sex bmi体重 bp血压 s1-s6血清
data=diabetes['data']
target = diabetes['target']
#直接使用机器学习,直接求解系数和误差值
lrg = LinearRegression()
#一共有10列系数,每一列都会有一个系数,也就是x前面的系数
lrg.coef_
#获取偏执项,也就是常数项
lrg.intercept_
小数据、多特征。
缩减方法可以去掉不重要的参数,因此能更好地理解数据。L2范数在计算 系数的 时候 考虑的是 先接近于0 ,在慢慢增长(梯度上升)
from sklearn.linear_model import Ridge
X = np.random.randint(0,150,size=(3,5))
y = 3* X[:,0] + 5 * X[:,1] + 3 * X[:,2] + 10 * X[:,3] + 3 * X[:,4]
#实例化岭回归
#alpha=1.0 = lambda
#fit_intercept=True 默认有偏执项的
rg = Ridge(fit_intercept=False,alpha=0.01)
rg.fit(X,y)
#系数
rg.coef_
#常数项
rg.intercept_
#岭迹线 是 lambda的取值范围 也就是alpha的取值范围 使得求出的各个列的预测系数更贴近真实值。
X = 1/(np.arange(10) + np.arange(1,11).reshape(10,1))
y = np.ones(10)
#alpha先不设定
rg = Ridge(fit_intercept=False)
alphas = np.logspace(-10,0,10)
res = []
for i in alphas:
#设置岭回归的惩罚系数的值
rg.set_params(alpha=i)
rg.fit(X,y)
res.append(rg.coef_)
import matplotlib.pyplot as plt
plt.figure(figsize=(18,12))
plt.plot(alphas,res)
#修改刻度轴
plt.xscale('log')
#获取当前的画布对象
axes = plt.axes()
plt.grid()
plt.xlim(axes.get_xlim()[::-1])
根据图像分析,选取中间部分,该数据的alpha应该靠近0.001左右更适合。
小数据、少特征的数据集。
X = 1/(np.arange(10) + np.arange(1,11).reshape(10,1))
y = np.ones(10)
#罗斯回归
la = Lasso(fit_intercept=False,alpha=0.020)
la.fit(X,y)
la.coef_
from sklearn.neighbors import KNeighborsRegressor
data = np.linspace(0,10,50)
target = np.sin(data)
#添加噪音
target[::5] += np.random.randn(10) * 0.35
plt.scatter(data,target)
knn_R = KNeighborsRegressor()
knn_R.fit(data.reshape(50,1),target)
X_test = np.linspace(0,10,50)
y_test = np.sin(data)
y_ = knn_R.predict(X_test.reshape(50,1))
plt.scatter(data,target)
plt.plot(X_test,y_)
假如有一个罐子,里面有黑白两种颜色的球,数目多少不知,两种颜色的比例也不知。我 们想知道罐中白球和黑球的比例,但我们不能把罐中的球全部拿出来数。现在我们可以每次任意从已经摇匀的罐中拿一个球出来,记录球的颜色,然后把拿出来的球 再放回罐中。这个过程可以重复,我们可以用记录的球的颜色来估计罐中黑白球的比例。假如在前面的一百次重复记录中,有七十次是白球,请问罐中白球所占的比例最有可能是多少?很多人马上就有答案了:70%。而其后的理论支撑是什么呢?
我们假设罐中白球的比例是p,那么黑球的比例就是1-p。
因为每抽一个球出来,在记录颜色之后,我们把抽出的球放回了罐中并摇匀,
所以每次抽出来的球的颜 色服从同一独立分布。
这里我们把一次抽出来球的颜色称为一次抽样。题目中在一百次抽样中,
七十次是白球的概率是P(Data | M),这里Data是所有的数据,
M是所给出的模型,表示每次抽出来的球是白色的概率为p。
如果第一抽样的结果记为x1,第二抽样的结果记为x2...
那么Data = (x1,x2,…,x100)。这样,
P(Data | M)
= P(x1,x2,…,x100|M)
= P(x1|M)P(x2|M)…P(x100|M)
= p70(1-p)30.
那么p在取什么值的时候,P(Data |M)的值最大呢?将p70(1-p)30对p求导,并其等于零。
70p69(1-p)30-p70*30(1-p)29=0。
解方程可以得到p=0.7。
在边界点p=0,1,P(Data|M)=0。所以当p=0.7时,P(Data|M)的值最大。这和我们常识中按抽样中的比例来计算的结果是一样的。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegression
import sklearn.datasets as datasets
from sklearn.model_selection import train_test_split
#导入数据load_digits()
num = datasets.load_digits()
data = num['data']
target = num['target']
#显示数据
plt.figure(figsize=(0.5,0.5))
plt.imshow(data[5].reshape(8,8),cmap='gray')
#将数据切分 1797
X_train,X_test,y_train,y_test = train_test_split(data,target,test_size=0.01)
#实例化
lor = LogisticRegression() #C = 岭回归的中alpha penalty='l2' 这是正则化参数 tol=0.0001 梯度下降的精确值
#排雷 步伐 越小越好,越精确
lor.fit(X_train,y_train)
lor.score(X_train,y_train)
y_=lor.predict(X_test)
lor.score(X_test,y_test)
import numpy as np
import sklearn.datasets as datasets
#创建数据
#make_blobs 就是用来创建点的
#n_samples=100, n_features=2, centers=3 生成3类数据 返回一个元祖 第一个元素是特征值 第二个元素是目标值
#cluster_std 每个类型点的标准差,标准差越小,点越聚合
data,target = datasets.make_blobs(n_samples=102,cluster_std=1.2)
#画一个散点图
plt.scatter(data[:,0],data[:,1],c=target)
#需要很多的点铺满整个画布,再对这些点进行预测 150*200 = 3w
x = np.linspace(-1,11,200)
y = np.linspace(-13,6,150)
#meshgrid 返回全为x轴的数据 和 全为y轴的数据
xx,yy = np.meshgrid(x,y)
xy = np.concatenate([xx.ravel().reshape(-1,1),yy.ravel().reshape(-1,1)],axis=1)
#建立模型
lr_ = LogisticRegression()
lr_.fit(data,target)
#评分
lr_.score(data,target)
#数据测试
y_ = lr_.predict(xy)
#线性分类的分类线为什么平整,因为先求的线性回归
plt.scatter(xy[:,0],xy[:,1],c=y_,cmap='cool')
plt.scatter(data[:,0],data[:,1],c=target,cmap='gray')
from sklearn.datasets import load_boston
from sklearn.linear_model import LinearRegression,SGDRegressor #一个是普通的方程,一个是带有梯度下降的方程
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
#对回归进行评估 mse
from sklearn.metrics import mean_squared_error
#1.引入数据
lb = load_boston()
#一共506个样本,13列值
lb.data.shape
#2.将数据切割
X_train,X_test,y_train,y_test = train_test_split(lb.data,lb.target,test_size=0.1)
#3.将特征值标准化
std_x = StandardScaler()
X_train = std_x.fit_transform(X_train)
X_test = std_x.transform(X_test)
#将目标值标准化
std_y = StandardScaler()
y_train = std_y.fit_transform(y_train.reshape(-1,1))
y_test = std_y.transform(y_test.reshape(-1,1))
#4.建立模型 逻辑回归
lr = LinearRegression()
lr.fit(X_train,y_train)
#测试
y_lr = lr.predict(X_test)
#获取求解的系数
lr.coef_
#获取偏执值
lr.intercept_
#建立模型 使用梯度下降的方程
sgd = SGDRegressor()
sgd.fit(X_train,y_train)
#测试
y_sgd = sgd.predict(X_test)
#获取求解的系数
sgd.coef_
#获取偏执值
sgd.intercept_
import numpy as np
import pandas as pd
from pandas import DataFrame
#knn+逻辑
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
#标准化
from sklearn.preprocessing import StandardScaler
#1.引入葡萄酒的数据集
white_ = pd.read_csv('winequality-white.csv',sep=';')
white_['quality'].unique() #品质从3-9 一共7个类别
data = white_.iloc[:,:-1]
target = white_.iloc[:,-1]
#实例化标准化方法
std_ = StandardScaler()
data_ = std_.fit_transform(data)
#切割数据
X_train,X_test,y_train,y_test = train_test_split(data_,target,test_size=0.01)
#2.建立逻辑模型
lr = LogisticRegression()
lr.fit(X_train,y_train)
#3.评估和预测
lr.score(X_train,y_train)
lr.coef_.shape #7中分类 11
def convert2level(quality):
if quality <=4:
return 'low'
elif quality >= 8:
return 'high'
else:
return 'median'
#因为分类太多,准确率就会不高,怎么解决?
#答:数据分箱,实际上就是将相同的小类别合并成一个大类别
#3-9 一共7个类别 3,4 分为 low 5,6,7分为 median 8,9分为 high .map()
white_['quality'] = white_['quality'].map(convert2level)
#重新取值
data = white_.iloc[:,:-1]
target = white_.iloc[:,-1]
#重新标准化
std_ = StandardScaler()
data_ = std_.fit_transform(data)
#重新切割数据
X_train,X_test,y_train,y_test = train_test_split(data_,target,test_size=0.01)
#重新训练
lr.fit(X_train,y_train)
lr.score(X_train,y_train)
y_lr = lr.predict(X_test)
lr.score(X_test,y_test)
决策树(decision tree)是一个树结构(可以是二叉树或非二叉树)。其每个非叶节点表示一个特征属性上的测试,每个分支代表这个特征属性在某个值域上的输出,而每个叶节点存放一个类别。使用决策树进行决策的过程就是从根节点开始,测试待分类项中相应的特征属性,并按照其值选择输出分支,直到到达叶子节点,将叶子节点存放的类别作为决策结果。
不同于逻辑斯蒂回归和贝叶斯算法,决策树的构造过程不依赖领域知识,它使用属性选择度量来选择将元组最好地划分成不同的类的属性。所谓决策树的构造就是进行属性选择度量确定各个特征属性之间的拓扑结构。
构造决策树的关键步骤是分裂属性。所谓分裂属性就是在某个节点处按照某一特征属性的不同划分构造不同的分支,其目标是让各个分裂子集尽可能地“纯”。尽可能“纯”就是尽量让一个分裂子集中待分类项属于同一类别。分裂属性分为三种不同的情况:
1、属性是离散值且不要求生成二叉决策树。此时用属性的每一个划分作为一个分支。
2、属性是离散值且要求生成二叉决策树。此时使用属性划分的一个子集进行测试,按照“属于此子集”和“不属于此子集”分成两个分支。
3、属性是连续值。此时确定一个值作为分裂点split_point,按照>split_point和<=split_point生成两个分支。
构造决策树的关键性内容是进行属性选择度量,属性选择度量是一种选择分裂准则,它决定了拓扑结构及分裂点split_point的选择。
属性选择度量算法有很多,一般使用自顶向下递归分治法,并采用不回溯的贪心策略。这里介绍常用的ID3算法。
日志密度/L | 好友密度/F | 真实头像/H | 真实账户/R |
---|---|---|---|
S | S | NO | NO |
S | L | YES | YES |
L | M | YES | YES |
M | M | YES | YES |
L | M | YES | YES |
M | L | NO | YES |
M | S | NO | NO |
L | M | NO | YES |
M | S | NO | YES |
S | S | YES | NO |
表中S、M和L分别表示小、中和大。
设L、F、H和R表示日志密度、好友密度、是否使用真实头像和账号是否真实,试用ID3算法构造决策树。
import numpy as np
解:设D为10个样本集,其中决策属性(真实账户/R)有7个YES、3个NO。决策属性信息熵为:
info_D = -(0.7*np.log2(0.7)+0.3*np.log2(0.3))
#日志密度属性期望信息熵为:
#占总列 下同 对应真实账户yes/no占总个数的比例
info_L_D = -(0.3*(1/3*np.log2(1/3)+2/3*np.log2(2/3))
+0.3*(np.log2(1))+
0.4*(1/4*np.log2(1/4)+3/4*np.log2(3/4)))
#好友密度属性期望信息熵为:
info_F_D = -(0.4*(1/4*np.log2(1/4)+3/4*np.log2(3/4))
+0.4*(np.log2(1))
+0.2*(np.log2(1)))
#真实头像属性期望信息熵为:
info_H_D= - (0.5* (4/5*np.log2(4/5)
+1/5*np.log2(1/5))
+0.5*((3/5*np.log2(3/5)+2/5*np.log2(2/5))))
如果使用是id这个字段作为根,那么所有的数据都是叶子节点
C4.5算法是用于生成决策树的一种经典算法,是ID3算法的一种延伸和优化。
C4.5算法对ID3算法主要做了一下几点改进:
(1)通过信息增益率选择分裂属性,克服了ID3算法中通过信息增益倾向于选择拥有多个属性值的属性作为分裂属性的不足;
(2)能够处理离散型和连续型的属性类型,即将连续型的属性进行离散化处理;
(3)构造决策树之后进行剪枝操作;
(4)能够处理具有缺失属性值的训练数据。
分裂属性选择的评判标准是决策树算法之间的根本区别。
区别于ID3算法通过信息增益选择分裂属性,C4.5算法通过信息增益率选择分裂属性。
CART(classificationandregressiontree), 分类回归树算法,既可用于分类也可用于回归,在这一部分我们先主要将其分类树的生成。区别于ID3和C4.5,CART假设决策树是二叉树,内部节点特征的取值为“是”和“否”,左分支为取值为“是”的分支,右分支为取值为”否“的分支。这样的决策树等价于递归地二分每个特征,将输入空间(即特征空间)划分为有限个单元。CART的分类树用基尼指数来选择最优特征的最优划分点,具体过程如下 使用GINI系数作为衡量标准:
【注意】 参数max_depth越大,越容易过拟合
#预剪枝 在决策树 开始计算的之前 , 给一个深度
#后剪枝 在计算过程中,设定叶节点的数量
import numpy as np
from sklearn.datasets import load_iris
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
#GridSearchCV GridSearch网格搜索 CV交叉验证(缩写)
from sklearn.model_selection import train_test_split,GridSearchCV
#标准化 决策树不需要任何数据做数据标准化,空数据对于决策树的影响是非常非常小的。
#pydotplus 画图工具库 可以画出决策树
#tree 决策树在画图时候需要依赖tree包
import sklearn.tree as tree
from sklearn.externals.six import StringIO
import pydotplus
#加载处理数据
iris = load_iris()
data = iris['data']
target = iris['target']
#切割数据
X_train,X_test,y_train,y_test=train_test_split(data,target,test_size=0.1)
#如果 max_depth 是树的深度,层次数量太多,很容易发生 过拟合 泛化性不强
tree_ = DecisionTreeClassifier(criterion='entropy',max_depth=2)
tree_.fit(X_train,y_train)
#打印决策树
st_ = StringIO()
"""
export_graphviz()
第一个参数是 decision_tree 决策树的实例 tree_
第二个参数是 out_filt 代表使用的打印工具 st_
第三个参数是 feature_names 数据的特征 写的是数据集的原始对象 iris.feature_names,
第四个参数是 class_names 数据中分类的名字 iris.target_names,
"""
tree.export_graphviz(tree_,
out_file=st_,
feature_names=iris.feature_names,
class_names=iris.target_names,
filled=True,rounded=True)
# 调用画图工具
graph = pydotplus.graph_from_dot_data(st_.getvalue())
#输出图片
graph.write_pdf('iris.pdf')
#评估
tree_.score(X_train,y_train)
tree_.score(X_test,y_test)
多个决策树组合成森林
随机森林是混合算法
随机森林中建立五个决策树,4个将数据定为A类,1个定为B类,少数服从多数
随机森林的优点:
1、在当前的所有算法中,具有极好的准确率
2、能够在大数据的场景下有效的发挥
3、能够处理高维特征的数据,不需要降维
4、可以评估各种类型的特征
from sklearn.ensemble import RandomForestClassifier
# n_estimators 估计器=算法的模型 生成决策树的数量
rfc = RandomForestClassifier()
# estimator, 估计器的实例对象
# param_grid, 是一个字典 字典当中是参数调优的值
param = {'n_estimators':[120,200,300,500,800,1200],'max_depth':[1,2,3,4]}
gc = GridSearchCV(rfc,param_grid=param,cv=2)
gc.fit(X_train,y_train)
#返回最好的参数
gc.best_params_
#返回最好的随机模型
gc.best_estimator_
gc.best_score_
优点:
缺点:
高斯分布就是正态分布
import sklearn.datasets as datasets
from sklearn.naive_bayes import GaussianNB,MultinomialNB,BernoulliNB
from sklearn.model_selection import train_test_split
data = datasets.load_iris()['data']
target = datasets.load_iris()['target']
X_train,X_test,y_train,y_test=train_test_split(data,target,test_size=0.1)
GNB = GaussianNB()
GNB.fit(X_train,y_train)
GNB.score(X_train,y_train)
GNB.score(X_test,y_test)
适用于文本数据(特征表示的是次数,例如某个词语的出现次数)
import sklearn.datasets as datasets
from sklearn.naive_bayes import GaussianNB,MultinomialNB,BernoulliNB
from sklearn.model_selection import train_test_split
MNB = MultinomialNB()
MNB.fit(X_train,y_train)
MNB.score(X_train,y_train)
MNB.score(X_test,y_test)
【用途】适用于伯努利分布,也适用于文本数据(此时特征表示的是是否出现,例如某个词语的出现为1,不出现为0)
绝大多数情况下表现不如多项式分布,但有的时候伯努利分布表现得要比多项式分布要好,尤其是对于小数量级的文本数据
import sklearn.datasets as datasets
from sklearn.naive_bayes import GaussianNB,MultinomialNB,BernoulliNB
from sklearn.model_selection import train_test_split
BNB = BernoulliNB()
BNB.fit(X_train,y_train)
BNB.score(X_train,y_train)
BNB.score(X_test,y_test)
导包
导入sklearn.feature_extraction.text.TfidfVectorizer用于转换字符串
读取短信数据
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
sms = pd.read_csv('./day12_data/SMSSpamCollection',sep='\t',header=None)
#将目标值 和 特征值提取出来
data = sms[1]
target = sms[0]
#转成one-hot编码 稀松矩阵
tfidf = TfidfVectorizer()
text_vector = tfidf.fit_transform(data)
#5572个文本 8713个单词 一共使用74169个单词
text_vector
#获取特征名称,文本的特征就是单词
tfidf.get_feature_names()
text_vector.toarray()
#目标值array(['ham', 'ham'],
X_test = ["Did you catch the bus ? Are you frying an egg ? Did you make a tea? Are you eating your mom's left over dinner ? Do you feel my Love ? go die."
,"Thanks for your subscription to Ringtone UK your mobile will be charged £5/month Please confirm by replying YES or NO. If you reply NO you will not be charged!kill you"]
X_test = tfidf.transform(X_test)
多项式
MNB = MultinomialNB()
MNB.fit(text_vector,target)
MNB.score(text_vector,target)
MNB.predict(X_test)
伯努利
BNB = BernoulliNB()
BNB.fit(text_vector,target)
BNB.score(text_vector,target)
BNB.predict(X_test)
高斯
GNB = GaussianNB()
#高斯贝叶斯不认识稀松矩阵
GNB.fit(text_vector.toarray(),target)
GNB.score(text_vector.toarray(),target)
GNB.predict(X_test.toarray())
Support Vector Machine。支持向量机,其含义是通过支持向量运算的分类器。其中“机”的意思是机器,可以理解为分类器。 那么什么是支持向量呢?在求解的过程中,会发现只根据部分数据就可以确定分类器,这些数据称为支持向量。 见下图,在一个二维环境中,其中点R,S,G点和其它靠近中间黑线的点可以看作为支持向量,它们可以决定分类器,也就是黑线的具体参数。
解决的问题:
在训练数据中,每个数据都有n个的属性和一个二类类别标志,我们可以认为这些数据在一个n维空间里。我们的目标是找到一个n-1维的超平面(hyperplane),这个超平面可以将数据分成两部分,每部分数据都属于同一个类别。 其实这样的超平面有很多,我们要找到一个最佳的。因此,增加一个约束条件:这个超平面到每边最近数据点的距离是最大的。也成为最大间隔超平面(maximum-margin hyperplane)。这个分类器也成为最大间隔分类器(maximum-margin classifier)。 支持向量机是一个二类分类器。
SVM的一个优势是支持非线性分类。它结合使用拉格朗日乘子法和KKT条件,以及核函数可以产生非线性分类器。
SVM的目的是要找到一个线性分类的最佳超平面 f(x)=xw+b=0。求 w 和 b。
首先通过两个分类的最近点,找到f(x)的约束条件。
有了约束条件,就可以通过拉格朗日乘子法和KKT条件来求解,这时,问题变成了求拉格朗日乘子αi 和 b。
对于异常点的情况,加入松弛变量ξ来处理。
非线性分类的问题:映射到高维度、使用核函数。
线性分类及其约束条件:
SVM的解决问题的思路是找到离超平面的最近点,通过其约束条件求出最优解。
from sklearn.svm import SVC
import numpy as np
import matplotlib.pyplot as plt
nd1 = np.random.randn(20,2)-[2,2]
nd2 = np.random.randn(20,2)+[3,2]
print(nd1,'\n\n\n',nd2)
dot = np.concatenate([nd1,nd2])
dot
#给数据设置目标值
target = [0]*20 + [1]*20
target
#绘制分布图
plt.scatter(dot[:,0],dot[:,1],c=target)
#训练模型,并训练
# kernel 核函数 rbf 基于半径
svc = SVC(kernel='linear')
X_train = dot
y_train = target
svc.fit(X_train,y_train)
#获取参数
coef_=svc.coef_
b_=svc.intercept_
#提供支持向量(过线点的位置坐标)
support_vectors_ = svc.support_vectors_
plt.scatter(support_vectors_[:,0],support_vectors_[:,1],s=100,c='pink',alpha=0.8)
plt.scatter(dot[:,0],dot[:,1],c=target)
#求分界线方程系数y=wx+b
w = -(coef_[:,0]/coef_[:,1])
b = -(b_/coef_[:,1])
X = np.linspace(-6,5,100)
y=w*X+b
#划分界线
plt.scatter(support_vectors_[:,0],support_vectors_[:,1],s=100,c='pink',alpha=0.8)
plt.scatter(dot[:,0],dot[:,1],c=target)
plt.plot(X,y)
#绘制三维图形
from mpl_toolkits.mplot3d import Axes3D
x1 = X_train[:,0]
y1 = X_train[:,1]
w1= coef_[:,0]
w2= coef_[:,1]
z = w1*x1+w2*y1+b_
#绘制三维图片
fig = plt.figure(figsize=(10,10))
#实例化3d模块
axes3d = Axes3D(fig)
#绘制3d散点图
axes3d.scatter3D(x1,y1,z,c=y_train,cmap='rainbow')
#绘制超图片
axes3d.plot_surface(X,y,z.reshape(-1,1),color='pink',alpha=0.3)
#绘制过点线
#第一个点和最后一个点是肯定没有关系
support_vectors_
#获取图片上方的点
vector_up = support_vectors_[-1]
vector_down = support_vectors_[0]
#计算点到分类线之间的距离
#y = wx + b
#b = y - wx
y_up = w * X +(vector_up[1] - w*vector_up[0])
y_down = w * X +(vector_down[1] - w*vector_down[0])
plt.scatter(support_vectors_[:,0],support_vectors_[:,1],s=200,c='pink',alpha=0.5)
plt.scatter(X_train[:,0],X_train[:,1],c=y_train)
plt.plot(X,y)
plt.plot(X,y_up,X,y_down)
data = np.random.randn(300,2)
plt.scatter(data[:,0],data[:,1])
target = np.logical_xor(data[:,0]>0,data[:,1]>0)
plt.scatter(data[:,0],data[:,1],c=target)
svc = SVC()
svc.fit(data,target)
#生成测试数据
x = np.linspace(-3,3.2,200)
y = np.linspace(-3,3.2,150)
xx,yy = np.meshgrid(x,y)
xy = np.c_[xx.ravel(),yy.ravel()]
#预测
y_ = svc.predict(xy)
svc.score(data,target)
plt.scatter(xy[:,0],xy[:,1],c=y_)
plt.scatter(data[:,0],data[:,1],c=target,cmap='cool')
plt.contour(xx,yy,z.reshape(150,200))
#使用svm中自动的合成函数
z = svc.decision_function(xy)
z.shape
#第三个轴必须是二维
plt.contourf(xx,yy,z.reshape(150,200))
#svm 3d图形
fig = plt.figure(figsize=(10,10))
axes3d = Axes3D(fig)
axes3d.plot_surface(xx,yy,z.reshape(150,200),cmap='rainbow')
from sklearn.datasets import load_iris
data = load_iris()['data'][:,:2]
target = load_iris()['target']
data.shape
li_ = ['linear','poly','rbf']
model_ ={}
for i in range(len(li_)):
model_[li_[i]]=SVC(kernel=li_[i])
for i in model_:
model_[i]=model_[i].fit(data,target)
plt.scatter(data[:,0],data[:,1],c=target)
#创建预测的数据 30000
x = np.linspace(4,8.1,200)
y = np.linspace(1.9,4.5,150)
xx,yy=np.meshgrid(x,y)
xy = np.c_[xx.ravel(),yy.ravel()]
xy.shape
res={}
for i in model_:
res[i] = model_[i].predict(xy)
plt.figure(figsize=(12,10))
for i,k in enumerate(res):
axes = plt.subplot(2,2,i+1)
axes.contourf(xx,yy,res[k].reshape(150,200),cmap='cool')
axes.scatter(data[:,0],data[:,1],c=target)
from sklearn.svm import SVR
X = np.linspace(0,10,100)
y = np.sin(x)
y[::4] += np.random.randn(25)*0.35
plt.scatter(X,y)
X_test = np.linspace(0,10,200).reshape(-1,1)
li_ = ['linear','poly','rbf']
model_ = {}
for i in range(len(li_)):
model_[li_[i]] = SVR(kernel=li_[i]).fit(X.reshape(-1,1),y)
plt.figure(figsize=(12,8))
plt.scatter(X,y)
for i in res_:
plt.plot(X_test,res_[i],label=i)
plt.legend()
K-Means算法是一种聚类分析(cluster analysis)的算法,其主要是来计算数据聚集的算法,主要通过不断地取离种子点最近均值的算法。
K-Means算法主要解决的问题如下图所示。我们可以看到,在图的左边有一些点,我们用肉眼可以看出来有四个点群,但是我们怎么通过计算机程序找出这几个点群来呢?于是就出现了我们的K-Means算法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-stNZzxY6-1592462080594)(数据分析图片/k-meansgif)]
K-Means主要最重大的缺陷——都和初始值有关:
K是事先给定的,这个K值的选定是非常难以估计的。很多时候,事先并不知道给定的数据集应该分成多少个类别才最合适。(ISODATA算法通过类的自动合并和分裂,得到较为合理的类型数目K)
K-Means算法需要用初始随机种子点来搞,这个随机种子点太重要,不同的随机种子点会有得到完全不同的结果。(K-Means++算法可用来解决这个问题,其可以有效地选择初始点)
总结:K-Means算法步骤:
K-Means算法应用:
看到这里,你会说,K-Means算法看来很简单,而且好像就是在玩坐标点,没什么真实用处。而且,这个算法缺陷很多,还不如人工呢。是的,前面的例子只是玩二维坐标点,的确没什么意思。但是你想一下下面的几个问题:
1)如果不是二维的,是多维的,如5维的,那么,就只能用计算机来计算了。
2)二维坐标点的X,Y 坐标,其实是一种向量,是一种数学抽象。现实世界中很多属性是可以抽象成向量的,比如,我们的年龄,我们的喜好,我们的商品,等等,能抽象成向量的目的就是可以让计算机知道某两个属性间的距离。如:我们认为,18岁的人离24岁的人的距离要比离12岁的距离要近,鞋子这个商品离衣服这个商品的距离要比电脑要近,等等。
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
import numpy as np
X_train,y_train = make_blobs(n_samples=300,centers=4)
plt.scatter(X_train[:,0],X_train[:,1],c=y_train)
km = KMeans(4)
km.fit(X_train)
y_ = km.predict(X_train)
cluster_centers_=km.cluster_centers_
plt.scatter(X_train[:,0],X_train[:,1],c=y_train)
plt.scatter(X_train[:,0],X_train[:,1],c=y_)
plt.scatter(cluster_centers_[:,0],cluster_centers_[:,1],c=km.predict(cluster_centers_),cmap='rainbow',s=100)
import pandas as pd
data = pd.read_csv('./k-means_data/Asiafootball.txt',header=None)
#将列名进行修改
data.columns = ["国家","2006世界杯","2010世界杯","2007亚洲杯"]
#去除国家这一列
X_train = data.drop(labels='国家',axis=1)
km = KMeans(3)
km.fit(X_train)
y_=km.predict(X_train)
np.argwhere(y_==0).ravel()
country = data['国家']
for i in range(3):
index = np.argwhere(y_ == i).ravel()
print(country[index])
print('\n')
#绘制三维立体图形
from mpl_toolkits.mplot3d import Axes3D
cluster_centers_ = km.cluster_centers_
fig = plt.figure(figsize=(12,8))
axes3d = Axes3D(fig)
axes3d.scatter3D(X_train.iloc[:,0],X_train.iloc[:,1],X_train.iloc[:,2],c=y_,s=200,cmap='cool')
axes3d.scatter3D(cluster_centers_[:,0],cluster_centers_[:,1],cluster_centers_[:,2],s=400,alpha=0.5,c=km.predict(cluster_centers_))
1.导入相应的工具包:SVM,GridSearchCV,PCA,matplotlib
2.我们需要相应的数据集
3.还用fetch_lfw_people导入人脸的数据,这个数据包在第一次使用的时候会去下载
4.查看人脸的结构
import numpy as np
import matplotlib.pyplot as plt
import sklearn.datasets as datasets
from sklearn.model_selection import train_test_split,GridSearchCV
#人脸识别是分类还是回归?分
#人脸自动补全?回归
from sklearn.svm import SVC
from sklearn.decomposition import PCA
#min_faces_per_person 把每个人至少有70张图片的数据给筛选出来了
face = datasets.fetch_lfw_people(min_faces_per_person=70,resize=1.0)
face
#提取特征值和目标值
data = face.data
target = face.target
target_names = face.target_names
#slice(70, 195, None), slice(78, 172,
face.images.shape
plt.imshow(data[2].reshape(125,94),cmap='gray')
#分割数据
X_train,X_test,y_train,y_test = train_test_split(data,target,test_size=0.02)
#现在图片的维度是多少 2 维
#对于机器学习来说,图片是多少维的?125 * 125
#维度太高,用PCA降维
#whiten=False 要不要进行标准化的处理
pca = PCA(n_components=150,whiten='True')
X_train_pca = pca.fit_transform(X_train)
X_test_pca = pca.transform(X_test)
#SVM
C参数: 惩罚系数,对结果误差的宽容的,C值越高,对于误差的容忍度就越高(过拟合),C值越小误差就越大(欠拟合)
gamma参数:在SVM使用rbf的内核才能使用,表示的是支持向量的数量,gamma越大,支持向量数量越少(决策边境就不准确),gamma越小,支持向量的数量就会越多(效率下降了)
#进行建模 SVM 网格搜索+交叉验证
svc = SVC()
param = {'C':[0.1,0.5,1,1.5,2.0,2.5],'gamma':[0.001,0.003,0.01,0.5]}
#estimator 估算器
#param_grid 要调节的参数,应当是一个字典
gc = GridSearchCV(svc,param,cv=2)
gc.fit(X_train_pca,y_train)
#返回最好的参数
gc.best_params_
#返回最好的准确率
gc.best_score_
#返回最好的模型
svc_best = gc.best_estimator_
#评分
svc_best.score(X_train_pca,y_train)
y_ = svc_best.predict(X_test_pca)
svc_best.score(X_test_pca,y_test)
#将预测的图片全部打印,把真实的目标值和预测的目标值作为标题 26 每行显示5张 2*3
plt.figure(figsize=(5*3,6*5))
for i in range(26):
axes = plt.subplot(6,5,i+1)
#X_test_pca X_test
axes.imshow(X_test[i].reshape(125, 94),cmap='gray')
#取消刻度轴
axes.axis('off')
#目标值都是一些数字
true_name = target_names[y_test[i]].split(' ')[-1]
predict_name = target_names[y_[i]].split(' ')[-1]
#设置标题
axes.set_title('True:%s\nPredict:%s'%(true_name,predict_name))
#保存模型
from sklearn.externals import joblib
#保存.m的文件
joblib.dump(svc_best,'Bface.m')
#加载
model_ = joblib.load('Bface.m')
model_
model_.predict(X_test_pca)
首先我们需要考虑使用机器学习算法的目的。如果想要预测目标变量的值,则可以选择监督学习算法,否则可以选择无监督学习算法。确定选择监督学习算法之后,需要进一步确定目标变量的的类型,如果目标变量是离散型,如是/否,1/2/3,等等,则可以选择分类器算法;如果目标变量是连续型的数值,如0.0~100.00、-999~999等,则需要选择回归算法
如果不想预测目标变量的值,则可以选择无监督学习。进一步分析是否需要将数据划分为离散的组。如果这是唯一的要求,则使用聚类算法;如果还需要估计数据与每个分组的相似的程度,则需要使用密度估计算法