本文是根据b站路飞学城Python数据分析全套教程的学习视频整理归纳的学习文档,主要目的是方便自己进行查阅,详细的还得去b站看原视频。另外有很多文字都是根据我自己的理解写的,比较小白,欢迎指正。
array() | 将列表转换为数组,可选择显示指定dtype |
---|---|
arange() | range的numpy版,支持浮点数 |
linspace() | 类似arange(),第三个参数为数组长度 |
zeros() | 根据指定形状和dtype创建全0数组 |
ones() | 根据指定形状和dtype创建全1数组 |
empty() | 根据指定形状和dtype创建空数组(随机值) |
eye() | 根据指定边长和dtype创建单位矩阵 |
import numpy as np
np.array([1,2,3])
>>>array([1,2,3])
np.array([0]*10)
>>>array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
np.zeros(10) # 此时该数组的dtype为float64 ,需转换为int才能正常输出0,后面的ones()同理
>>>array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
np.zeros(10, dtype='int')
>>>array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
np.ones(10, dtype='int')
>>>array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
np.arange(起始数,数字个数,步长)
np.linspace(起始数,最终数,数字个数) # 最后得出的数组各数之间步长相同
ndarray-批量运算 |
---|
数组和标量之间的运算 |
a+1 a*3 1//a a**0.5 a>5 |
同样大小数组之间的运算 |
a+b a/b a**b a%b a==b |
import numpy as np
a = np.arange(10)
a
>>>array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
a+1
>>>array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
a*3
>>>array([ 0, 3, 6, 9, 12, 15, 18, 21, 24, 27])
b = np.arange(10,20)
>>>array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
a+b
>>> array([10, 12, 14, 16, 18, 20, 22, 24, 26, 28])
a>b
>>>array([False, False, False, False, False, False, False, False, False,False], dtype=bool)
ndarray-索引 |
---|
一维数组的索引:a[5] |
多维数组的索引: |
列表式写法: a[2]【3】 |
新式写法:a[2,3] |
# 一维数组检索
a = np.arange(10)
a[0]
>>>0
# 二维数组检索
np.arange(15)
>>>array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10a, 11, 12, 13, 14])
a = np.arange(15).reshape((3,5)) # 一维数组转二维数组
>>>array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
a[0][0]
>>>0
a[0,0]
>>>0 # 两种写法
ndarray-切片 |
---|
一维数组的切片:a[5:8] a[4:] a[2:10] = 1 |
多维数组的切片:a[1:2, 3:4] a[:, 3:5] a[:,1] |
数组切片与列表切片的不同:数组切片时并不会自动复制(而是创建一个视图),在切片数组上的修改会影响原数组。 |
copy()方法可以创建数组的深拷贝 |
In [17]: a
Out[17]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [18]: a[0:4]
Out[18]: array([0, 1, 2, 3])
In [19]: a[4:]
Out[19]: array([4, 5, 6, 7, 8, 9])
In [20]: a[:4]
Out[20]: array([0, 1, 2, 3]) # 一维数组的三种切片方式
In [21]: b = list(range(10))
In [22]: b
Out[22]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [23]: c=a[0:4]
In [24]: d = b[0:4]
In [25]: c[0] = 20
In [26]: d[0] = 20
In [27]: c
Out[27]: array([20, 1, 2, 3])
In [28]: d
Out[28]: [20, 1, 2, 3]
# 二维数组
a = np.arange(15).reshape((3,5))
a
>>>array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
a[0:2,0:2]
>>>array([[0, 1],
[5, 6]])
a[1:,2:4] # 前一个代表行,后一个代表列
>>>array([[ 7, 8],
[12, 13]])
Q1:给一个数组,选出数组中所有大于5的数
A1:a[a>5]
Q2: 给一个数组,选出数组中所有大于5的偶数
A2: a[(a>5) & (a%2==0)]
Q3: 给一个数组,选出数组中所有大于5的数和偶数
A3: a[(a>5) | (a%2==0)]
a = [random.randint(0,10) for i in range(20)]
a
>>>[3, 8, 7, 7, 2, 3, 7, 8, 4, 2, 0, 0, 6, 3, 9, 0, 1, 7, 6, 7]
a = np.array(a) # 将a转化为数组
list(filter(lambda x:x>5,a))
>>>[8, 7, 7, 7, 8, 6, 9, 7, 6, 7] # 原方法
a[a>5] # 选出数组中所有大于5的数
>>>array([8, 7, 7, 7, 8, 6, 9, 7, 6, 7])
a>5 # 判断数组的每一位是否大于5
>>>array([False, True, True, True, False, False, True, True, False, False, False, False, True, False, True, False, False, True, True, True])
a = np.arange(4)
a
>>>array([0,1,2,3])
a[[True , False, True, False]]
>>>array([0, 2]) # 对应位的数字不显示
# Q1:给一个数组,选出数组中所有大于5的偶数
a = [random.randint(0,10) for i in range(20)]
a
>>>[10, 9, 0, 10, 6, 8, 0, 5, 7, 3, 10, 3, 10, 1, 9, 5, 9, 5, 8, 4]
a = np.array(a) # 将a转化为数组
# 错误:a[a>5][a%2==0]
b = a[a>5]
b
>>>array([10, 9, 10, 6, 8, 7, 10, 10, 9, 9, 8])
b = b[b%2==0]
b
>>>array([10, 10, 6, 8, 10, 10, 8]) # 第一种方法
a[(a>5) & (a%2==0)]
>>>array([10, 10, 6, 8, 10, 10, 8]) # 第二种方法
# Q2:筛选出数组中大于5的数和偶数
a[(a>5) | (a%2==0)]
>>>array([10, 9, 0, 10, 6, 8, 0, 7, 10, 10, 9, 9, 8, 4])
Q1:对于一个数组,选出其第1,3,4,6,7个元素,组成新的二维数组。
A1:a[[1,3,4,6,7]]
Q2:对一个二维数组,选出其第一列和第三列,组成新的二维数组。
A2:a[:,[1,3]]
a = np.arange(20)
a
>>>array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
# Q1
a[[1,3,4,6,7]]
>>>array([1, 3, 4, 6, 7])
# Q2
a = np.arange(20).reshape(4,5) # 转为二维数组
a
>>>array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]])
a[:,[1,3]]
>>>array([[ 1, 3],
[ 6, 8],
[11, 13],
[16, 18]])
# 将6,8,16,18单独组成一个二维数组
a[[1,3],:][:,[1,3]]
>>>array([[ 6, 8],
[16, 18]])
补充-浮点数特殊值
a = np.arange(-5,5)
a
>>>array([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4])
np.abs(a) # 可以直接写abs(a)
>>>array([5, 4, 3, 2, 1, 0, 1, 2, 3, 4])
np.sqrt(a)
>>>array([nan, nan, nan, nan, nan, 0. , 1. , 1.41421356, 1.73205081, 2. ])
a = np.arange(-5.5,5.5)
a
>>> array([-5.5, -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5])
np.ceil(a) # 向上取整,例1.2取2,-2.3取-3
>>>array([-5., -4., -3., -2., -1., -0., 1., 2., 3., 4., 5.])
np.floor(a) # 向下取整,例1.2取1,-2.3取-2
>>> array([-6., -5., -4., -3., -2., -1., 0., 1., 2., 3., 4.])
np.round(a) # 四舍五入
>>>array([-6., -4., -4., -2., -2., -0., 0., 2., 2., 4., 4.])
np.trunc(a) # 向0取整,
>>>array([-5., -4., -3., -2., -1., -0., 0., 1., 2., 3., 4.])
np.rint(a) # 同round
np.modf(a) # 将小数与整数部分分开
>>>(array([-0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]),
array([-5., -4., -3., -2., -1., -0., 0., 1., 2., 3., 4.]))
a = np.arange(0,5)
>>> array([0, 1, 2, 3, 4])
b = a/a
b
>>>array([nan, 1., 1., 1., 1.])
np.isnan(b) # 判断数组内是否含有nan
>>>array([ True, False, False, False, False])
np.maximum(a,b) # 取出每一位最大的数字
>>>array([nan, 1., 2., 3., 4.]) # nan无法进行比较
np.minimum(a,b) # 取出每一位最小的数字
>>>array([nan, 1., 1., 1., 1.])
统计方法 | 统计方法 | ||
---|---|---|---|
sum | 求和 | min | 求最小值 |
mean | 求平均数 | max | 求最大值 |
std | 求标准差 | argmin | 求最小值索引 |
var | 求方差 | argmax | 求最大值索引 |
a = array([0, 1, 2, 3, 4])
a.sum() # 求和
>>>10
a.mean() # 求平均值
>>>2.0
a.var() # 求方差,方差:每一位数减平均数后平方的和再除以数字的个数
>>>2.0
a.std() # 求标准差,标准差及方差的开根
>>>1.4142135623730951
a.argmax() # 求最大值索引,返回最大值的下标
>>>4
随机数生成
np.random.randint(0,10,10) # 随机生成10个0到10的整数,第三个参数为输出结果的shape,例如第三个参数为(3,5)将会生成三行五列的随机0到10的整数
>>>array([8, 6, 9, 7, 1, 1, 6, 3, 9, 0])
array([0, 1, 2, 3, 4])
np.random.shuffle(a) # 打乱数组
a
>>>array([4, 0, 3, 2, 1])
np.random.rand(10) # 随机生成0到1之间的数组,括号内为输出结果shape
>>>array([0.59299055, 0.62454554, 0.22663945, 0.19710862, 0.40294187, 0.69161135, 0.13875322, 0.62038921, 0.96111296, 0.32484364])
np.random.choice(a,(2,1)) # 在数组中随机选择输出,第二个参数为shape
>>>array([[3],
[4]])
np.random.uniform(2.0,4.0,5) # 生成范围内随机数组,第三个shape
>>>array([3.6005868 , 2.54784429, 2.62126056, 2.45776224, 2.68572162])
series是一种类似于一维数组的对象,由一组数据和一组与之相关的数据标签(索引)组成。
创建方式:pd.Series([4,7,-5,3])
pd.Series([4,7,-5,3],index=[‘a’,‘b’,‘c’,‘d’])
pd.Series({‘a’:1,‘b’:2})
pd.Series(0,index=[‘a’,‘b’,‘c’,‘d’])
获取值数组和索引数组:values属性和index属性
Series比较像列表(数组)和字典的结合体
series-使用特性
series支持array的特性(下标): | series支持字典的特性(标签): |
---|---|
从ndarray创建Series:Series(arr) | 从字典创建Series:Series(dic) |
与标量运算:sr*2 | in运算:‘a’ in sr |
两个Series运算:sr1+sr2 | 键索引:sr[‘a’], sr[[‘a’, ‘b’, ‘d’]] |
索引:sr[0], sr[[1,2,4]] | |
切片:sr[0:2] | |
通用函数:np.abs(sr) | |
布尔值过滤:sr[sr>0] |
import pandas as pd
pd.Series([2,3,4,5])
>>>
0 2
1 3
2 4
3 5
dtype: int64
pd.Series([4,7,-5,3],index=['a','b','c','d']) # 自定义索引
>>>
a 4
b 7
c -5
d 3
dtype: int64
a = array([4, 0, 3, 2, 1])
pd.Series(a) # 对数组
>>>
0 4
1 0
2 3
3 2
4 1
dtype: int32
整数索引的pandas对象往往会使新手抓狂
例:
sr = pd.Series(np.arange(4.))
sr[-1]
如果索引是整数类型,则根据整数进行下标获取值时总是面向标签。
解决方法:loc属性(将索引解释为标签)和iloc属性(将索引解释为下标)
sr = pd.Series(np.arange(20))
>>>
0 0
1 1
2 2
3 3
...
16 16
17 17
18 18
19 19
dtype: int32
sr2 = sr[10:].copy()
sr2
>>>
10 10
11 11
...
17 17
18 18
19 19
dtype: int32
sr2[10] # 此时索引默认为标签,不推荐
>>>10
sr2.loc[10] # 同sr2[10],loc为属性,iloc相反
>>>10
sr2.iloc[9] # 将索引解释为下标
>>>19
会自动根据标签对齐,所以sr1+sr2 最终结果为
>>>
a 33
c 32
d 45
dtype: int64
如果数组sr2中有sr1中不存在的标签,则最后sr1+sr2的结果中该标签的值为NaN
(反之同理)
例:
sr1 = pd.Series([12,23,34],index=['c', 'a', 'd'])
sr2 = pd.Series([11,20,10,15],index=['d', 'c', 'a','b'])
sr1+sr2
>>>
a 33.0
b NaN
c 32.0
d 45.0
dtype: float64
当sr1 = pd.Series([12,23,34],index=[‘c’, ‘a’, ‘d’]),
sr2 = pd.Series([11,20,10],index=[‘b’, ‘c’, ‘a’])时,sr1+sr2的结果中b标签和d标签的值分别为NaN,那如何使结果在索引’b’处的值为11,索引’d’处的值为34呢?
运用算术方法:add,sub,div,mul
sr1.add(sr2,fill_value=0)
例如 sr
sr
>>>
a 33.0
b NaN
c 32.0
d NaN
dtype: float64
在sr中索引’b’和’d’的值都是NaN,缺失状态。对这些缺失值的处理可以有以下几种方法。
1.删除
sr.isnull() # 首先判断是否有缺失值
>>>a False
b True
c False
d True
dtype: bool
# sr.notnull() 返回结果与isnull()相反
sr[sr.notnull()] # 可以删除缺失值
>>>
a 33.0
c 32.0
dtype: float64
sr.dropna() # 可以删除缺失值
2.填充
sr.fillna(0) # 将缺失值填充为'0'
>>>
a 33.0
b 0.0
c 32.0
d 0.0
dtype: float64
sr.fillna(sr.mean()) # 将缺失值填充为平均值
>>>
a 33.0
b 32.5
c 32.0
d 32.5
dtype: float64
DataFrame-二维数据对象
DataFrame是一个表格型的数据结构,含有一组有序的列。DataFrame可以被看做是由Series组成的字典,并且共用一个索引。
创建方式:
pd.DataFrame({‘one’:[1,2,3,4], ‘two’:[4,3,2,1]})
pd.DataFrame({‘one’:pd.Series([1,2,3],index=[‘a’, ‘b’, ‘c’]), ‘two’:pd.Series([1,2,3,4],index=[‘b’, ‘a’, ‘c’, ‘d’])})
…
csv文件读取与写入:
df.read_csv(‘filename.csv’)
df.to_csv()
pd.DataFrame({
'one':[1,2,3,4], 'two':[4,3,2,1]})
>>>
one two
0 1 4
1 2 3
2 3 2
3 4 1
pd.DataFrame({
'one':pd.Series([1,2,3],index=['a', 'b', 'c']), 'two':pd.Series([1,2,3,4],index=['b', 'a', 'c', 'd'])})
>>>
one two
a 1.0 2
b 2.0 1
c 3.0 3
d NaN 4
DataFrame-常用属性 | |
---|---|
index | 获取行索引 |
T | 转置行列 |
columns | 获取列索引 |
values | 获取值数组(二维数组) |
describe() | 获取快速统计 |
df
>>>
one two
0 1 4
1 2 3
2 3 2
3 4 1
df.index
>>>RangeIndex(start=0, stop=4, step=1)
df.values
>>>
array([[1, 4],
[2, 3],
[3, 2],
[4, 1]], dtype=int64)
df.T # 行列交换
>>>
0 1 2 3
one 1 2 3 4
two 4 3 2 1
df.describe() # 对每一列进行统计
>>>
one two
count 4.000000 4.000000
mean 2.500000 2.500000
std 1.290994 1.290994
min 1.000000 1.000000
25% 1.750000 1.750000
50% 2.500000 2.500000
75% 3.250000 3.250000
max 4.000000 4.000000
df
>>>
one two
a 1.0 2.0
b 2.0 1.0
c 3.0 NaN
d NaN Nan
df.dropna() # 删除NaN
>>>
one two
a 1.0 2.0
b 2.0 1.0
df.dropna(how='all') # 删除都是NaN的行
>>>
one two
a 1.0 2.0
b 2.0 1.0
c 3.0 NaN
df.dropna(how='any') # 默认,删除所有含有NaN的行
>>>
one two
a 1.0 2.0
b 2.0 1.0
df.drop(axis=1) # 默认axis=0按行为标准,写成1后按列为标准
pandas-其他常用方法 | |
---|---|
mean(axis=0,skipna=False) | 对列(行)求平均值 |
sum(axis=1) | 对列(行)求和 |
sort_index(axis,…,ascending) | 对列(行)索引排序 按标签排序 |
sort_values(by,axis,ascending) | 按某一列(行)的值排序 |
Numpy的通用函数同样适用于pandas |
df = pd.DataFrame({
'one':pd.Series([1,2,3],index=['a','b
...: ','c']),'two':pd.Series([5,2,1,6],index=['a','b','c
...: ','d'])})
>>>
one two
a 1.0 5
b 2.0 2
c 3.0 1
d NaN 6
df.mean() # 对列(行)求平均值 括号内axis值默认为0,若为1则对行求平均值
>>>
one 2.0
two 3.5
dtype: float64
df.sum() # 求和 括号内参数与mean()相同
>>>
one 6.0
two 14.0
dtype: float64
df.sort_values(by='具体行',accending=False,axis=1或0) # 其中accending表示升序,False则表示为降序,含有NaN的行不参与排序默认放到最后一行
时间序列类型:
时间戳:特定时刻
固定时间:如2017年7月
时间间隔:起始时间—结束时间
Python标准库处理时间对象:datetime
灵活处理时间对象:datautil
dateutil.parser.parse() # 无法处理中文格式 但是可以处理JAN等缩写
成组处理时间对象:pandas
pd.to_datetime()
dateutil.parser.parse('20010130') # 可以将任何格式的时间形式转换
>>>datetime.datetime(2001, 1, 30, 0, 0)
pd.to_datetime(['2001.1.30','20010813']) # 可以批量处理时间对象 无论格式是否相同
>>> DatetimeIndex(['2001-01-30', '2001-08-13'], dtype='datetime64[ns]', freq=None)
pd.date_range('2001.1.30','2001.8.13',periods=10) # periods表示输出的时间个数
>>>
DatetimeIndex(['2001-01-30 00:00:00', '2001-02-20 16:00:00',
'2001-03-14 08:00:00', '2001-04-05 00:00:00',
'2001-04-26 16:00:00', '2001-05-18 08:00:00',
'2001-06-09 00:00:00', '2001-06-30 16:00:00',
'2001-07-22 08:00:00', '2001-08-13 00:00:00'],
dtype='datetime64[ns]', freq=None)
sr = pd.Series(np.arange(100),index=pd.date_range('200
...: 10130',periods=100)) # 首先生成以时间对象为索引的Series
>>>
2001-01-30 0
2001-01-31 1
..
2001-05-09 99
Freq: D, Length: 100, dtype: int32
sr['2001-03','2001-04'] # 然后可以根据具体的日期进行索引,可以对一个时间段进行索引
>>>
2001-03-01 30
2001-03-02 31
...
2001-03-30 59
2001-03-31 60
Freq: D, dtype: int32
# 一些函数
sr.resample('W').sum() # resample()就是对括号内的单位时间进行重新采样,例如对将每一周的数据和统计出来就是上面这样,括号内的参数与时间对象创建的频率是一样的单位
>>>
2001-02-04 15
2001-02-11 63
2001-02-18 112
...
2001-05-13 294
Freq: W-SUN, dtype: int32
sr.truncate(before='2001-01-30') # 该函数就是输出你输入的时间后的所有记录,功能类似切片,实用性不高,括号内还有after
pd.read_csv('training.csv',index_col='Time') # 可以更改索引,这里是将第0列作为索引,index_col的参数也可以是自定义的列名,例如这里的Time
>>>
ID name score
Time
2001/1/1 202001 A 98
2001/1/2 202002 B 95
...
2001/1/11 202011 K 68
2001/1/12 202012 L 65
# 但是这里的Time序列无法直接进行检索,输出只是index,所以需要将其转化为时间序列
pd.read_csv('training.csv',index_col='Time',parse_dates=['Time']) # 可以指定其中一列转化为时间序列,如果parse_dates=True会自动转化
# 如果文件没有列名读取时会自动把第一行当作列名,为了避免这种情况会使用下面的方法
pd.read_csv('training.csv',header=None)
>>>0 1 2 3
0 2001/1/1 202001 A 98
...
11 2001/1/12 202012 L 65
pd.read_csv('training.csv',header=None,names=list('abcd')) # 也可以指定输出列名
>>>
a b c d
0 2001/1/1 202001 A 98
1 2001/1/2 202002 B 95
...
11 2001/1/12 202012 L 65
df # df[0,0]的位置值为NaN
>>>
0 1 2 3
0 NaN 202001 A 98
1 2001/1/2 202002 B 95
...
11 2001/1/12 202012 L 65
df.to_csv('training.csv', header=False, index=False, na_rep='null', columns=[0,1,2,3]) # 此步骤可以将df存储的内容保存至training.csv中
pandas支持其他文件类型:json,XML,HTML,数据库,pickle,excel…
数据可视化
plt.plot([1,2,3,4],[2,3,1,7]) # 折线图,第一个方括号里对应X轴的值,第二个方括号对应Y轴的值
plt.plot([1,2,3,4],[2,3,1,7],'o') # 后面有个o是只用点点出来,'o-'的话就是点和线组成
Matplotlib-图像标注 | |
---|---|
设置图像标题:plt.title() | 设置y轴范围:plt.ylim() |
设置x轴名称:plt.xlabel() | 设置x轴刻度:plt.xticks() |
设置y轴名称:plt.ylabel() | 设置y轴刻度:plt.yticks() |
设置x轴范围:plt.xlim() | 设置曲线图例:plt.legend() |
plt.xticks(np.arange(0,11,2),['a','b','c','d','e','f'])
# 该行语句其中括号里第一个参数设置了x轴的长度以及步长,第二个参数将x轴的每一个数字替换成英文字母
plt.legend()
# 这个如果直接打上去是不会有任何的改变的,首先必须每一条线有lable属性,对应图例名称,例如plt.plot([1,2,3,4],[2,3,1,7],label='line 1'),这样才可以在图像空白处显示曲线图例
df = pd.read_csv('training.csv', parse_dates=['Date'], index_col='Date')[['Name','Score']]
# 这里就是读取了training.csv文件,将Date标签设置为索引,然后再设置了需要显示的变量
题目:Matplotlib实例——绘制数学函数图像
使用Matplotlib模块再一个窗口中绘制数学函数y=x,y=x²,y=3x³+5x²+2x+1的图像,使用不同颜色的线加以区别,并使用图例说明各个线代表什么函数。
x = np.linspace(-100,100,10000)
y1 = x.copy()
y2 = x ** 2
y3 = 3*x**3+5*x**2+2*x+1
plt.plot(x,y1,label='y=x',color='red')
plt.plot(x,y2,label='y=x^2',color='green')
plt.plot(x,y3,label='y=3x^3+5x^2+2x+1',color='blue')
plt.ylim(-1000,1000)
plt.legend()
plt.show()
# 举例
fig = plt.figure()
ax1 = fig.add_subplot(2,2,1)
ax1.plot([1,2,3,4],[5,4,2,6])
ax2 = fig.add_subplot(2,2,2)
plt.show()
函数 | 说明 |
---|---|
plt.plot(x,y,fmt,…) | 坐标图 |
plt.boxplot(data,notch,position) | 箱型图 |
plt.bar(left,height,width,bottom) | 条形图 |
plt.barh(width,bottom,left,height) | 横向条形图 |
plt.polar(theta,r) | 极坐标图 |
plt.pie(data.explode) | 饼图 |
plt.psd(x,NFFT=256,pad_to,Fs) | 功率谱密度图 |
plt.specgram(x,NFFT=256,pad_to,F) | 谱图 |
plt.cohere(x,y,NFFT=256,Fs) | X-Y相关性函数 |
plt.scatter(x,y) | 散点图 |
plt.step(x,y,where) | 步阶图 |
plt.hist(x,bins,normed) | 直方图 |
# 柱状图
data = [21,22,41,100] # 确定各值
labels = ['Jan','Feb','Mar','Apr'] # 确定各条的名字
plt.bar(np.arange(len(data)),data,color=['red','blue','yellow','green']) # 确定属性,包括条形图的对应位置,值,以及各条的颜色
plt.xticks(np.arange(len(data)),labels) # 改变x轴
plt.show()
# 饼图
plt.pie([10,20,30,40],labels=['a','b','c','d'],autopct='%.2f%%',explode=[0.1,0,0,0]) # 这里面第一个参数是对应饼内各块的值,labels就是各块的标签,autopct可以设置值的显示形式,这里是百分号后显示两位小数,explode是可以让其中几块突出显示,括号内的数值指突出的距离
plt.axis('equal') # 刻度等长
plt.show
现在已经没有matplotlib.finance子包了,已经单独分离出mplfinance包
mplfinanace包中有许多绘制金融相关图的函数接口。
绘制k线图:mpf.plot()函数
import mplfinance as mpf
mpf.plot(data) # data里为传入的数据
通过参数type修改绘图类型,默认是ohlc,可改为type='candle’或者type=‘line’
mpf.plot(data,type='candle')
关键字参数mav=(2,5,10),多条均线使用元组,只绘制一条均线,可以mav=10
mpf.plot(data,type='candle',mav=(2,5,10))
mpf.plot(data,type='candle',mav=(10,))
关键字参数volume=True
mpf.plot(data,type='candle',mav=(2,5,10),volume=True)
关键字参数show_nontrading,默认是False,设置为True,就可以看到停盘的时间段
mpf.plot(data,type='candle',mav=(2,5,10),volume=True,show_nontrading=True)
# 由于上述读取的数据没有停盘时间段,因此绘图没有什么不同。
Tushare是一个免费、开源的python财经数据接口包,更多信息可以上官网查看
tushare.org
需要另外安装一个Tushare的包pip install Tushare
import tushare as ts
ts.get_k_data('601318') # 可以显示近几年该代码股票的交易情况
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import tushare as ts
# 获取该股票的历史行情数据
df = ts.get_k_data('601318',start='1988-01-01')
df.to_csv('601318.csv') # 存储成csv文件
# 以时间为索引
df = pd.read_csv('601318.csv',index_col='date',parse_dates=['date'])
# 输出该股票所有收盘比开盘上涨3%以上的日期
df[(df['close']-df['open'])/df['open']>=0.03].index
# 输出该股票所有开盘比前日收盘跌幅超过2%的日期
df[(df['open']-df['close'].shift(1))/df['close'].shift(1)<=-0.02]
#shift()的功能是将该列的数据全部往下移一行,括号内的数字代表向下移几行,不知道该函数也可以用循环做
# 假如我从2010年1月1日开始,每月第一个交易日买入1手股票,每年最后一个交易日卖出所有股票,到今天为止,我的收益如何?
price_last = df['open'][-1]
df = df['2010-01':'2021-07']
df_monthly = df.resample('M').first() # 重新取样,取每个月的第一天的数据并存储
df_yearly = df.resample('A').last()[:-1] # 重新取样,取每年的最后一天的数据并存储
cost_money = 0
hold = 0
for year in range(2010,2022):
cost_money = df_monthly[str(year)]['open'].sum()*100 # 买入所花费的钱
hold += len(df_monthly[str(year)]['open'])*100 # 手中持有的股数
if year !=2021:
cost_money -= df_yearly[str(year)]['open'][0] * hold # 卖出该年股票后花费的钱
hold = 0
print (cost_money)
cost_money -= hold * price_last
print (-cost_money)
查找历史金叉死叉日期
题目:
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import tushare as ts
# 获取该股票的历史行情数据
df = ts.get_k_data('600519',start='2001-01-01')
df.to_csv('600519.csv',index=False) # 存储成csv文件
# 以时间为索引
df = pd.read_csv('600519.csv',index_col='date',parse_dates=['date'])[['open','close','low','high']]
# 循环方法
# df['ma5'] = np.nan
# df['ma30'] = np.nan
# for i in range(4,len(df)):
# df.loc[df.index[i],'ma5'] = df['close'][i-4:i+1].mean()
# for i in range(29,len(df)):
# df.loc[df.index[i],'ma30'] = df['close'][i-29:i+1].mean()
# rolling方法
df['ma5'] = df['close'].rolling(5).mean()
df['ma30'] = df['close'].rolling(30).mean()
# 画出三条线
df[['close','ma5','ma30']].plot()
plt.show()
# 方法1
# golden_cross = []
# death_cross = []
# for i in range(1,len(df)):
# if df['ma5'][i] >= df['ma30'][i] and df['ma5'][i-1] < df['ma30'][i-1]:
# golden_cross.append(df.index[i])
# if df['ma5'][i] <= df['ma30'][i] and df['ma5'][i-1] > df['ma30'][i-1]:
# death_cross.append(df.index[i])
# 方法2
sr1 = df['ma5'] < df['ma30']
sr2 = df['ma5'] >= df['ma30']
death_cross = df[sr1 & sr2.shift(1)].index
golden_cross = df[~(sr1 | sr2.shift(1))].index
first_money = 100000
money = first_money
hold = 0 # 持有股数
sr1 = pd.Series(1,index=golden_cross)
sr2 = pd.Series(0,index=death_cross)
sr = sr1.append(sr2).sort_index()
for i in range(0,len(sr)):
p = df['open'][sr.index[i]]
if sr.iloc[i] == 1:
# 金叉
buy = (money // (100 * p))
hold += buy*100
money -= buy*100*p
else:
# 死叉
money += hold * p
hold = 0
p = df['open'][-1]
now_money = hold * p + money
print(now_money - first_money)