1. 概述
numpy介绍
numpy 是使用Python进行科学计算的基础包。它包含如下的内容:
- 一个强大的N维数组对象。
- 复杂的(广播)功能。
- 用于集成C / C ++和Fortran代码的工具。
- 有用的线性代数,傅里叶变换和随机数功能。 除了明显的科学用途外,NumPy还可以用作通用数据的高效多维容器。可以定义任意数据类型。这使NumPy能够无缝快速地与各种数据库集成。
NumPy是在BSD许可下获得许可的,允许重用而不受限制。
pandas介绍
pandas 是一个开源的,BSD许可的库,为Python (opens new window)编程语言提供高性能,易于使用的数据结构和数据分析工具。
Pandas是NumFOCUS (opens new window)赞助的项目。这将有助于确保Pandas成为世界级开源项目的成功,并有可能捐赠 (opens new window)给该项目。
2. numpy数据分析
numpy属性
import numpy as np
array = np.array([[1, 2, 3], # 定义矩阵
[2, 3, 4]])
print(array)
print(f"number of dim: {array.ndim}") # 维度
print(f"shape: {array.shape}") # 多少行,多少列
print(f"size: {array.size}") # 有多少元素
numpy的创建array
定义一维数组
import numpy as np
a = np.array([2, 3, 4], dtype=np.int) # 定义数字格式
print(a) # 没有逗号分隔列表
print(a.dtype) # 打印数字格式 int、float默认64位
a_arange = np.arange(10, 20, 2) # 定义一个有序数组 [起始、终止)、步长
a_split = np.linspace(1, 10, 4) # 定义一个分段数列 [起始、终止]、分成几段
print(f"a_arange: {a_arange}")
print(f"a_split: \n{a_split}")
定义多维矩阵
import numpy as np
m = np.array([[2, 3, 4],
[3, 4, 5]]) # 生成矩阵
print(m)
mzeros = np.zeros((3, 4)) # 定义零元矩阵
mones = np.ones((3, 4)) # 定义1元矩阵
mempty = np.empty((3, 4)) # 定义几乎为0的空矩阵
m_arange = np.arange(12).reshape((3, 4)) # 定义一个有序矩阵
m_split = np.linspace(1, 10, 6).reshape((2, 3)) # 定义一个分段矩阵
print(f"mzeros: \n{mzeros}")
print(f"mones: \n{mones}")
print(f"mempty: \n{mempty}")
print(f"m_arange: \n{m_arange}")
print(f"m_split: \n{m_split}")
numpy的基础运算
数组运算
import numpy as np
a = np.array([10, 20, 30, 40])
b = np.arange(1, 5)
print(f"a = {a}")
print(f"b = {b}")
print(f"a+b = {a+b}")
print(f"a-b = {a-b}")
print(f"b^2 = {b**2}")
print(f"sin(a) = {np.sin(a)}")
print(f"cos(a) = {np.cos(a)}")
print(f"exp(a) = {np.exp(a)}")
print(f"b<3 = {b<3}") # b的数值小于3?
print(f"b=3 = {b==3}") # b的数值等于3?
矩阵计算
import numpy as np
a = np.array([[1, 1],
[0, 1]])
b = np.arange(1, 5).reshape((2, 2))
print(f"a : \n{a}")
print(f"b : \n{b}")
print(f"a*b : \n{a*b}") # 元素逐个相乘
print(f"a@b : \n{np.dot(a, b)}") # 矩阵乘法 等价于 a.dot(b)
import numpy as np
a = np.random.random((2, 4)) # 从(0, 1)随机创建一个矩阵 2行4列
print(f"a = \n{a}")
print(f"sum(a) = {np.sum(a)}") # 矩阵元素的和
print(f"min(a) = {np.min(a)}") # 矩阵元素的最小值
print(f"max(a) = {np.max(a)}") # 矩阵元素的最大值
print(f"行sum(a) = {np.sum(a, axis=1)}") # 每行的和
print(f"列min(a) = {np.min(a, axis=0)}") # 每列的最小值
import numpy as np
A = np.arange(14, 2, -1).reshape((3, 4))
print(f"A = \n{A}")
print(f"min(A)_arg = {np.argmin(A)}") # 矩阵A最小值的索引
print(f"max(A)_arg = {np.argmax(A)}") # 矩阵A最大值的索引
print(f"mean(A) = {np.mean(A)}") # 平均值 等价于A.mean()或np.average(A)
print(f"median(A) = {np.median(A)}") # 中位数
print(f"cumsum(A) = {np.cumsum(A)}") # 矩阵A各元素累加
print(f"diff(A) = \n{np.diff(A)}") # 矩阵A各元素累差
print(f"nonzero(A) = {np.nonzero(A)}") # 矩阵的非零元素索引 行--列
print(f"sort(A) = \n{np.sort(A)}") # 对矩阵逐行按从小到大进行排序
print(f"transpose(A) = \n{A.T}") # 矩阵转置,等价于np.tranpose(A)
print(f"clip(A) = \n{np.clip(A, 5, 9)}") # 所有矩阵元素值小于5的变为5,大于9的变为9,其他数不变
numpy的索引
import numpy as np
A = np.arange(3, 15).reshape((3, 4))
print(f"A = \n{A}")
print(f"A[2] = {A[2]}") # 矩阵按行索引 第三行
print(f"A[1][1] = {A[1][1]}") # 矩阵按元素索引 第二行第二列 等价于A[1, 1]
print(f"A[2, :] = {A[2, :]}") # 矩阵第三行的所有数
print(f"A[:, 1] = {A[:, 1]}") # 矩阵第二列的所有数
print(f"A[2, 0:2] = {A[2, 0:2]}") # 矩阵第三行的第一个数到第二个数
print("矩阵按行输出: ")
for row in A: # 按行输出
print(row)
print("矩阵按列输出: ")
for column in A.T: # 按列输出
print(column)
print("矩阵按元素输出: ")
for item in A.flat: # 迭代器 将矩阵拉直为行向列
print(item)
numpy的array合并
import numpy as np
A = np.array([1, 1, 1])
B = np.array([2, 2, 2])
print(f"A = {A}")
print(f"B = {B}")
print(f"vertical stack: \n{np.vstack((A, B))}") # 将A、B上下合并
print(f"horizontal stack: \n{np.hstack((A, B))}") # 将A、B左右合并
print(f"A column dim: \n{A[np.newaxis, :]}") # 在A的行上加维度, 将序列变为矩阵
print(f"A row dim: \n{A[:, np.newaxis]}") # 在A的列上加维度, 将序列变为矩阵
print(f"arrays combine: \n{np.concatenate((A, B, B, A), axis=0)}") # 多个数组横向合并 默认水平合并
numpy的array分割
import numpy as np
A = np.arange(12).reshape((3, 4))
print(f"A: \n{A}")
print(f"split row: \n{np.split(A, 3, axis=0)}") # 将A按行均分为三部分
print(f"split column: \n{np.split(A, 2, axis=1)}") # 将A按列均分为两部分
print(f"split neq column: \n{np.array_split(A, 3, axis=1)}") # 将A按列不等分为三部分 2,1,1
print(f"vsplit(A): \n{np.vsplit(A, 3)}") # 将A按纵向分为三块
print(f"hsplit(A): \n{np.hsplit(A, 2)}") # 将A按横向分为两块
numpy的copy & deep copy
import numpy as np
a = np.arange(4)
print(f"a = {a}")
b = a # numpy copy 将a的值赋给b,且关联a
c = a.copy() # deep copy 将a的值赋给c,但不关联a
a[1:3] = [22, 33]
print(f"a = {a}")
print(f"b = {b}")
print(f"c = {c}")
3. pandas数据处理
pandas基础介绍
创建一维数表
import pandas as pd
import numpy as np
s = pd.Series([1, 3, 6, np.nan, 44, 1]) # 创建一个序列
print(f"s = \n{s}") # 打印列表,自动添加序号和数据类型
打印时间数表
dates = pd.date_range('2020.12.16', periods=6)
print(f"dates = {dates}") # 打印时间列表
指定序列索引
df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=['a', 'b', 'c', 'd']) # 行索引index 列索引columns
df1 = pd.DataFrame(np.arange(12).reshape((3, 4)))
df2 = pd.DataFrame({'A': 1.,
'B': pd.Timestamp('20130102'),
'C': pd.Series(1, index=list(range(4)), dtype='float32'),
'D': np.array([3]*4, dtype='int32'),
'E': pd.Categorical(['test', 'train', 'test', 'train']),
'F': 'foo'})
更多的数据处理
print(f"df2.dtypes = \n{df2.dtypes}") # 打印每一列的数据格式
print(f"df2.index = \n{df2.index}") # 打印每一列序号
print(f"df2.columns = \n{df2.columns}") # 打印每一列的名字
print(f"df2.values = \n{df2.values}") # 打印每一列的值
print(f"df2.describe = \n{df2.describe()}") # 打印每一列的统计信息
print(f"df2.T = \n{df2.T}") # 打印矩阵转置后结果
将表格排序
print(f"df2.sort_column = \n{df2.sort_index(axis=1, ascending=False)}") # 将表格按列名称逆序排序
print(f"df2.sort_row = \n{df2.sort_index(axis=0, ascending=False)}") # 将表格按行名称逆序排序
print(f"df2.sort_values = \n{df2.sort_values(by='E')}") # 将表格按E列值排序
pandas筛选数据
将表格切片
import pandas as pd
import numpy as np
dates = pd.date_range('2020.12.16', periods=6)
df = pd.DataFrame(np.arange(24).reshape((6, 4)), index=dates, columns=['A', 'B', 'C', 'D'])
print(f"df = \n{df}")
print(f"df.A = \n{df.A}") # 列标为'A'的列 等价于df['A']
print(f"df[0:3] = \n{df[0:3]}") # 从第一行到第三行切片 等价于df['2020-12-16':'20201218']
用loc方法筛选数据
# select by label: loc
print(f"df.loc['20201216'] : \n{df.loc['20201216']}") # 以行标签索引选择
print(f"df.loc[:, ['A', 'B']] : \n{df.loc[:, ['A', 'B']]}") # 所有行,以列标签索引选择
print(f"df.loc['20201220', ['A', 'B']] : \n{df.loc['20201220', ['A', 'B']]}") # 某一行,以列标签索引选择
用iloc方法筛选数据
# select by position: iloc
print(f"df.iloc[3] : \n{df.iloc[3]}") # 选择第四行数据
print(f"df.iloc[3, 0] : \n{df.iloc[3, 0]}") # 选择第四行第一列数据
print(f"df.iloc[3:5, 1:3] : \n{df.iloc[3:5, 1:3]}") # 切片
print(f"df.iloc[[1, 3, 5], 1:3] : \n{df.iloc[[1, 3, 5], 1:3]}") # 逐个选择
# Boolean indexing
print(f"df[df.A > 8] : \n{df[df.A > 8]}") # 选择满足条件的数据
pandas设置值
import pandas as pd
import numpy as np
dates = pd.date_range('20201216', periods=6)
df = pd.DataFrame(np.arange(24).reshape((6, 4)), index=dates, columns=['A', 'B', 'C', 'D'])
print(f"df: \n{df}")
df.iloc[2, 2] = '@' # 根据位置改值
df.loc['20201218', 'B'] = '$' # 根据标签改值
df[df.A > 10] = '*' # 根据值更改信息(df.A[]则只会更改A列的数据)
df['E'] = np.nan # 增加列
df['F'] = pd.Series([1, 2, 3, 4, 5, 6], index=pd.date_range('20201216', periods=6)) # 增加列 用指定序列填充
print(f"df: \n{df}")
pandas处理丢失数据
丢数据
import pandas as pd
import numpy as np
dates = pd.date_range('20201216', periods=6)
df = pd.DataFrame(np.arange(24).reshape((6, 4)), index=dates, columns=['A', 'B', 'C', 'D'])
df.iloc[0, 1] = np.nan
df.iloc[1, 2] = np.nan
print(f"df: \n{df}")
print(f"df.dropna_row: \n{df.dropna(axis=0, how='any')}") # 丢掉有丢失数据的行,出现任何一个nan就丢 how:{'any', 'all'}
print(f"df.dropna_row: \n{df.dropna(axis=1, how='all')}") # 丢掉有丢失数据的列,全部都是nan才丢
改数据
print(f"df.fillna_0: \n{df.fillna(value=0)}") # 将丢失数据改为0
print(f"df.isnull(): \n{df.isnull()}") # 值是否为丢失数据
print(f"np.any(df.isnull()): \n{np.any(df.isnull()) == True}") # 是否有缺失值
pandas导入导出文件
import pandas as pd
import numpy as np
# 读取 read_XXX 读取XXX格式的文件
# 保存 to_XXX 保存为XXX格式的文件
data = pd.read_csv('dataname.csv') # 读取数据文件
print(f"show data: \n{data}")
data.to_csv('data.csv') # 保存数据文件
pandas合并concat
直接合并
import pandas as pd
import numpy as np
# concatennating
df1 = pd.DataFrame(np.ones((3, 4))*0, columns=['a', 'b', 'c', 'd'])
df2 = pd.DataFrame(np.ones((3, 4))*1, columns=['a', 'b', 'c', 'd'])
df3 = pd.DataFrame(np.ones((3, 4))*2, columns=['a', 'b', 'c', 'd'])
print(f"df1: \n{df1}")
print(f"df2: \n{df2}")
print(f"df3: \n{df3}")
res1 = pd.concat([df1, df2, df3], axis=0, ignore_index=True) # 竖向合并三个数表,重新标号
print(f"res1: \n{res1}")
合并前裁剪
# join, ['inner', 'outer']
df4 = pd.DataFrame(np.ones((3, 4))*0, columns=['a', 'b', 'c', 'd'], index=[1, 2, 3])
df5 = pd.DataFrame(np.ones((3, 4))*1, columns=['b', 'c', 'd', 'e'], index=[2, 3, 4])
print(f"df4: \n{df4}")
print(f"df5: \n{df5}")
res2 = pd.concat([df4, df5], join='inner', ignore_index=True) # 合并,裁剪不同部分
res3 = pd.concat([df4, df5], join='outer', ignore_index=True) # 合并,不同部分为NaN
print(f"res2: \n{res2}")
print(f"res3: \n{res3}")
添加数据
# append
res5 = df4.append(df5, ignore_index=True) # 将df5加到df4下面
print(f"res5: \n{res5}")
df6 = pd.DataFrame(np.ones((3, 4))*1, columns=['c', 'd', 'e', 'f'], index=[3, 4, 5])
res6 = df4.append([df5, df6], ignore_index=True) # 将df5, df6加到df4下面
print(f"res6: \n{res6}")
s1 = pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])
res7 = df4.append(s1, ignore_index=True) # 添加一行到最下面
print(f"res7: \n{res7}")
pandas合并merge
一个简单的例子
import pandas as pd
import numpy as np
# merging two df by key/keys.(may be used in database)
# simple example
left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
'C': ['C0', 'C1', 'C2', 'C3'],
'D': ['D0', 'D1', 'D2', 'D3']})
print(f"left: \n{left}")
print(f"right: \n{right}")
res = pd.merge(left, right, on='key') # 合并左右两个数表 基于指标为'key'的列合并
print(f"res: \n{res}")
考虑两个指标
# consider two keys
left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
'key2': ['K0', 'K1', 'K0', 'K1'],
'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
'key2': ['K0', 'K0', 'K0', 'K0'],
'C': ['C0', 'C1', 'C2', 'C3'],
'D': ['D0', 'D1', 'D2', 'D3']})
res = pd.merge(left, right, on=['key1', 'key2'], how='left') # 合并两个数表 索引为key的两列均考虑
# 基于左侧列的指标罗列 how=['left','right','outer','inner']
print(f"left: \n{left}")
print(f"right: \n{right}")
print(f"res: \n{res}")
显示合并信息
# indicator
df1 = pd.DataFrame({'col1': [0, 1], 'col_left': ['a', 'b']})
df2 = pd.DataFrame({'col1': [1, 2, 2], 'col_left': [2, 2, 2]})
res = pd.merge(df1, df2, on='col1', how='outer', indicator=True) # 合并两个数表,考虑col1,没有的用NaN进行填充,显示合并信息
# give the indicator a custom name
res1 = pd.merge(df1, df2, on='col1', how='outer', indicator='indicator_column') # 对信息列命名为indicator_column
print(f"df1: \n{df1}")
print(f"df2: \n{df2}")
print(f"res: \n{res}")
print(f"res1: \n{res1}")
根据指标合并
# merge by index
left = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
'B': ['B0', 'B1', 'B2']},
index=['K0', 'K1', 'K2'])
right = pd.DataFrame({'C': ['C0', 'C1', 'C2'],
'D': ['D0', 'D1', 'D2']},
index=['K0', 'K2', 'K3'])
print(f"left: \n{left}")
print(f"right: \n{right}")
res = pd.merge(left, right, left_index=True, right_index=True, how='outer') # 合并两个数表,考虑两个数表的index指标
print(f"res: \n{res}")
# handle overlapping
boys = pd.DataFrame({'k': ['K0', 'K1', 'K2'], 'age': [1, 2, 3]})
girls = pd.DataFrame({'k': ['K0', 'K0', 'K3'], 'age': [4, 5, 6]})
res = pd.merge(boys, girls, on='k', suffixes=['_boy', '_girl'], how='inner') # 合并两个数表 同一指标改写法合并
print(f"boys: \n{boys}")
print(f"girls: \n{girls}")
print(f"res: \n{res}")
pandas plot画图
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# plot data
# Series
data = pd.Series(np.random.randn(1000), index=np.arange(1000)) # 生成数据
data = data.cumsum() # 累加数据
# DataFrame
data = pd.DataFrame(np.random.randn(1000, 4),
index=np.arange(1000), columns=list("ABCD")) # 四种类型的数据
data = data.cumsum() # 累加数据
print(data.head(6)) # 打印前6个数据 默认为5
# data.plot() # 生成图像
# 'bar', 'hist', 'box', 'kde', 'area', 'hexbin', 'pie'...
ax = data.plot.scatter(x='A', y='B', color='DarkBlue', label='Class 1')
data.plot.scatter(x='A', y='C',color='DarkGreen', label='Class 2', ax=ax)
plt.show() # 显示图像