numpy+pandas

1.jupyter的使用

一. 安装与使用

1.Jupyter Notebook是基于网页的用于交互计算的应用程序,可以在网页页面中直接编写代码和运行代码,代码的运行结果也会直接在代码块下显示。如在编程过程中需要编写说明文档,可在同一个页面中直接编写,便于作及时的说明和解释。

用途包括:数据清理和转换,数值模拟,统计建模,机器学习等等。

  • 运行 pip install jupyter命令即可安装Jupyter.
  • 在命令行中输入jupyter notebook即可启动Jupyter.
  • jupyter启动以后,会在电脑上新建一个服务器,并且会自动打开电脑的浏览器访问该服务器.

2.快捷键(点help可查看全部)

  • Shift+Enter : 运行本单元,选中下个单元
  • Ctrl+Enter : 运行本单元
  • Alt+Enter : 运行本单元,在其下插入新单元
  • Y:单元转入代码状态
  • M:单元转入markdown状态
  • A :在上方插入新单元
  • B:在下方插入新单元
  • X:剪切选中的单元
  • Shift +V:在上方粘贴单元
  • tab:代码自动补全
  • shitf + tab:方法提示

查看属性和方法:dir(s)

二. IPython里的魔法函数
  1. IPython 里提供的内置函数,可以快速实现一些功能,特点是以%开始
  2. IPython里的魔法函数分为两种,一种是单行的line,一种是单元格cell
import time

# 计算一段代码的执行时间:%time 代码
%time sum(range(1,1000000))   # 代码只执行一次

# 计算一段代码的执行时间:         # 代码执行多次,取平均值
%timeit sum(range(1,1000000))

# %% 对一个cell 起作用
%%time
x = 0
for i in range(1,1000000):
	x += i

# 执行一个外部文件
%run 文件名.py

# 显示IPython里面的魔法函数
%magic

# 显示历史代码的过程
%history

# 删除变量
a = 100
%xdel a

# 查看IPython的文档
%quickref

# ?random   查看 random文档
# ??random  查看 random源代码

# 多行输出
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

2.numpy

一. numpy使用

NumPy是使用Python进行科学计算的基础包,一个强大的N维数组对象,复杂的(广播)功能,用于集成C / C ++和Fortran代码的工具,有用的线性代数,傅里叶变换和随机数功能

  1. numpy最重要的一个特点是它的N维数组对象-----ndarray,该对象是一系列数据(通常是同一类型数据的集合)

  2. ndarray里每一个维度称为一个轴。

  • [1,2,3]:只有一个维度,也就只有一个轴。有三个元素,轴长为3.

  • [

​ [4,5,7,10],

​ [11,12,34,55]

​ ] :两个维度,也就有两个轴长,第一个轴长是2,第二个轴长是4.

  1. ndarray的shape属性,是一个元组类型的数据,用来表示数组有几个轴及每个轴的轴长。
import numpy as np

na = np.array([  # 调用 numPy的array方法,可以创建一个 ndarray对象 
    [
        [9, 4, 2],
     	[3, 5, 8],
     	[2, 2, 0],
     	[7, 6, 1]
    ],
    [	
        [1, 4, 7],
     	[2, 5, 8],
     	[3, 6, 9],
    	[7, 4, 2]
    ],
])
print(na.ndim)   # 3 数组的维度
print(na.size)   # 24 数组里元素的个数
print(na.dtype)  # int32 数组里元素的类型
print(na.shape)  
# (2, 4, 3) 倒着看,从最里面的一层开始数。这是一个三维数组,第一个轴长是2,第二个轴长是4,第三个轴长是3
print(na.itemsize) # 4 数组里元素的字节数
二. numpy数据类型
print(na.dtype)  # 数组里元素的类型
三. 创建ndarray对象(N维数组对象)

NumPy提供了很多的函数来快速的生成一个ndarray对象。

1. numpy.random

numpy.random 包里提供了很多的方法,可以快速的生成一个数组。

# size ==>单个数字:一维,或者是元组:多维
na1 = np.random.random(size=5)  #  生成指定 size 的 [0.0,1.0)随机浮点数

na2 = np.random.randint(5, 100, size=4) # 生成指定 size个数 的随机整数的数组  
# array([79, 42, 89, 94])
na2 = np.random.randint(5, 100, size=(2,2))  # 生成指定size的数组
# array([[76, 71],
#       [81, 21]])

# np.random.randn(d0, d1, ..., dn) 标准正态分布
na3 = np.random.randn(3, 5)  # 生成正态分布的随机数组
2. arange:

根据一个序列生成一个数组,用法和Python里的range类使用基本一致。

# np.arange(start,end,step=1),默认为1
na1 = np.arange(10)
na2 = np.arange(3,20)
na3 = np.arange(2,20,3)
3. array:将序列转换成为ndarray对象。
# array方法可以将 range,list,tuple,set和dict等序列数据转换成为ndarray对象。
na1 = np.array(range(10))
na2 = np.array([1,2,3])
na3 = np.array(('hello','good','yes'))
na4 = np.array({98,78,99,95})
na5 = np.array({'name':'zhangsan','age':18,'score':90})
4.full和full_like:使用指定值来填充数组。
na1 = np.full((2,5),10)  # 生成一个2X5的数组,用10填充
"""
array([[10, 10, 10, 10, 10],
       [10, 10, 10, 10, 10]])
"""

na2 = np.full_like(np.array([0,1,2,3]),5)
# 生成一个用 5 填充每一个位置的,形如np.array([0,1,2,3])数组  的数组

"""
array([5, 5, 5, 5])
"""
5.zeros和zeros_like:用来创建元素全是0的数组。
na1 = np.zeros(shape=(3, 2, 4))  # zeros必须要指定shape,用来生成一个指定形状的数组
na2 = np.zeros_like([1,2,3])  # 根据指定的列表(或数组)的格式,生成一个新的数组
6.ones和ones_like:用来创建元素全是1的数组。
na1 = np.ones(shape=(3,2,4))

"""
np.ones(shape, dtype=None, order='C')

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.]]])

"""
na2 = np.ones_like([98,76,55])

"""
array([1, 1, 1])
"""
7.linspace:生成一个线性数组。
na = np.linspace(10, 100, num=19)   # 生成一个10-100的 有19个元素的数组
"""
np.linspace(
    start,
    stop,
    num=50,
    endpoint=True, # 最后一个值 取到
    retstep=False, 
    dtype=None, # 数据类型
    axis=0, # 默认为0 指按行生成
 )

array([ 10.,  15.,  20.,  25.,  30.,  35.,  40.,  45.,  50.,  55.,  60.,
        65.,  70.,  75.,  80.,  85.,  90.,  95., 100.])
"""
8.np.diag:返回一个对角矩阵。
np = np.diag([1,2,3,4])
"""
array([[1, 0, 0, 0],
       [0, 2, 0, 0],
       [0, 0, 3, 0],
       [0, 0, 0, 4]])
"""
9.np.eye:返回一个二维的对角数组,其中对角线为1,零点为零。
"""
np.eye(N, M=None, k=0, dtype=float) 对角线为1其他的位置为0
"""

# 生成一个3阶单位阵
# N 是行数,M 是列数,K是对角线上移(正数)或者下移(负数)
np.eye(3,3,1)
10.np.random.permutation(x) :随机排列数列,元素不重复
# 随机排列数列,元素不重复
np.random.permutation(10)
"""
array([6, 2, 7, 5, 1, 0, 9, 4, 8, 3])

"""
四. ndarray的属性
ndarray.shape:查看数组的形状
ndarray.size:查看数组的长度,即元素个数
ndarray.ndim:查看数组的维数
ndarray.dtype:查看数组元素的类型
五. ndarray的基本操作
1.索引(下标)
#一维数组的索引
arr = np.array([1,2,3,4])
# 通过下标访问
#arr[n]
arr[3]
# 以下标的列表为索引可以获取指定的多个元素
arr[[2,0,3,1]]

# 二维数组的索引
a = np.array([[1,2],[3,4],[5,6]])
# # 索引
a[1][0]
# # 索引一行
a[2]

