pandas
#有许多数据结构,比python多
0 .panda的导入 以及df,Series
导入pandas:
import pandas as pd
from pandas import DataFrame,Series
import numpy as np
一.Series
Series是一种类似与一维数组的对象,由下面两个部分组成:
- values:一组数据(ndarray类型)
- index:相关的数据索引标签
a.Series的创建
两种创建方式:
(1) 由列表创建
默认索引为0到N-1的整数型索引
使用列表创建Series
Series(data=[1,2,3])
自带隐形索引
可以通过设置index参数指定索引
s = Series(data=[1,2,3],index=['a','b','c'])
(2) 由numpy数组创建
Series(data=np.random.randint(0,100,size=(3,)))
由numpy数组创建
b.Series的索引和切片
c.Series的基本概念
1查看去重相加
s.head() : 查看前n个
tail() : 查看后n个值
s.unique() : Series元素进行去重
当索引没有对应的值时,可能出现缺失数据显示NaN(not a number)的情况
使得两个Series进行相加
s1 = Series(data=[1,2,3,4],index=['a','b','c','d'])
s2 = Series(data=[1,2,3,4],index=['a','b','e','d'])
s = s1 + s2
2 使用函数检测缺失数据
pd.isnull(),
pd.notnull(),
s.isnull(),
notnull()
s[[True,True,False,False,True]] #如果将布尔值作为Serrise的索引,则只保留True对应的元素值 # 根据这一属性 后面提取符合条件的值 当有判断时, 作业里用到
s[s.notnull()]
3 Series之间的运算
- 在运算中自动对齐不同索引的数据
- 如果索引不对应,则补NaN
二、DataFrame
DataFrame是一个【表格型】的数据结构。DataFrame由按一定顺序排列的多列数据组成。设计初衷是将Series的使用场景从一维拓展到多维。DataFrame既有行索引,也有列索引。
- 行索引:index
- 列索引:columns
- 值:values
a. DataFrame的创建
最常用的方法是传递一个字典来创建。DataFrame以字典的键作为每一【列】的名称,以字典的值(一个数组)作为每一列。
此外,DataFrame会自动加上每一行的索引。
使用字典创建的DataFrame后,则columns参数将不可被使用。
同Series一样,若传入的列与字典的键不匹配,则相应的值为NaN。
1 由numpy数组创建
DataFrame(data=np.random.randint(60,100,size=(3,4)))
多维的
(1) 自定义索引
df = DataFrame(data=np.random.randint(60,100,size=(3,4)),index=['A','B','C'],columns=['a','b','c','d'])
b.DataFrame属性
values、columns、index、shape
values
array([[92, 67, 79, 68],
[84, 66, 61, 66],
[84, 79, 66, 82]])
columns Index(['A', 'B', 'C'], dtype='object')
index Index(['a', 'b', 'c', 'd'], dtype='object')
shape (3, 4)
c.字典格式
dic = {
'张三':[150,150,150,150],
'李四':[0,0,0,0]
}
df = DataFrame(data=dic,index=['语文','数学','英语','理综'])
df
d.DataFrame的索引
1 对列进行索引
- 通过类似字典的方式 df['q']
- 通过属性的方式 df.q
可以将DataFrame的列获取为一个Series。返回的Series拥有原DataFrame相同的索引,且name属性也已经设置好了,就是相应的列名。
df = DataFrame(data=np.random.randint(60,100,size=(3,4)),index=['A','B','C'],columns=['a','b','c','d'])
df
size(3,4) 必须和index 行 columns 列对应
获取前两列
df[['a','c']]
(1) 修改列索引
df.columns = ['a','c','b','d']
df
2 对行进行索引
- 使用.loc[]加index来进行行索引
- 使用.iloc[]加整数来进行行索引
同样返回一个Series,index为原来的columns。
对第一行的索引:
df.iloc[0]
df.loc['A']
对第一二行的索引:
df.loc[['A','B']]
3 对元素索引的方法
- 使用列索引
- 使用行索引(iloc[3,1] or loc['C','q']) 行索引在前,列索引在后
df.iloc[1,2] # 第二行第三列
df.loc[['B','C'],'b'] # 第B到C行,第b列
e.DataFrame的切片:
【注意】 直接用中括号时:
- 索引表示的是列索引
- 切片表示的是行切片
df[0:2] 行
df.iloc[:,0:2] 列
在loc和iloc中使用切片(切列) : df.loc['B':'C','丙':'丁']
f.总结:
- 索引:
- 取行:df.loc['A']
- 取列:df['a']
- 取元素:df.iloc[1,2]
- 切片:
- 切行:df[0:2]
- 切列:df.iloc[:,0:2]
g.DataFrame的运算
DataFrame之间的运算
同Series一样:
- 在运算中自动对齐不同索引的数据
- 如果索引不对应,则补NaN
z. 小总结:
索引默认是列,所以用行的话,除了索引取值,ddd['语文':'语文'] 用 loc['语文']
切片默认是行 所以用列的话,除了取一列ddd['李四'],取多列,用loc[:,'张三':'李四']
做题
ddd.loc[:,'张三':'刘二']+10
回想
案例分析
1. 收成比开始涨幅3%的股票
2. 今日开比昨日收减幅2%的股票
思路把 昨日收往下下滑一行
shift[1]
然后以日期为标识
riqi = [([open]-[close])/close<3%].index
[riqi][]
3. 从2010年每月第一个开买进1手,每年末的第一个月卖出所有,如果到今天,能赚多少
dic['y'] = ['A'][-1] # 去2019 显示问题还是对的
dic['m'] = ['M'][:-1]['open'].sum * 100 # 每年每月的
dic['L'] = ['M']['-1']['close'] # 每年最后一个月的
dic['L'] * 1200 + dic['']
今日份错误:
size 没有定义
DataFrame(data=np.random.randint(60,100,size(3,4)))
true:
DataFrame(data=np.random.randint(60,100,size=(3,4)))
作业
作业1
1 假设ddd是期中考试成绩,ddd2是期末考试成绩,请自由创建ddd2,并将其与ddd相加,求期中期末平均值。
ddd = DataFrame(data=np.random.randint(100,120,size=(4,4)),index=['语文','数学','英语','理综'],columns=['张三','李四','王五','刘二'])
ddd2 = DataFrame(data=np.random.randint(100,120,size=(4,4)),index=['语文','数学','英语','理综'],columns=['张三','李四','王五','刘二'])
ddd_avg = ddd+ddd2
ddd_avg.mean()
2 假设张三期中考试数学被发现作弊,要记为0分,如何实现?
# ddd[2,1] = 0 # 错误,属于直接加列
ddd.drop(labels=(2,1),axis=1,inplace=True)
ddd.loc['数学',['张三']] = 0
3 李四因为举报张三作弊立功,期中考试所有科目加100分,如何实现?
ddd['李四']+100
4 后来老师发现有一道题出错了,为了安抚学生情绪,给每位学生每个科目都加10分,如何实现?
ddd.loc[:,'张三':'刘二']+10
作业2
1查看一个股盘
2输出该股票所有收盘比开盘上涨3%以上的日期。
3输出该股票所有开盘比前日收盘跌幅超过2%的日期。
4假如我从2010年1月1日开始,每月第一个交易日买入1手股票,每年最后一个交易日卖出所有股票,到今天为止,我的收益如何?
下载tushare 包 : pip3 install tushare
导入数据: 比如 茅台是 600519
1数据的提取处理
#使用tushare包获取某股票的历史行情数据。
import tushare as ts
df = ts.get_k_data(code='600519',start='2000-01-01')# 因为茅台是从2001年左右开始股 get_k_data(code='',start='') 股票号, 开始日期
df.to_csv('./600519.csv') # 转成csv存储到本地
#将date这一列作为源数据的行索引且将数据类型转成时间类型
df = pd.read_csv('./600519.csv',index_col='date',parse_dates=['date'])
#当做第一题,二题时,直接提取index即得到答案 , 还因为日期是惟一的也可以做索引
df.drop(labels='Unnamed: 0',axis=1,inplace=True) # 删除多余的索引列
df # 查看数据是否插入 4000多条
2输出该股票所有收盘比开盘上涨3%以上的日期。
伪代码: (收盘-开盘)/开盘 > 3%
(df['close']-df['open'])/df['open'] > 0.03
#将上述表达式返回的布尔值作为df的行索引:取出了所有符合需求的行数据
df.loc[(df['close']-df['open'])/df['open'] > 0.03]# 如果是正确的的,则loc会采纳得到所有的
加上index就得到了日期 .index
以解析成时间格式的日期为index的数据
得到的日期格式
3输出该股票所有开盘比前日收盘跌幅超过2%的日期。
伪代码: (开盘-前日收盘)/前日收盘 < -2%
用到的知识点
某一列.shift(1) #选中的数据往下面移动1格 就可以对修改后的同行的数据操作open和close了
(df['open'] - df['close'].shift(1) / df['close'].shift(1) < -0.02)
df.loc[(df['open'] - df['close'].shift(1) / df['close'].shift(1) < -0.02)].index
4 赚了多少
假如我从2010年1月1日开始,每月第一个交易日买入1手股票,每年最后一个交易日卖出所有股票,到今天为止,我的收益如何?
从2010年开始 1月1日(只能表示年! 月日怎么表示?)# df['2010-09-10':'2019-09-10']?
df['2010':'2019']
不一定从1月04开始的
# 数据的重新取样
df_monthly = df.resample('M').frist() # 每月第一个交易日买入1手股票 此为1股要*100
df_yearly = df.resample('A').last()[:-1] # 每年最后一个交易日卖出, 最后一年还没过完,没法收盘 所以[:-1]
recv_money = df_monthly['open'].sum()*100 # 求和乘100 #去开盘数据求和
send_money = df_yearly['close'].sum()*1200 # 取收盘数据1年的12个月,
再加上 df['close'][-1]*800 #最后一个月,不是12月了,是8月的 而且只能df['close'] 取值
相减即得股票盈利