python数据分析备课

import numpy as np #重在数值运算
arr = np.array([1,2,3])  #创建一维数组
print(arr)    #array([1,2,3])
arr = np.array([[1,2,3],[4,5,6]])  #创建二维数组
print(arr)    
#array([[1,2,3],
#       [4,5,6]])
arr = np.array([1,2.2,'three'])  #创建1维数组
print(arr)  #array(['1','2.2','three'])
#数组强制转成同一类型,字符串>浮点型>整数 
#这是与列表的区别,列表可以有不同类型的数据



# 将外部的一张图片读取加载到numpy数组中,对数组的修改,看对图片的影响
import matplotlib.pyplot as plt # 重在对图片处理
img_arr = plt.imread('d:\\001.jpeg')
print(img_arr)# 返回一个三维数组的数据 
plt.imshow(img_arr) # 图片的可视化处理
plt.show() # 显示
img_arr = img_arr -100
plt.imshow(img_arr) # 图片的可视化处理
plt.show() # 显示




# ======常见创建数组的方式=========
# zero()
# ones()
# linespace()
# arange()
# random 系列
np.ones(shape=(3,4)) # 创建2维数组
np.linespace(0,100,num=20)# 创建1维数组 一维的等差数组
np.arange(10,50,step=20)# 创建1维数组 一维的等差数组
np.random.randint(0,100,size=(5,3)) #2维随机数组
# numpy的常用属性
# shape 形状
# ndim  维度
# size  元素的个数
# dtype 类型



np.random.randint(0,100,size=(5,6)) #2维随机数组
arr.shape  # 返回(5,6)
arr.ndim  # 返回 2
arr.size   # 返回数组元素的个数
arr.dtype   # 返回 ndarray
arr = np.array([1,2,3])
arr.dtype   # 返回 int64
arr = np.array([1,2,3],dtype = 'int32')
arr.dtype   # 返回 int32
arr.dtype ='uint8'   # 
arr.dtype   # 返回 uint8


# =============numpy的索引和切片操作=============
arr = np.random.randint(0,100,size=(5,6)) #2维随机数组
print(arr)
print(arr[1]) # 取出了numpy数组中的下标为1的行数据
print(arr[1,3,4])  # 取出多行数据
# 切出arr数组的前两行数据
arr[0:2] #arr[行切片]
# 切出arr数组的前两列数据
arr[:,0:2] #arr[行切片,列切片]
arr[0:2,0:2] #arr[行切片,列切片]
# 将数组的行倒置
arr[::-1]
# 将数组的列倒置
arr[:,::-1]
# 将所有元素倒置
arr[::-1,::-1]




#将一张图片进行左右翻转
img_arr = plt.imread('d:\\001.jpeg')
print(img_arr.shape) # (300,450,3)
plt.imshow(img_arr[:,::-1,:])
#将一张图片进行上下翻转
plt.imshow(img_arr[::-1,:,:])
#图片裁剪
plt.imshow(img_arr[66:200,78:300,:])


# =======================================
# 变形reshape
arr = np.random.randint(0,100,size=(5,6)) 
print(arr)# 5行6列的二维数组
#变形的操作,元素的个数,不能多页不能少
# 将2维的数组变形成1维
arr_1 = arr.reshape((30,))  #
# 将2维的数组变形成3维
arr_3 = arr.reshape((2,3,5))  #
# 级联操作
    # 将多个numpy数组进行横向或者纵向的拼接,只能同一纬度进行级联
    # axis轴向的理解
       #- 0:列
       #- 1:行
    # -问题:级联的两个数组纬度一样,但是行列个数不一样会如何
np.concatenate((arr,arr),axis=1)



#图片的级联  
np.concatenate((img_arr,img_arr),axis=1)
np.concatenate((img_arr,img_arr),axis=0)
# 常用的聚合操作
# sum, max, min, mean
arr.sum(axis=1)
arr.max(axis=1)
arr.min(axis=1)
# 常用的数学函数
# sin,cos,tan
# around(a,decimals)  
     #a : 数组
     #decimals : 舍入的小数位数