# # 索引是对原数组的引用
# # 可以通过索引修改原数组的元素
a[2][1]=98
a[1]=[61,45]
a

"""
4
array([3, 1, 4, 2])
3
array([5, 6])
array([[ 1,  2],
       [61, 45],
       [ 5, 98]])
       
"""
2.切片

一维数组切片和python的列表相同

# array[start:end:step]  step默认是1
a = np.linspace(1,10,10,dtype=np.int)
a
# array[start:end:step]  step默认是1
a = np.linspace(1,10,10,dtype=np.int)
a
"""
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10])
"""

二维数组切片

# 前n行
a[:]
a[2:]
a[:3]
a[2:6]
a[1:-2]
a[-1:-4:-1]
a[::-1]

# 不能省略行切片
a[:,:3]
a[:,1:3]

# 将最后一列改为0,原数组也会改变
# 切出来的都是视图
a[:,-1:-2:-1] = 0
a
3.1 索引数组

索引可以是一个整型数组,数组中的每个值指示要使用的数组中的哪个值代替索引。索引数组返回的是原始数据的副本,而不是切片获取的视图。

a = np.array([[1,2,3],[4,5,6],[7,8,9]])
# a
# 第一个[0,1]表示0行,1行;第二个[0,1],表示0列,1列
# 整体表示取a中a[0][0]和a[1][1]
# a[[0,1],[0,1]]  # array([1, 5])
a[[1,2],[2,0]]
# 取第0,1行和所有列生成一个新数组
a[[0,1]]
# 取所有行和第1,2列
a[:,[0,1]]
# 索引可以重复
a[[1,2,1,0]]

3.2 三维数组的例子
from matplotlib import pyplot as plt

# 准备一张图片放大当前目录
# 使用matplotlib读取图片
cat = plt.imread("cat.jpg")
# 查看类型
type(cat)
# 查看维度
cat.ndim
# 查看形状
cat.shape
# 第一维取反,高度
plt.imshow(cat[::-1,:,:])

# 第二维取反,左右
plt.imshow(cat[:,::-1,:])

# 第三维取反,颜色
plt.imshow(cat[:,:,::-1])

# 取一部分图像
plt.imshow(cat[0:200,:,:])
4.1 布尔数组

用作索引的布尔数组的处理方式与索引数组完全不同。布尔数组的形状必须与要索引的数组的初始尺寸相同。 与索引数组一样,返回的是数据的副本,而不是切片所获得的视图。

# 一维数组
a = np.array([1,2,3,4])
# 布尔索引的长度必须要和原数组一致
a[[True,False,True,False]]

# 数组可以直接进行关系运算,结果是布尔数组
a > 2

# 选取大于2的元素
a[a>2]
# 二维数组
a = np.random.randint(0,20,size=(4,5))

# 找出元素值大于10的
a[a>10]
4.2 使用逻辑判断
  • 逻辑与 & 逻辑或 | 逻辑非 ~
# 获取数组中大于5切是偶数的元素
a[(a>5)&(a%2==0)]

# 获取数组中不大于3的元素值
a[a<=3]
a[~(a>3)]

# 获取数组中元素值大于4或者是偶数的元素
a[(a>4)|(a%2==0)]
4.3 三目运算

满足条件(condition),执行x,不满足执行y。

np.where(condition, x, y)

# 元素是偶数的值扩大两倍,为奇数的值加1
np.where(a%2==0,a*2,a+1)
5.修改数组的元素值
# 切片会产生新数组
a = np.arange(1,25).reshape(4,6)
a
# 修改某一行的值
a[1]=9

# 修改某一列的值
a[:,1]*=2

# 修改连续多行
a[-2:]-=1

# 修改连续多列
a[:,-3:]*=2

# 修改多行多列,取第二行到第四行,第三列到第五列
a[1:,2:6]+=1

# 修改多个不相邻的点(0,0),(3,1)
a[[0,3],[0,1]] = 1000

# 把数组中大于15的元素修改为0
a[a>15]=0
a
六. 数组变换
1.变形

可以通过reshape或resize函数改变数组的形状,其中reshape 函数返回修改后的新对象,而ndarray.resize方法修改数组本身

  • 变形的各个维度上整数的乘积必须等于arr.size
  • 如果想让自动计算某个轴上的大小,可以传入-1
a = np.arange(0,12)
a
# 不可以改变元素个数,新数组和原数组元素个数必须一致
# -1 :自动计算列数
res = a.reshape((4,-1))
res
# 判定res和a是不是同一个数组
res is a
# resize 修改数组本身,不返回值
a.resize((4,3))
a
2. 数组转置
a = np.arange(12).reshape(4,3)
a
# 转置产生新数组
a.T
3. 数组扁平化

flatten方法可以把高维数组变成一维数组

a = np.arange(12).reshape(3, 4)
a
a.flatten()
4. 数组转列表
a = np.arange(12).reshape(3, 4)
a.tolist()
七. 数组的轴

数组的轴(axis):在numpy中可以理解为方向,使用0,1,2数字表示,

  • 一维数组,只有一个0轴,
  • 二维数组(shape(2,2))有0轴和1轴
  • 三维数组(shape(2,2,3))有0,1,2轴

有了轴的概念后,我们计算会更加方便,比如计算一个2维数组的平均值,必须指定是计算哪个方向上面的数字的平均值

# a.sum(axis=None, dtype=None, out=None, keepdims=False)
a = np.array([[1,2,3],[4,5,6]])
a
# 未指定axis则对所有元素求和
a.sum()

# 按列求和
a.sum(axis=0)

# 按行求和
a.sum(axis=1)
八. 数组的计算
1.广播机制
  • 广播是一种强有力的机制,它让Numpy可以让不同大小的矩阵在一起进行数学计算。
  • 广播原则:如果两个数组的后缘维度(trailing dimension,即从末尾开始算起的维度)的轴长度相符,或其中的一方的长度为1,则认为它们是广播兼容的。广播会在缺失和(或)长度为1的维度上进行。
  • 广播能够进行,必须满足:
    • 一种是两个数组的维数不相等,但是它们的后缘维度的轴长相符,
    • 一种是有一方的长度为1。
    • 必须使用已有的全部数据进行填充
1.1沿缺失维度进行
# arr1的shape为(4,3),arr2的shape为(3,)。可以说前者是二维的,而后者是一维的。但是它们的后缘维度相等,arr1的第二维长度为3,和arr2的维度相同。arr1和arr2的shape并不一样,但是它们可以执行相加操作,这就是通过广播完成的,在这个例子当中是将arr2沿着0轴进行扩展。
arr1 = np.array([[0, 0, 0],[1, 1, 1],[2, 2, 2], [3, 3, 3]]) 
arr2 = np.array([1, 2, 3])   
arr1
arr2
arr1.shape
arr2.shape
arr1 + arr2

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A3SoYODE-1628010726306)(C:\Users\姚啊\AppData\Roaming\Typora\typora-user-images\image-20210306214505371.png)]

1.2 沿维度为1的方向进行
# arr1的shape为(4,3),arr2的shape为(4,1),它们都是二维的,但是第二个数组在1轴上的长度为1,所以,可以在1轴上面进行广播,如下图所示:
arr1 = np.array([[0, 0, 0],[1, 1, 1],[2, 2, 2], [3, 3, 3]])  
arr2 = np.array([[1],[2],[3],[4]])   
arr1
arr2
arr1+arr2

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N32q2TNo-1628010726308)(C:\Users\姚啊\AppData\Roaming\Typora\typora-user-images\image-20210306214721839.png)]

2.数组和数的运算
a = np.array([[1,2],[3,4]])
a
# 算术运算
a*2
# 关系运算
a>2
3.1数组和数组之间的运算
# 只要两个数组按照广播机制能够扩展成形状相同的数组就可以,数组运算实际上是对应位置上元素之间的计算
arr1
arr2

arr1+arr2
arr1*arr2
3.2 矩阵内积

数组之间的计算默认是对应元素的计算,如果要计算矩阵内积,可以使用dot方法

a = np.array([[1,2],[3,4]])
b = np.array([[1,1],[2,2]])
a
b
# 计算内积
np.dot(a,b)

"""
array([[1, 2],
       [3, 4]])
array([[1, 1],
       [2, 2]])
array([[ 5,  5],
       [11, 11]])
"""
九. 数组的聚合操作(统计)

聚合的目的就是获得数组的信息,即相关数据的概括统计值.

具体包括:均值和偏差,求和,乘积,中位数,最小值和最大值,分位数等等

arr = np.random.randint(0,10,size=10)
arr2 = np.array([[80,88],[82,89],[75,81]])
arr
arr2

"""
array([3, 4, 3, 8, 5, 9, 3, 9, 4, 8])
array([[80, 88],
       [82, 89],
       [75, 81]])
"""
# 1 求和 np.sum

# 多维数组获取所有数据和
arr2.sum()
np.sum(arr2)
# 获取某一个轴上的数据和 axis控制轴向
arr2.sum(axis=1) # 行
"""
487
487
array([168, 163, 156])
"""
# 2. 求平均值 np.mean
arr2
arr2.mean()

np.mean(arr2,axis=0)  # 列
np.mean(arr2,axis=1)   # 行


"""
array([[80, 88],
       [82, 81],
       [75, 81]])
81.16666666666667
array([79.        , 83.33333333])
array([84. , 81.5, 78. ])

"""
# 3求最大值 np.max
arr2
np.max(arr2,axis=0)    # 列
np.max(arr2,axis=1)    # 行

"""
array([[80, 88],
       [82, 81],
       [75, 81]])
array([82, 88])
array([88, 82, 81])

"""
# 4 求最小值 np.min
arr2
np.min(arr2,axis=0)     # 列
np.min(arr2,axis=1)     # 行

"""
array([[80, 88],
       [82, 81],
       [75, 81]])
array([82, 88])
array([88, 82, 81])
"""
# 5求最大值的索引 np.argmax
arr2
np.argmax(arr2,axis=0)
# np.argmax(arr2)  # 没有axis时,默认扁平化数组为一维,返回下标

"""
array([[80, 88],
       [82, 89],
       [75, 81]])
array([1, 1], dtype=int64)
"""
# 6 求最小值的索引 np.argmin
arr2
np.argmin(arr2,axis=0)

"""
array([[80, 88],
       [82, 81],
       [75, 81]])
array([2, 1], dtype=int64)
"""
# 7 方差 np.var
# 描述数据的波动性大小,单位和元数据不同
arr.var()
np.var(arr2)
np.var(arr2,axis=0)
np.var(arr2,axis=1)

"""
6.040000000000001
22.916666666666668
array([ 8.66666667, 12.66666667])
array([16.  , 12.25,  9.  ])
"""
# 8. 标准差 np.std
# 描述数据的波动性大小,单位和元数据相同
arr2.std()

"""
4.7871355387816905
"""
# 9 中位数np.median
# 一组数据排序后,中间位置的数据
# 如果数据个数n为奇数,则中位数= data[(n+1)/2]
# 如果数据个数n为偶数,则中位数=(data[n/2]+data[n/2+1])/2
# 注意不能用arr.median求中位数

arr2.sort()  # 排序,改变的是自身
arr2
np.median(arr2)

"""
array([[80, 88],
       [82, 89],
       [75, 81]])
81.5
"""
arr2 = np.array([True,False,True,True])
# 10 # np.any  检测一个BOOL数组中,是否至少存在一个True
np.any(arr2)

"""
True
"""
# 11 # np.all  检测一个BOOL数组中,是否全为True
np.all(arr2)

"""
False
"""

grades = np.array([56,89,90,67,80])
grades
# 查看有没有不及格成绩
# res = grades<60    # 满足是True
# res
# res.any            # 有True 就是有不及格
(grades<60).any()
# 查看是不是所有成绩都大于70
(grades>70).all()

"""
array([56, 89, 90, 67, 80])
True
False
"""
十. 级联
1.np.concatenate()

级联需要注意的点:

  • 级联的参数是元组:一定要加中括号或小括号
  • 维度必须相同
  • 形状相符
  • 【重点】级联的方向默认是shape这个tuple的第一个值所代表的维度方向
  • 可通过axis参数改变级联的方向
a = np.random.randint(0,100,12).reshape(3,4)
b = np.linspace(0,12,num=3,dtype=np.int).reshape(3,1)
a
b
# 行数一样的时候,axis=1横向连接
# 列数一样的时候,axis=0竖向连接
np.concatenate((a,b),axis=1)
# 使用axis控制连接方向

"""
array([[16, 96, 22, 45],
       [82, 48, 90, 43],
       [ 7, 36, 49, 17]])
array([[ 0],
       [ 6],
       [12]])
array([[16, 96, 22, 45,  0],
       [82, 48, 90, 43,  6],
       [ 7, 36, 49, 17, 12]])

"""
2.np.hstack与np.vstack

水平级联与垂直级联,处理自己,进行维度的变更

# 横着连接 np.hstack (左右)
np.hstack((a,b))

"""
array([[16, 96, 22, 45,  0],
       [82, 48, 90, 43,  6],
       [ 7, 36, 49, 17, 12]])
"""
# 竖着连接 np.vstack  (上下)
a = np.random.randint(0,100,12).reshape(3,4)
b = np.random.randint(0,100,8).reshape(2,4)
a
b
np.vstack((a,b))

"""
array([[82, 91, 29, 77],
       [66, 63,  9, 64],
       [24, 77, 86, 28]])
array([[47, 29, 50, 11],
       [12, 74,  0, 58]])
array([[82, 91, 29, 77],
       [66, 63,  9, 64],
       [24, 77, 86, 28],
       [47, 29, 50, 11],
       [12, 74,  0, 58]])
"""
十一.切分

将一个数组分割为多个子数组

与级联类似,三个函数完成切分工作:

np.split np.vsplit np.hsplit

arr = np.random.randint(0,100,size=(6,6))
arr

# indices_or_sections直接指定切分的份数,返回的是一个数组
# 默认按行切分axis=0,  axis=1按列切分
# a1,a2,a3 =np.split(arr,indices_or_sections=3)
a1,a2,a3 =np.split(arr,indices_or_sections=3,axis=1)
a1
a2
a3
# 使用axis控制切分方向
"""
array([[29, 39],
       [37, 49],
       [93, 42],
       [81, 30],
       [26, 42],
       [91, 14]])
array([[21, 25],
       [53, 34],
       [ 3, 40],
       [95, 75],
       [64,  1],
       [22, 98]])
array([[ 7, 29],
       [85,  3],
       [54, 82],
       [ 6, 84],
       [46,  7],
       [19, 83]])
"""

# 非等分,可以indices_or_sections指定,
# indices_or_sections=[m,n] 表示的范围是0:m, m:n, n:
a1,a2,a3=np.split(arr,indices_or_sections=[1,4])  # [:1,1:4,4:]
a1
a2
a3

"""
array([[29, 39, 21, 25,  7, 29]])
array([[37, 49, 53, 34, 85,  3],
       [93, 42,  3, 40, 54, 82],
       [81, 30, 95, 75,  6, 84]])
array([[26, 42, 64,  1, 46,  7],
       [91, 14, 22, 98, 19, 83]])
"""
# 横着切 np.hsplit
a1,a2=np.hsplit(arr,indices_or_sections=[2])
a1
a2

# 竖着切 np.vsplit
a1,a2,a3=np.vsplit(arr,indices_or_sections=[3,4])
a1
a2
a3
十二. 其他
1. 排序

np.sort()与ndarray.sort()都可以,但有区别:

  • np.sort()不改变输入
  • ndarray.sort()本地处理,不占用空间,但改变输入
arr1 = np.random.randint(1,20,size=10)

arr1
# 生成新数组,不改变原数组的顺序
np.sort(arr1)
# arr1.sort()
2. 副本np.copy

所有赋值运算不会为ndarray的任何元素创建副本。对赋值后的对象的操作也对原来的对象生效。