np.sin(arr) # 对arr中的每个元素进行求正玄操作
np.around(3.84) # 返回4.0
np.around(3.84,1) # 返回3.8




# 常用统计函数
# numpy.amin()    numpy.amax():用于计算数组中的元素沿指定轴的最小、最大值
# numpy.ptp():计算数组中的元素的最大值与最小值的差(最大值-最小值)
# numpy.median() 函数用于计算数组a中元素的中位数(中值)
# 标准差std():标准差是一组数据平均值分散程度
# 公式:std = qurt(mean(x-x.mean())**2)
# 方差var():统计中的方差是每隔样本值与全体样本值的平均数之差的平均数。
# 公式:mean(x-x.mean())**2
np.ptp(arr,axis=1)   #所有列中最大值和最小值的差
arr[1].std()         #计算标准差
arr[1].var()         #计算方差
#矩阵相关
# NumPy中包含了一个矩阵库,numpy.matlib
#eye返回一个标准的单位矩阵
np.eye(6)
np.eye(6).T #转置矩阵
a1=np.array([[2,1],[4,3]])
a1=np.array([[1,2],[1,0]])
np.dot(a1,a2) # 矩阵相乘 返回 array([[3,4],[7,8]])



#===============================================

# pandas 主要处理非数据类型的数据

# Series   是一种类似于一维数组的对象,由values,index 组成。

    # values: 一组数据ndarray

    # index: 相关的数据索引标签

# DataFrame  

    # 由列表或者numpy数组创建

    # 由字典创建

    

    

from pandas import Series
s = Series(data=[1,2,3,'four'])
print(s)
#返回
# 0    1
# 1    2
# 2    3
# 3   four
# dtype = object
import numpy as np
Series(
    data=np.random.randint(0,100,size = (3,4))   #这样会报错,不能执行二维的数据
)
Series(
    data=np.random.randint(0,100,size = (3,))   #这样正常
)
# index 用来指定显式索引
s = Series(
    data=[1,2,3,'four'],
    index=['a','b','c','d'])  
)
print(s)
#返回
# a    1
# b    2
# c    3
# d   four
# dtype = object
#为什么需要有显式索引,显式索引可以增强Series的可读性
dic = {
    '语文':100,
    '数学':100,
    '理综':100
    }
s = Series(data=dic)
print(s)
# Series 的索引和切片
print(s[0]) #返回100
print(s.语文) #返回100
print(s[0:2]) 
# 语文   100 
# 数学   99
# dtype:int64
# Series 的常用属性
# shape
# size
# index
# values
s.shape #(3,)
s.size #3
s.index  #返回索引     Index(['语文','数学','理综'],dtype='object')
s.values #返回值       array([100,99,250])
s.dtype  #元素的类型   dtype('int64')
s = Series(data=dic[1,2,3,'four'],index=['a','b','c','d'])
s.dtype #数据类型 s.dtype('O')  表示的是object (字符串类型)
# Series 的常用方法
# head(),tail()
# unique()
# isnull(),notnull()
# add(),sub(),mul(),div()
s = Series(data=np.random.randint(60,100,size=(10,)))
s.head() #显示前n个数据,默认显示5个
#0 91
#1 79
#2 85
s.tail() #显示后n个数据,默认显示5个
s.unique() #去重  array([,,,,])
s.isnull() #判断每一个元素是否为空 dtype bool
#0 False
#1 False
#2 False
# ...
s.notnull() #判断每一个元素是否非空
#0 True
#1 True
#2 True
# ...
# 为什么会出现空值呢
# Series 算法运算
     # 法则:索引一致的元素进行算术运算,否则补空
s1 = Series(data=[1,2,3],index=['a','b','c'])
s2 = Series(data=[1,2,3],index=['a','d','c'])
s = s1+s2
print(s)
# a   2.0
# b   NaN
# c   6.0
# d   NaN
print(s.isnull())
# a   False
# b   True
# c   False
# d   True