可使用copy()函数创建副本

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

# 修改a1_copy,a1不会变
a1_copy[2]=90
a1
a1_copy

"""
array([1, 2, 3, 4])
array([ 1,  2, 90,  4])
"""
3. 去重

numpy.unique 函数用于去除数组中的重复元素。

a = np.array([5,2,6,2,7,5,6,8,2,9])
np.unique(a)
a # 原数组不会改变

"""
array([2, 5, 6, 7, 8, 9])
array([5, 2, 6, 2, 7, 5, 6, 8, 2, 9])
"""


# groupby分组时 nunique 去重
4. 数组中nan和inf
inf 表示无穷大,比如一个数字除以0,Python中会报错,但是numpy中会是一个inf或者-inf

nan,表示缺失的数据,所以一般用nan来表示。任何与其做运算结果都是nan。
# 创建一个nan和inf 
a = np.nan
b = np.inf
a
b
# nan不等于nan
np.nan == np.nan   # False

"""
nan
inf
False
nan
"""
t = np.arange(24,dtype=float).reshape(4,6)
t

"""
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.]])
"""
# 可以使用np.count_nonzero() 来判断非零的个数
np.count_nonzero(t)    # 23个
# 将第三行第四列的数改成nan
t[2,3] = np.nan
t
"""
array([[ 0.,  1.,  2.,  3.,  4.,  5.],
       [ 6.,  7.,  8.,  9., 10., 11.],
       [12., 13., 14., nan, 16., 17.],
       [18., 19., 20., 21., 22., 23.]])
"""
# 判断nan的个数
# 生成布尔数组
t != t

# 使用np.count_nonzero() 来判断非零的个数 ===>  0 是 False
np.count_nonzero(t!=t)
# 判断是否存在nanS
(t!=t).any()

"""
array([[False, False, False, False, False, False],
       [False, False, False, False, False, False],
       [False, False, False,  True, False, False],
       [False, False, False, False, False, False]])
1
True
"""
# 注意: nan和任何数计算都为nan
a+4

3. pandas

一. pandas的安装和引用

Pandas 基于 NumPy 开发,可以与其它第三方科学计算支持库完美集成。

pip install pandas
import numpy as np
import pandas as pd
from pandas import Series,DataFrame

# 多行输出
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
二. pandas的基本数据结构
  • 常见的有Series和DataFrame两种数据结构。Series表示一维数组,能保存不同种数据类型,字符串、布尔值、数字等都可以保存在Series中。

  • 以NumPy`.npy``格式将数组保存到二进制文件。-----np.save(文件名, 要保存的数组名)

三.数据清洗配置
1.探索性数据分析(Exploratory Data Analysis,EDA)

主要的工作是:对数据进行清洗,对数据进行描述(描述统计量,图表),查看数据的分布,比较数据之间的关系,培养对数据的直觉,对数据进行总结等

探索性数据分析(Exploratory Data Analysis,EDA) - HuZihu - 博客园 (cnblogs.com)

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt 
import matplotlib.style as style

# 设置数据的小数点位
pd.set_option('display.float_format')

# 画布背景
style.use('fivethirtyeight')
# 中文字体显示
plt.rcParams['font.family']=['SimHei']
# 负数问题
plt.rcParams['axes.unicode_minus']=False
四. 数据清洗的相关方法

查看Series或DF有的方法:dir(s)

读取ANSI编码的csv文件时:pd.read_csv(‘superstore_dataset2011-2015.csv’,encoding=“unicode_escape”)

1.统计方法

1.两个Series 相加:s1 + s2 ===>index对应的 数据相加,没有对应的相加为NaN

2.统计方法:s.sum()=>求和,s.cumsum()=> 累计求和;

  1. s.max()/min()/平均数mena()/标准差std()/方差var()/count()/中位数median
2.常用函数
s.T===>转置

s.duplicated(subset,keep)===>判断有重复的吗,行与行之间进行比较;subset=['某列']可指定列,对指定列的行进行比较;keep=['要保留的值的位置']

s.drop_duplicates(subset,keep,inplace,ignore_index)===>删除特定列下面的重复行
s.drop(lables,axis,index,columns)===>lables=['要删除的行或列标签'] 与 axis=0/1搭配使用;index=['行标签'];columns=['列标签']
s.dropna(axis,how='any/all',thresh,inplace)===>删除NaN;thresh=n 要保留的非缺失值个数 n ,是n 就删掉,不是就保留。

s.isnull / s.isna()===>判断有缺失值吗,有缺失值就True
s.fillna(values,inplace)===>用指定值填充缺失值

s.isnull.any()===>只要有一个缺失值,就返回True
s.isnull.all()===>全是缺失值,返回True

s.rename()===>重命名,以字典的形式
s.replace()===>替换,(old,new,limit=替换几次,inplace=是否在原数据修改)

s.head()===>查看前几行,默认前5行
s.tail()===>查看后几行,默认后5行
# 调用函数实现某个功能
map(字典或者函数)===>只能Series用,
s.map(函数名)==>将s里面的每个元素执行map里面的函数

apply(函数)===>可以用于df,
df.apply(func,axis=0)

tranform(函数)===>可以用于df,
df.transform(func,axis=0)

agg(函数/字典)===>可以用于df


# 排序
s.sort_values(by,axis,ascending=True,inplace)
ascending=True:默认升序

# 设置行标签
df.set_index()
# 对于Series,行标签带有前缀。对于DataFrame,列标签带有前缀
s.add_prefix(str) ===>在每个标签之前添加字符串

# 复制
s.copy()
s.deepcopy() ===> 不影响被copy的数据

# 将标签数值化
dfa['物形']=dfa["物理形态"].astype("category").cat.codes
3.查看数据完整性
# 安装库
pip install missingno
# 调用
import missingno

# 空白越多说明缺失越严重
# 绘制缺失值矩阵
missingno.matrix(data)
# 条形图/直方图/柱图
msno.bar(data)
# 热力图 
msno.heatmap(data)
# 树图
msno.dendrogram(data)
4.异常值查看
# 可用seaborn看异常值情况

# 箱图
seaborn.boxplot()
5.相关性检测
df.corr(method='pearson')

Series

一. 创建Series

Series的每个元素都带有两种index

  • 显示index : 由用户指定
  • 隐式index : 由系统自动分配(Series对象中每个元素的下标,类似Python"列表"的下标)

Series的访问既可以通过显示index,也可以通过隐式index,在数据分析和数据科学项目中,一般用显式索引(index),而不是隐式下标,原因在于:当数据量很大时,很难准确定义其下标

"""
pd.Series(
    data=None,
    index=None,
    dtype=None,
    name=None,
    copy=False,
    fastpath=False,
)
"""
x = pd.Series(np.random.randint(10,200,size=4),index=['A','B','C','D'],name='我是数据名字')
x.index.name = '我是标签名字'
x

输出

我是标签名字
A     86
B    102
C    158
D     91
Name: 我是数据名字, dtype: int32
二. 索引和切片
data=np.random.randint(10, 200, size=4)
indexs=['a', 'b', 'c', 'd']
series = pd.Series(data=data, dtype=np.uint8, index=indexs)
print(series)

"""
a     43
b    122
c     67
d    150
dtype: uint8
"""
# series可以使用下标和key两种方式进行索引
# 需要注意,loc 只支持使用key(标签)索引;而 iloc支持使用下标(数字)索引
# 还可以使用条件进行索引
a = (series > 90) | (series < 50) # |=或(or)

# 可以使用下标或者key来进行切片操作
print(series['a':'c'])
print(series[0:3])

print(series.loc['a']) # 43
print(series.iloc[0]) # 43

DataFrame

一. 创建DataFrame

pd.DataFrame(data=None, index=None, columns=None, dtype=None, copy=False)

参数说明:
data:可选数据类型,如:ndarray,series,map,lists,dict,constants和另一个DataFrame
index:行标签索引,缺省值np.arrange(n),不计入df列
columns:列标签索引,缺省值np.arrange(n),不计入df行
dtype:每列的数据类型
copy:默认值False,引用/复制数据

data:通过二维列表创建;通过包含列表的字典创建;通过 含有列表的Series 的字典创建;使用numpy数组创建;通过数据的读入(读取CSV和excel文件)

二. DataFrame的属性(df.)
1	df.shape	形状
2	df.ndim	    维数
3	df.dtypes	每一列的元素类型
4	df.size	    元素个数
5	df.index	获取行标签或索引
6	df.columns	获取列标签或索所
7	df.axes	    获取行和列索引
8	df.values	返回ndarray类型的对象
9	df.info()	打印DataFrame的简要摘要。
10	df.describe()	按列生成描述性统计信息
11	df.head()	获取前n行
12	df.tail()	获取后n行
df = pd.DataFrame(data=[
    ['male', 18, 175, 145],
    ['female', 17, 160, 110],
    ['male', 18, 178, 150],
    ['male', 19, 180, 148],
    ['female', 18, 165, 100]
], index=['张三', '李四', 'Jack', 'Henry', 'Merry'], columns=['gender', 'age', 'height', 'weight'])

print(df)

"""
         gender  age   height  weight
张三       male   18     175     145
李四     female   17     160     110
Jack     male    18     178     150
Henry    male    19     180     148
Merry   female   18     165     100
"""
三. DataFrame的index和columns

DataFrame的index和columns属于Index类型,Index是一个不可变的有序序列,性能和ndarray一样,但不能修改.

1. 索引和切片

语法:

实现目的	     语法	            结果
选择列	        df[col]	         Series/DataFrame
切片行	        df[5:10]	     DataFrame
按标签选择	   df.loc[label]	Series
按位置选择	   df.iloc[数字]	    Series
按布尔向量选择行 df[布尔值]	  DataFrame
1.1 基于标签的索引----.loc
df['列标签'] ==df.列名 ===>根据column进行索引,得到的结果是一个Series类型的数据

df['列标签']['行标签']

df.loc['行标签']===>取出指定行的 所有列的值,Series 类型的

df.loc['行标签'],['列标签']===>取出指定了行和列的值

df[布尔值]  返回的是DataFrame
1.2 基于下标的索引----.iloc
df.iloc['行下标']==>根据行的下标进行索引,得到的是一个Series类型的数据

df.iloc['行下标'],['列下标']===>取出指定了行和列的值

1.3 切片
# 切片
# df['gender','height'] 直接使用列进行切片有可能会报错(如果行索引有中文时,会报错)

df['张三':'Henry']  # 在切片时,默认是以行来进行切片。

df.loc['张三':"Henry"] # 等价于  df['张三','Henry']

df.loc[:,'列名']  返回的是Series
df.loc[:,['列名']]  返回的是DF

df.iloc[0:3]  # 截取从第0行到第3行的数据,包括第0行,不包括第0行



# 截取 指定行 指定列 的数据
df.loc['Jack':"Merry",'age':"weight"]  # 截取 Jack 到Merry的 age 到 weight 数据

df.iloc[0:2, 1:3] # 截取第 0(包含) 到 2(不包含) 行,第 1(包含) 到 3(不包含) 列的数据
2. 增删数据
增加一行:df.loc["行标签"] = {key:value}
# 使用字典赋值,不必输入所有项,没有输入的编程nan
# df2.loc['006']={'员工姓名':'建军','销售业绩':'30000'}


df.append(DataFrame)末尾增加一行,返回一个新的DF
# row7=DataFrame({'员工姓名':'哈利波特'},index=['007'])
# row7
# df2.append(row7)   # 产生新的DF
增加列
# 给不存在的列标签赋值,会增加一个新列
# 增加一列并且给增加的列赋值,赋值可以是已存在列之间的运算

插入列
# df.insert(loc, column, value, allow_duplicates=False) 
# 参数:loc 插入位置,整数,列的下标位置
#       column 插入列的列名
#       value给插入的列值,值的内容可以是列表、Series

# 在第3列位置插入:年龄
# df2.insert(2,'年龄',[23,25,24,26])
# df2.insert(2,'年龄',Series([20,25,24],index=['001','002','003']))
# 删除列
- del df[列名],注意:这是在原数据上进行删除,不能重复删除
- df.pop("列名"),在原数据上删除指定列,会返回被删除列

# 删除行或列
# df.drop() 可以根据标签删除行或列,index是行标签,column是列标签,inplace来决定是否在原数据上进行。返回删除数据后的df
# df2.drop(labels=None,axis=0,index,columns,inplace=False)
df.drop(['B','C'],axis=1) ,label和axis一起使用,指定列名或行名,和对应的轴向

# 删除多列
df2.drop(columns=['创造收益','是否达标'],inplace=True)
# 删除多行
df2.drop(index=['001,004']) 
3.查询数据
# 找出员工等级为中级的员工
df2[df2['员工等级'].map(lambda x : x=='中级')]

# 找出员工等级为 中级的员工  的姓名
df2.loc[df2['员工等级'].map(lambda x: x.startswith('中')),'员工姓名']

# df.isin(values),判断df中的每个元素是否在value中
# 返回的是bool值
df2['员工等级'].isin(['中级','高级'])

# 返回 员工等级 为True 的 df中的数据
df2[df2['员工等级'].isin(['中级','高级'])]

# 返回 df,为False的显示Nan
df2[df2.isin(['中级','高级'])]

# 多列多条件查询
con = {'员工等级':['中级','高级'],'销售业绩':[20000,50000]}
df2.isin(con)

# 是否有满足条件的,按行(1)输出,按列(0)输出
df2.isin(con).any(1)
# where:返回所有数据,满足条件的数据 会显示;不满足的返回other的值

# 返回的是指定列 df2['员工等级'] 的结果
df2['员工等级'].where(df2['员工等级']=='中级',other = 0)

# 返回的是整个 df2 的结果
df2.where(df2['员工等级']=='中级',other = 0)
# df.query():使用布尔表达式查询DataFrame的列
# 查询条件是字符串,返回的是满足条件的一行数据

df2.query('销售业绩>40000')  == df2[df2.销售业绩>40000]

# 如果值是字符串需要加引号
df2.query("性别=='f'") == df2[df2.性别=='f']

# 
df2.query("(销售业绩>20000) & (员工等级=='中级')")
df2[(df2.销售业绩>40000) & (df2.性别=='f')]
4. DataFrame的运算
4.1 复制copy

"""
姓名 语文 数学 英语
0 杨路 131 143 144
1 王雪 131 135 144
2 韩林霖 127 139 142
3 沙龙逸 123 148 136
"""

# 复制一份
grades2 = grades.copy()
grades2
4.2设置行标签
# 将 姓名列 设置为行标签
df3 = grades.set_index('姓名')
df3

4.3聚合函数
# grades2的平均分
grades2.mean()

# 按人求总分,然后降序排列
grades2.sum(axis=1).sort_values(ascending=False)
# DF和标量运算:每一个数据都 +5
grade3 + 5


# DF和Series运算,df需要调用add方法,然后控制轴向axis="index"
# 每个数据都 +10 ,Series只有index(行标签),只能按照行 +
s1 = Series([10,10,10,10],index=["杨路","王雪","韩林霖","沙龙逸"])
grade3.add(s1,axis='index')
# DF 和 DF运算

x = pd.DataFrame({"a":[1,2,3],
                 "b":[2,3,4],
                 "c":[3,4,5]})
x

y = pd.DataFrame({"a":[1,2,3],
                 "b":[2,3,4],
                 "d":[3,4,5]},
                 index=[1,2,3])
y

总结

DataFrame 和 一个数、nuympy 广播机制

DataFrame 和 数组(Series) 索引对齐,axis控制方向,需要使用内置方法进行

DataFrame 和 DataFrame 索引对齐,不分方向

5.Python 操作符与pandas操作函数的对应表
Python OperatorPandas Method(s)
+add()
-sub(), subtract()
*mul(), multiply()
/truediv(), div(), divide()
//floordiv()
%mod()
**pow()
四. 缺失值、重复值处理

Pandas 中主要有两种缺失值:None和np.nan。Pandas将None和np.nan都视作np.nan。np.nan是浮点类型,能参与到计算中。但计算的结果总是NaN。但可以使用np.nan*()函数来计算nan,此时视nan为0。

1. 查看缺失值

为了使检测到的缺失值更容易(并且跨不同列和数据类型),Pandas 提供了 isnull() 和 notnull() 函数,它们也是 Series 和 DataFrame 对象的方法。

# 元素级别的判断,把对应的所有元素的位置都列出来,元素为空或者NA就显示True,否则就是False。返回一个跟原数据相同的DF,只包含布尔值
df.isnull()
pd.isnull(df)

# 逻辑和isnull相反,不为空是True,为空False
df.notnull()

# 查看所有行或列是否都不为空,通过axis来改变查看方向
df.notnull().all()

# 查看所有行或列是否存在空值,通过axis来改变查看方向
df.isnull().any()

# 统计缺失值个数
df.isnull().sum()
2. 缺失值填充

Pandas 对象具有多种数据处理方法来处理缺失的数据。

  • fillna() 方法可以通过几种方式将非空数据填补到 NA 值的位置。

    # 默认产生新的DF
    df.fillna(value,axis=None,inplace=False,limit=None,method)
    
    # 每个列的数据类型可能不一样,可以对某一列的缺失值用指定的同一值进行填充
    df1.销售业绩.fillna(1000)
    
    # 注意:value参数是不能跟method参数共用的
    # limit限制值填充最近的一行,限制填充次数
    # axis='index' 上下行之间 
    # ffill:用前项填充,
    df1.fillna(axis='index',method='ffill')
    
    # bfill:用后项填充,
    df1.fillna(axis='index',method='bfill')
    
    # 数值型数据可以用均值或者中位数进行填充
    df1
    # 用该列的均值填充
    df1.fillna(df1.mean(axis=0))
    
    # 用该列的中位数填充
    df1.fillna(df1.median())
    
    #只填充指定列
    df1.fillna(df1.mean()['销售业绩':'社保金额'])
    #只填充指定列,一次性填充不相邻的列
    # df1.fillna({'销售业绩':10,'提成收入':222,'创造收益':555})
    
  • replace() 方法把缺失值替换成指定字符

    df.replace(to_replace=None, value=None, inplace=False, limit=None)
    
    # 替换缺失值
    df1.replace(NaN,0)
    
    #用前一条记录对缺失值进行填充,也可以设置limit参数对填充的数量进行限制
    df1.replace(NaN,method='ffill')
    
    # 指定列的替换
    df1.replace({'提成收入':{NaN:22222},'创造收益':{NaN:0}})
    
    # 将DF中所有的2500替换为NaN
    df1.replace(2500,NaN)
    
3. 删除缺失值
df.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)

#可以设定必须整条纪录都是缺失值才进行删除
# how:any 行或列 有一个缺失值就删除该行或列
#   : all  行或列 全是缺失值就删除该行或列
df1.dropna(axis = 'index',how='all')
4. 移除重复数据

DataFrame中经常会出现重复行,利用duplicated()函数返回每一行,判断是否重复的结果(重复则为True).返回新的DF

# 判断每一行是否重复(结果是bool值,TRUE代表重复的)
df1.duplicated()

# 去除重复行
df1.drop_duplicates(
    subset: 列名
    keep: 保留重复项的第几个,默认为'first',
    inplace: 'bool' = False,
    ignore_index: 'bool' = False,
)

#  指定列,去除重复行
df1.drop_duplicates('A')

# 保留重复行中的最后一行,默认保留第一行。
df1.drop_duplicates(keep='last')

# 去除重复的同时改变DataFrame对象
# ignore_index=True :重排行标签
df1.drop_duplicates(inplace=True,ignore_index=True)
五. pandas层次化索引
1.创建多层索引
1> 隐式构造
  • 只支持使用数组表达多级索引的方式来进行构造。
  • 最常见的方法是给DataFrame构造函数的index参数传递两个或更多的数组,只支持数组。
df1 = Series([89,76,90,87],index=[['a','a','b','b'],['英语','数学','英语','数学']]) 
输出:
a  英语    89
   数学    76
b  英语    90
   数学    87
dtype: int64
2> 显示构造pd.MultiIndex

<1> pd.MultiIndex.from_arrays

# 使用数组构造有多级索引的Series
index = pd.MultiIndex.from_arrays(
    [['期中','期中','期中','期末','期末','期末'],
    ['语文','数学','英语','语文','数学','英语']])

ser2 = Series(np.random.randint(40,100,6),index=index)
ser2
# 使用数组构造多级索引的DataFrame

# 行标签,每一级为一个列表,
# 一级:['期中','期中','期中','期末','期末','期末']
# 另一级:['语文','数学','英语','语文','数学','英语']

index = pd.MultiIndex.from_arrays(
    [['期中','期中','期中','期末','期末','期末'],
     ['语文','数学','英语','语文','数学','英语']])
columns = ['lucy','tom','jack','rose','mery']
df1 = DataFrame(np.random.randint(20,120,size =(6,5)),
                index=index,columns=columns)
                
       lucy tom jack rose mery
期中	语文 97  70  38  67  21
     数学	58	94	71	33	85
     英语	35	65	83	21	82
期末	语文 99  110 42  76  89
     数学	114	117	52	52	40
     英语 102	37	72	77	41

<2> pd.MultiIndex.from_tuples

# 行标签,同一行的两个级的标签以 元组 的形式存在
index=pd.MultiIndex.from_tuples([
    ('期中','语文'),('期中','数学'),
    ('期中','英语'),('期末','语文'),
    ('期末','数学'),('期末','英语')])
columns=['Lucy','tom','jack','rose','mery']
df = DataFrame(np.random.randint(1,100,size=(6,5)),
               index=index,
               columns=columns)

<3> pd.MultiIndex.from_product

# 行标签,级与级之间 自动 进行 笛卡尔积 运算
# 最简单,推荐使用
# 
index=pd.MultiIndex.from_product([['期中','期末'],['语文','数学','英语']])
columns=['Lucy','Tom','Jack','Mary','Rose']
df = DataFrame(
    np.random.randint(20,100,size=(6,5)),
    index=index,
    columns=columns
)
df

       lucy tom jack rose mery
期中	语文 97  70  38  67  21
     数学	58	94	71	33	85
     英语	35	65	83	21	82
期末	语文 99  110 42  76  89
     数学	114	117	52	52	40
     英语 102	37	72	77	41
3>多层索引一维化
df.columns.
# 多层级索引相关操作包括stack和unstack,set_index和reset_index,以及指定level的相关方法。
2. 多层索引对象的索引与切片操作
1> Series的操作

对于Series来说,直接中括号[]与使用.loc()完全一样,推荐使用.loc中括号索引和切片

期中  语文     71
    数学     59
    英语     35
期末  语文     82
    数学     45
    英语    104
dtype: int32

# 使用.loc直接访问
s.loc['期中','语文']
s.loc['期中']

# 使用.iloc访问值,通过下标访问
s.iloc[0]  # 71

# 直接使用[]
s['期中','语文']  # 71
s['期中']['语文']  # 71

# 切片
s['期中'].loc['语文':'数学']
s['期中'].iloc[0:2]
s['期中'].iloc[[0,2]]
2> DataFrame的操作
   期中	       期末
   py  php	ja  py 	php	ja
0	8	49	95	69	86	20
1	98	23	98	53	11	72
2	8	49	19	53	16	44
3	14	1	16	19	2	51
4	33	44	53	70	86	2
# 直接[],取得第一级索引 期中 这一列的数据
df['期中']

# 直接通过2级索引获取一个元素,期中-py-0行
# 三个等价
df['期中'].loc[0,'python']
df['期中'].iloc[0,0]
df['期中']['python'][0]

# 两级索引获取一列,期中-php
df['期中','php']

# 切片
# 先访问行
df.iloc[0]
df.iloc[:2,:3]
六. pandas 的拼接操作
1.级联-cancat
concat(objs, axis=0, join='outer', join_axes=None, 
       ignore_index=False, 
       keys=None, levels=None, names=None, 
       verify_integrity=False, copy=True): 
objs:需要连接的对象的集合,一般是列表或字典;
axis:连接轴向;
join:参数为‘outer’或‘inner’;
join_axes=[]:指定自定义的索引;
keys=[]:创建层次化索引;
ignore_index=True:重建索引
# 默认行级联,可以使用ignor_index参数来重置索引
# 结果包含所有列
pd.concat([df1,df2])     ===> pd.concat([df1,df2],axis = 'index')

# 使用axis参数控制级联方向,按列索引
pd.concat([df1,df2],axis = 'columns')
keys=[]:创建层次化索引;
# 增加一层标签
pd.concat([df3,df4],keys=['a','b'])

员工姓名	销售业绩	提成收入	基本工资	社保金额	创造收益	年龄	是否达标
a	1	赵一	30000.0	6000.0	2500	125.0	NaN	NaN	NaN
    2	钱明	20000.0	4000.0	2500	125.0	NaN	NaN	NaN
    3	周元	50000.0	10000.0	2500	125.0	NaN	NaN	NaN
b	2	NaN	NaN	NaN	2500	125.0	13500.0	32.0	False
    3	NaN	NaN	NaN	2500	125.0	37500.0	30.0	True
    4	NaN	NaN	NaN	2500	125.0	NaN	24.0	False
    
    
# concat可以实现dataframe和series的拼接
# 按照行索引,在列上添加
ser1 = pd.Series(["正常","冻结","正常","正常",],name = "社保状态")
pd.concat([df,ser1],axis=1)
# join=inner 内连接  两个表的交集,outer 两个表的并集

# axis=1,在列上拼接,左右
# join = 'inner':内连接,取两个DF的行的交集
pd.concat([df3,df4],join = 'inner',axis=1)
# join = 'outer':外连接,取两个DF的行的并集
pd.concat([df3,df4],join = 'outer',axis=1)

# axis=0,在行上拼接,上下
# join = 'inner':取两个DF的列的交集
pd.concat([df3,df4],join = 'inner',axis=0)
# join = 'outer':取两个DF的列的交集
pd.concat([df3,df4],join = 'outer',axis=0)
2. 级联-append
# 把一个表追加到另一个的后边
# 谁在先,谁在上面
df3.append(df4)

#去掉原来表格的索引,用默认索引
df3.append(df4,ignore_index=True)
3. 合并-merge

逻辑类似于sql中的join,
merge与concat的区别在于,merge需要依据某一共同的行或列来进行合并。
使用pd.merge()合并时,会自动根据两者相同column名称的那一列,作为key来进行合并。
注意每一列元素的顺序不要求一致。

merge(left, right, how='inner', on=None, left_on=None, right_on=None,  
      left_index=False, right_index=False, sort=True,  
      suffixes=('_x', '_y'), copy=True, indicator=False)

参数介绍:
left和right:两个不同的DataFrame;
how:连接方式,有inner、left、right、outer,默认为inner;
on:指的是用于连接的列索引名称,必须存在于左右两个DataFrame中,如果没有指定且其他参数也没有指定,则以两个DataFrame列名交集作为连接键;
left_on:左侧DataFrame中用于连接键的列名,这个参数左右列名不同但代表的含义相同时非常的有用;
right_on:右侧DataFrame中用于连接键的列名;
left_index:使用左侧DataFrame中的行索引作为连接键;
right_index:使用右侧DataFrame中的行索引作为连接键;
sort:默认为True,将合并的数据进行排序,设置为False可以提高性能;
suffixes:字符串值组成的元组,用于指定当左右DataFrame存在相同列名时在列名后面附加的后缀名称,默认为('_x', '_y');
copy:默认为True,总是将数据复制到数据结构中,设置为False可以提高性能;
indicator:显示合并数据中数据的来源情况
#  没有指定连接键,默认用重叠列名
# 一对一连接
pd.merge(t1,t2)

# 一对多连接
pd.merge(t1,t3)

# 1. 默认把字段名字(列标签)相同的列作为合并的依据
# 2. 默认如果有多个列的标签相同,则会同时参考多列合并
# 多对多连接
pd.merge(t3,t4)
# on 指定参与合并的列,用于有多列标签相同的情况
# t3,t4张表以“手机型号”关联
pd.merge(t3,t4,on='手机型号')

# lef_on/right_on
# left_on/right_on 分别指定左右表参与合并的列,用于两张表参与合并的列标签不同的情况
# 生成一个新表t5,t5是t1的复制,修改t5的手机型号列名为型号
t5=t1.copy()
t5.rename(columns=lambda x:'型号' if x=='手机型号' else x,inplace=True)

# 如果合并的列名称不同,会自动保留所有的原始列,可以用户自己决定删除哪一列
# 合并t5,t2
pd.merge(t5,t2,left_on='型号',right_on='手机型号')
# t1和t2连接,采取inner模式
# inner模式,只保留连接字段上相等的记录
# how默认为inner
pd.merge(t1,t2)

# how='left' 左连接,以左表为主,保留左表所有记录,
# 如果右表不存在可连接的记录,则右表并过来的字段设置为nan
pd.merge(t1,t2,how='left')

# how='right' 右连接,以坐标为主,保留左表所有记录,
# 如果左表不存在可连接的记录,则左表并过来的字段设置为nan
pd.merge(t1,t2,how='right')

# how="outer" 外连接,是左连接和右连接记录之并
pd.merge(t1, t2, how='outer')
suffiexes:重复列添加后缀
suffiexes一般与on参数一起使用,给相同列标签但是没有参与合并的列添加后缀

# 合并只能参考列来合并
df1 = DataFrame(data={
    "张三":["A","B","C"],
    "李四":["B","B","A"],
    "王老五":["C","B","C"]
})

df2 = DataFrame(data={
    "张三":["A","B","C"],
    "李四":["C","D","E"]
})

pd.merge(df1, df2, on="张三", suffixes=["_大","_小"])

  张三  李四_大  王老五	  李四_小
0	A	B		C		C
1	B	B		B		D
2	C	A		C		E
4.高级聚合

使用groupby分组后,也可以使用transform和apply提供自定义函数实现更多的运算

  • df.groupby(‘item’)[‘price’].sum() <==> df.groupby(‘item’)[‘price’].apply(sum)
  • transform和apply都会进行运算,在transform或者apply中传入函数即可
  • transform和apply也可以传入一个lambda表达式
1.map()函数用法
  • map()可以使用字典映射新一列数据

  • map()中可以使用lambd表达式

  • map()中可以使用方法,可以是自定义的方法

    # 将java的成绩显示为等级:90-100A\ 80-89 B\ 70-79C\ 60-69D\ 0-59 E
    def level(value):
        if 90 <= value <= 100:
            return 'A'
        elif 80 <= value <= 89:
            return 'B'
        elif 70<=value<=79:
            return 'C'
        elif 60<=value<=69:
            return 'D'
        elif 0<=value<=59:
            return 'E'
        else:
            return '成绩不正确'
            
    df['java']=df.java.map(level)
    df
    
2.agg()函数
# 常用于groupby之后,多分组后的数据做聚合操作,传入的是函数名

# 每个列有不同的聚合
data.groupby(['order_type']).agg({'total_amount':['sum','count']})

# 对列进行聚合
df.agg("mean", axis="columns")

# 在行上聚合这些函数
df.agg(['sum', 'min'])

4. 可视化图表(画图)

一. matplotlib
# 在jupyter中执行的时候显示图片
import matplotlib.pyplot as plt
import matplotlib.style as style
%matplotlib inline
# 画布风格
style.use("fivethirtyeight")

# 识别中文:黑体 SimHei 仿宋 FangSong 楷体 KaiTi
plt.rcParams["font.sans-serif"] = ["SimHei"]
# 配置中文下负号不识别问题
plt.rcParams["axes.unicode_minus"] = False

# 画布的大小
plt.rcParams["figure.figsize"] = (10,6.18)

# 科学计数法
np.set_printoptions(suppress=True)
pd.set_option("display.float_format",lambda x : "%.3f"%x)
第一种 绘图
#首先,定义x的取值范围,生成取值在-10~10之间的100个浮点数
x = np.linspace(-10,10,num=100)
y = x**2   
# 绘制
plt.plot(x,y)
# 显示图表
plt.show()

第二种 绘图
# 绘图
# kind=图表类型(line,bar,barh,hist,box,pie,scatter)
# hist-直方图
# ax=子画布
# figsize=画布大小
# title=子画布名字
# x=x轴的数据,列名将作为x轴的名字
# y=y轴的数据,列名将作为x轴的名字
# sharex,sharey:共用x或者y轴,当subplots=True时,才可以设置共享
weather.plot(kind='scatter',x='最高气温',y='最低气温')

# 子画布 ax2的设置
ax2.pie(byclass.values,autopct="%.2f%%",wedgeprops=dict(width=0.3, edgecolor='r'),labels=byclass.index)

# wedgeprops=dict(width=0.3, edgecolor='r') 显示环图
# .axis():设置坐标轴外观、设置坐标轴范围

plt.figure(figsize=(5,5))
x = np.linspace(-1,1, 100)
y = x**2
plt.plot(x,y)
# 调整横纵轴的比例,或者绘图区的形状 equal,scaled,square
plt.axis('equal')
# 隐藏横轴和纵轴
plt.axis('off')

# x轴标签:名字=x-axis,绿色,旋转90,字体大小30
plt.xlabel('x-axis',color='blue',rotation=90,fontsize=30)
# 纵轴标签默认是90°,fontsize=20
# 位置 loc
plt.ylabel('y-axis',fontsize=20,loc='top')


# X、Y轴坐标刻度
# plt.xticks()和plt.yticks()方法,需指定刻度值和刻度名称--plt.xticks([刻度列表],[名称列表])
# 参数:fontsize、旋转角度rotation、color等参数设置
# 刻度:[0,1,2,3,4],刻度标签:["lucy","tom","jack","mery","lilei"]
plt.xticks([0,1,2,3,4],["lucy","tom","jack","mery","lilei"])
# 画布标题 :plt.title()==axes.set_title()
# 参数:设置标题label,loc {left,center,right},color 标签颜色,fontsize 字体大小,rotation 旋转角度

plt.figure(figsize=(10,3))

ax1 = plt.subplot(1,2,1)
ax1.plot(x, np.sin(x))
# 设置标题,loc,color,fontsize
ax1.set_title(label='ax1',loc='center',color='red',fontsize=15)

ax2 = plt.subplot(1,2,2)
ax2.plot(x, np.cos(x))
# 设置标题, rotation,color,fontsize
ax2.set_title(label='ax2',rotation=-45,color='b',fontsize=15)
plt.show()
# 添加图例的方法
plt.plot(x, np.sin(x), label="SIN(X)")
plt.plot(x, np.cos(x), label="COS(X)")
# 开启图例,图例会显示每一个绘图(不止plot)函数中的label参数的值显示出来
plt.legend(loc=0,labelcolor ='red')
plt.show()
# 保存图片
figure = plt.figure(figsize=(10,3), facecolor='orange')
x = np.linspace(0,2*np.pi, 100)
plt.plot(x,np.sin(x))
# 保存图片的背景色以savefig函数为准,分辨率dpi,背景色facecolor
figure.savefig(fname='L.png',dpi=50,facecolor='w')
点和线的样式
颜色color
透明度alpha
线性linestyle--ls
线宽linewidth--lw
点型marker='o','d','*','-','x','+','D'
点的大小markersize
点的主体颜色markerfacecolor
点的边线颜色markeredgecolor
点的边线宽度markeredgewidth

二. seaborn

基于Matplotlib的数据可视化库

import seaborn as sns
#设置画布的风格和设置中文
sns.set_style('darkgrid',{'font.sans-serif':['SimHei','Arial']})

#小费数据集
tips = sns.load_dataset('tips')
#绘制图表
# hue数据分类
# palette颜色
sns.barplot(x='day',y='tip',hue='sex',data=tips,palette='hls')
#保存图片
plt.savefig('sns_tips_bar.png',dpi=200

x轴的名字

sharex,sharey:共用x或者y轴,当subplots=True时,才可以设置共享

weather.plot(kind=‘scatter’,x=‘最高气温’,y=‘最低气温’)

子画布 ax2的设置

ax2.pie(byclass.values,autopct="%.2f%%",wedgeprops=dict(width=0.3, edgecolor=‘r’),labels=byclass.index)

wedgeprops=dict(width=0.3, edgecolor=‘r’) 显示环图


.axis():设置坐标轴外观、设置坐标轴范围

plt.figure(figsize=(5,5))
x = np.linspace(-1,1, 100)
y = x**2
plt.plot(x,y)

调整横纵轴的比例,或者绘图区的形状 equal,scaled,square

plt.axis(‘equal’)

隐藏横轴和纵轴

plt.axis(‘off’)

x轴标签:名字=x-axis,绿色,旋转90,字体大小30

plt.xlabel(‘x-axis’,color=‘blue’,rotation=90,fontsize=30)

纵轴标签默认是90°,fontsize=20

位置 loc

plt.ylabel(‘y-axis’,fontsize=20,loc=‘top’)

X、Y轴坐标刻度

plt.xticks()和plt.yticks()方法,需指定刻度值和刻度名称–plt.xticks([刻度列表],[名称列表])

参数:fontsize、旋转角度rotation、color等参数设置

刻度:[0,1,2,3,4],刻度标签:[“lucy”,“tom”,“jack”,“mery”,“lilei”]

plt.xticks([0,1,2,3,4],[“lucy”,“tom”,“jack”,“mery”,“lilei”])


画布标题 :plt.title()==axes.set_title()

参数:设置标题label,loc {left,center,right},color 标签颜色,fontsize 字体大小,rotation 旋转角度

plt.figure(figsize=(10,3))

ax1 = plt.subplot(1,2,1)
ax1.plot(x, np.sin(x))

设置标题,loc,color,fontsize

ax1.set_title(label=‘ax1’,loc=‘center’,color=‘red’,fontsize=15)

ax2 = plt.subplot(1,2,2)
ax2.plot(x, np.cos(x))

设置标题, rotation,color,fontsize

ax2.set_title(label=‘ax2’,rotation=-45,color=‘b’,fontsize=15)
plt.show()


添加图例的方法

plt.plot(x, np.sin(x), label=“SIN(X)”)
plt.plot(x, np.cos(x), label=“COS(X)”)

开启图例,图例会显示每一个绘图(不止plot)函数中的label参数的值显示出来

plt.legend(loc=0,labelcolor =‘red’)
plt.show()


保存图片

figure = plt.figure(figsize=(10,3), facecolor=‘orange’)
x = np.linspace(0,2*np.pi, 100)
plt.plot(x,np.sin(x))

保存图片的背景色以savefig函数为准,分辨率dpi,背景色facecolor

figure.savefig(fname=‘L.png’,dpi=50,facecolor=‘w’)


点和线的样式
颜色color
透明度alpha
线性linestyle–ls
线宽linewidth–lw
点型marker=‘o’,‘d’,’*’,’-’,‘x’,’+’,‘D’
点的大小markersize
点的主体颜色markerfacecolor
点的边线颜色markeredgecolor
点的边线宽度markeredgewidth


#### 二. seaborn

基于Matplotlib的数据可视化库

import seaborn as sns
#设置画布的风格和设置中文
sns.set_style(‘darkgrid’,{‘font.sans-serif’:[‘SimHei’,‘Arial’]})

#小费数据集
tips = sns.load_dataset(‘tips’)
#绘制图表

hue数据分类

palette颜色

sns.barplot(x=‘day’,y=‘tip’,hue=‘sex’,data=tips,palette=‘hls’)
#保存图片
plt.savefig(‘sns_tips_bar.png’,dpi=200

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值