# DataFrame 是一个表型的数据结构,DataFrame由按一定顺序排列的多列数据组成。

# 设计初衷是把Series从一维拓展到多维


# DataFrame 既有行索引,也有列索引

# 行索引:index

# 列索引:columns

# 值:values


# DataFrame 的创建

  # ndarray创建

  # 字典创建


df = DataFrame(data=[[1,2,3],[4,5,6]])
print(df)
#使用6行4列的数据
df = DataFrame(data=np.random.randint(0,100,size =(6,4)))
dic = {
    'name':['zhangsan','lisi','wanglaowu'],
    'salary':[1000,2000,3000]
}
df = DataFrame(data=dic,index = ['a','b','c']
print(df)
    # name        salary
# a   zhangsan    1000
# b   lisi        2000
# c   wanglaowu   3000
# DataFrame的属性
# values, columns , index, shape
print(df.values)  #返回一个二维数组,排除行列标签之外的值
print(df.columns) #返回一个  [ 'name' ,  'salary']
print(df.index)   #返回一个  ['a','b','c']
print(df.shape)   #返回一个   (2,3)
# 练习题
# 根据以下考试成绩表,创建一个DataFrame,命名为df:
          # 张三          李四
# 语文      150             0
# 数学      150             0
# 英语      150             0
# 理综      300             0
dic={
    '张三':[150,150,150,300]
    '李四':[0,0,0,0]
}
df = DataFrame(data=dic,index = ['语文','数学','英语','理综']
print(df)
# DataFrame索引操作
# 对行进行操作
# 对列进行操作
# 对元素进行操作
df = DataFrame(data=np.random.randint(60,100,size=(8,4)),columns=['a','b','c','d'])
print(df)
print(df['a']) #返回一列,取单列,如果df有显式的索引,通过索引机制取行或者列的时候,只可以使用显式索引。
print(df[['a','c']]) #取两列
#取单行
df.iloc[0]
#取多行
df.iloc[[0,3,5]]
# iloc  通过隐式索引取行
# loc   通过显式索引取行
# 取单个元素 0行3列的一个数据
df.iloc[0,3]
df.iloc[0,'a']
# 取多个元素
df.iloc[[1,3,5],2]
# 切行  前两行
df[0:2]
# 切列  前两列
df[:,0:2]
# df 索引和切片操作
   # -索引:
      # - df[col]:取列
      # - df.loc[index]:取行
      # - df.iloc[index,col]:取元素
   # -切片:
      # - df[index1:index3]  切行
      # - df[:,col1:col3]  切列
Data的运算
   同Series
# 练习:
# 1.假设ddd是期中考试成绩,ddd2是期末考试成绩,请自由创建ddd2,并将其与ddd相加,求期中期末平均值
# 2.假设张三期中考试数学被发现作弊,要记为0分,如何实现?
# 3.李四因为举报张三作弊立功,期中考试所有科目加100分,如何实现?
# 4.后来老师发现有一道题出错了,为了安抚学生情绪,给每位学生每个科目都加10分,如何实现?
dic = {
    '张三':[150,150,150,150],
    '李四':[100,100,100,100],
}
df = DataFrame(data=dic,index = ['语文','数学','英语','理综'])
qz = df
qm = df
#期中期末平均值:
print((qz+qm)/2)
qz.iloc['数学','张三']=0
qz['李四']+=100
qz +=10
print(qz)
#  时间数据类型的转换# pd.to_datetime(col)
# 将某一列设置为行索引# df.set_index()
dic = {
    'time':['2010-10-10','2011-11-20','202-01-10'],
    'temp':[33,31,30],
}
df = DataFrame(data=dic)
print(df)
#查看time列的类型
df['time'].dtype
#将time列的数据类型转换成时间序列类型
df['time'] = pd.to_datetime(df['time'])
print(df)
print(df['time'].dtype)
#将time列做为源数据的行索引
print(df)
new_df = df.set_index('time')
print(new_df)
print(df) #源数据df并没有被改变
#如果想要替换源数据
df.set_index('time',inplace = True)
print(df)#源数据被改变


#=====================================================================================


# 1、DateFrame基础操作的巩固
需求:股票分析
1.tushare包获取某股票的历史行情数据
2.输出该股票所有的收盘比开盘上涨3%以上的日期
3.输出该股票所有开盘比欠日收盘跌幅超过2%的日期
4.假如我从2010年1月1日开始,每月第一个交易日买入1手股票,每年最后一个交易日卖出所有的股票,
到今天为止,我的收益如何?
# 方式1:
# pip install tushare
# 如果安装网络超时可尝试国内pip源,如pip install tushare -i https://pypi.tuna.tsinghua.edu.cn/simple
# 方式2:访问https://pypi.python.org/pypi/tushare/下载安装 ,执行 python setup.py install
# 方式3:访问https://github.com/waditu/tushare,将项目下载或者clone到本地,进入到项目的目录下,
# 执行: python setup.py install
# 获取300321的历史行情数据
df = ts.get_k_data(code='300321',
              start='2013-12-04',
              end='2023-12-04')
# 将互联网上获取的股票数据存储到本地
df.to_csv('tongda.csv')
#将本地存储的数据读取到df
df = pd.read_csv('tongda.csv')
print(df.head())
# 对读取出来的数据进行处理 删掉 Unnamed
# 删除 df中指定的一列
df.drop(labels = 'Unnamed: 0',axis=1,inplace=True)
#查看每一列的数据类型
print(df['date'].dtype)
print(df.info)
#将time列转为时间序列类型
df['date'] = pd.to_datetime(df['date'])
print(df.head())
#将 date 列做为源数据的行索引
df.set_index('date',inplace=True)
print(df.head())
#输出该股票所有收盘比开盘上涨3%以上的日期
#伪代码 (收盘-开盘)/开盘 > 0.03
print((df['close']-df['open'])/df['open'] > 0.03)
#在分析的过程中如果产生了boolean值则下一步马上将布尔值作为源数据的行索引
#如果布尔值作为df的行索引,则可以取出true对应的行数据,忽略false对应的行数据
df.loc[(df['close']-df['open'])/df['open'] > 0.03] #获取了true对应的行数据(满足需求的行数据)
df.loc[(df['close']-df['open'])/df['open'] > 0.03].index #df行数据
#输出该股票所有开盘比欠日收盘跌幅超过2%的日期
#伪代码:(开盘-前日收盘)/前日收盘 < -0.02
ks=df.loc[(df['open']-df['close'].shift(1))/df['close'].shift(1)<-0.02]
print(ks.index)
#   假如 我从2012年5月23日开始,每月第一个交易日买入1手股票,
#   每年最后一个交易日卖出所有股票,到今天为止,我的收益如何?
# -时间节点:2012- 2023
# -一手股票:100支股票
# -买:
    # - 一个完整的年,需要买入1200支股票
# -卖:
    # - 一个完整的年,需要卖出1200支股票
# -买卖股票的单价:
    # - 开盘价
    
new_df = df['2012-05':'2023-12']
print(new_df)
# 买股票:找到每个月第一个交易日对应的行数据(捕获开盘价):每个月的第一行数据
df_month = new_df.resample('M').first() #数据的重新取样
#买入股票花费的总金额
cost = df_month['open'].sum()*100
#卖出股票到手的钱
#特殊情况:2023年买入的股票卖不出去
#以年重新取样后,将最后一行(2023)切出去
df_year = new_df.resample('Y').last()[:-1]
# 卖出股票到手的钱 
mon_2012 = df_year.loc['2012-12-31','open']*800 #2012年的收入
df_year =df_year[1:]
recv = df_year['open'].sum()*1200  #2013-2022年的股票收入
print(recv) 
print(new_df['close'][-1])
mon_2023 = 1200*new_df['close'][-1] #加上2023手中的股票价值
#计算总收益
recv = mon_2012+mon_2023+recv - cost



打赏

0 评论

发表评论