• Pandas


    Pandas的数据结构

    导入pandas:

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

    Series

    Series是一种类似与一维数组的对象,由下面两个部分组成:

    • values:一组数据(ndarray类型)
    • index:相关的数据索引标签

    Series(
    data=None,
    index=None,
    dtype=None,
    name=None,
    copy=False,
    fastpath=False,
    )

    Series的创建

    由列表或numpy数组创建

    • 默认索引为0到N-1的整数型索引
    # 使用列表创建Series
    Series(data=[1,2,3,])
    0    1
    1    2
    2    3
    dtype: int64
    Series(data=np.random.randint(0,100,size=(3)))
    0    93
    1    76
    2    65
    dtype: int32
    • 可以通过设置index参数指定索引
    Series(data=[1,2,3],index=['a','b','c']) #显式索引
    a    1
    b    2
    c    3
    dtype: int64
    ============================================

    练习1

    使用多种方法创建以下Series,命名为s1:  
    语文 150   
    数学 150   
    英语 150   
    理综 300   

    ============================================

    Series的索引和切片

    可以使用中括号取单个索引(此时返回的是元素类型),或者中括号里一个列表取多个索引(此时返回的是一个Series类型)。

    (1) 显式索引:

    • 使用index中的元素作为索引值

    • 使用s.loc[](推荐):注意,loc中括号中放置的一定是显示索引

      注意,此时是闭区间

    s = Series([1,2,3,4],index=['a','b','c','d'])
    s
    a    1
    b    2
    c    3
    d    4
    dtype: int64
    s[1]  # 2,隐式索引:
    s['a']  # 1
    s.a  # 1  显示索引

    隐式索引:

    • 使用整数作为索引值

    • 使用.iloc[](推荐):iloc中的中括号中必须放置隐式索引

      注意,此时是半开区间

    s[1:3]   # 隐式切片
    s['a':'c']  # 显示切片
    a    1
    b    2
    c    3
    dtype: int64

    Series的基本概念

    可以使用s.head(),tail()分别查看前n个和后n个值

    s.head(2)
    a    1
    b    2
    dtype: int64

    对Series元素进行去重

    s = Series([1,1,1,2,3,3,3,3,2])
    s.unique()
    array([123], dtype=int64)

    使得两个Series进行相加。

    当索引没有对应的值时,可能出现缺失数据显示NaN(not a number)的情况

    s1 = Series([1,2,3],index=['a','b','c'])
    s2 = Series([1,2,3],index=['a','d','c'])
    s = s1 + s2
    s
    a    2.0
    b    NaN
    c    6.0
    d    NaN
    dtypefloat64

    可以使用pd.isnull()pd.notnull(),或s.isnull(),notnull()函数检测缺失数据

    s[[1,2]]  # 一次取多值
    s[['a','b']]
    s[[True,False,True,False]] # True将值保留,False:将值舍去。True:2,False:NaN,True:6,Flase:NaN。
    a    2.0
    c    6.0
    dtypefloat64
    s.isnull()   # 检测每个元素,NOT NaN:False;NaN:True
    a    False
    b     True
    c    False
    d     True
    dtype: bool
    s.notnull()  # 检测每个元素,NOT NaN:True;NaN:False
    a     True
    b    False
    c     True
    d    False
    dtype: bool
    s[s.notnull()]
    a    2.0
    c    6.0
    dtypefloat64

    Series之间的运算

    • 在运算中自动对齐不同索引的数据
    • 如果索引不对应,则补NaN

    DataFrame

    DataFrame是一个【表格型】的数据结构。DataFrame由按一定顺序排列的多列数据组成。设计初衷是将Series的使用场景从一维拓展到多维。DataFrame既有行索引,也有列索引。

    • 行索引:index
    • 列索引:columns
    • 值:values

    DataFrame的创建

    最常用的方法是传递一个字典来创建。DataFrame以字典的键作为每一列的名称,以字典的值(一个数组)作为每一列。

    此外,DataFrame会自动加上每一行的索引。

    使用字典创建的DataFrame后,则columns参数将不可被使用。

    同Series一样,若传入的列与字典的键不匹配,则相应的值为NaN。

    • 使用ndarray创建DataFrame
    df = DataFrame(data=np.random.randint(0,100,size=(3,4)),index=['a','b','c'],columns=['A','B','C','D'])
    df
    A B C D
    a 49 10 86 64
    b 6 74 62 13
    c 49 79 14 25

    DataFrame属性:values、columns、index、shape

    df.values
    array([[49, 10, 86, 64],
           [ 6, 74, 62, 13],
           [49, 79, 14, 25]]
    )
    df.columns
    Index(['A''B''C''D'], dtype='object')
    df.index
    Index(['a''b''c'], dtype='object')
    df.shape
    (3, 4)

    试做:使用ndarray创建DataFrame:创建一个表格用于展示张三,李四,王五的java,python的成绩

    dic = {
        '张三':[150,150,150,150],
        '李四':[0,0,0,0]
    }

    df = DataFrame(data=dic,index=['语文','数学','英语','理综'])
    df
    张三 李四
    语文 150 0
    数学 150 0
    英语 150 0
    理综 150 0

    DataFrame的索引

    (1) 对列进行索引

    - 通过类似字典的方式  df['q']
    - 通过属性的方式     df.q

    可以将DataFrame的列获取为一个Series。返回的Series拥有原DataFrame相同的索引,且name属性也已经设置好了,就是相应的列名。

    df
    张三 李四
    语文 150 0
    数学 150 0
    英语 150 0
    理综 150 0
    # 修改列索引
    df['张三']   # 返回的是Series
    语文    150
    数学    150
    英语    150
    理综    150
    Name: 张三, dtype: int64
    # 获取前两列
    df[['李四','张三']]
    李四 张三
    语文 0 150
    数学 0 150
    英语 0 150
    理综 0 150

    (2) 对行进行索引

    - 使用.loc[]index来进行行索引
    - 使用.iloc[]加整数来进行行索引

    同样返回一个Series,index为原来的columns。

    df.loc['语文']
    张三    150
    李四      0
    Name: 语文, dtype: int64
    df.iloc[0]
    张三    150
    李四      0
    Name: 语文, dtype: int64
    df.iloc[[0,1]]
    张三 李四
    语文 150 0
    数学 150 0

    (3) 对元素索引的方法
    - 使用列索引
    - 使用行索引(iloc[3,1] or loc['C','q']) 行索引在前,列索引在后

    df['张三']['英语']
    150
    df.loc['英语','张三']  # 逗号左方:行,右方:列
    150
    df.loc[['数学','理综'],'张三']  # 逗号左方:行,右方:列
    数学    150
    理综    150
    Name: 张三, dtype: int64

    切片:

    【注意】
    直接用中括号时:

    • 索引表示的是列索引
    • 切片表示的是行切片
    df
    张三 李四
    语文 150 0
    数学 150 0
    英语 150 0
    理综 150 0
    df[0:2]
    张三 李四
    语文 150 0
    数学 150 0

    在loc和iloc中使用切片(切列) : df.loc['B':'C','丙':'丁']

    df.iloc[:,0:1]
    张三
    语文 150
    数学 150
    英语 150
    理综 150

    索引:

    • df[列索引]:取一列
    • df[[col1,col2]]:取出两列
    • df.loc[显示的行索引]:取行
    • df.loc[行,列]:取元素
      切片:
    • df[index1:index3]:切行
    • df.loc[col1:col3]:切列

    3)DataFrame的运算

    (1) DataFrame之间的运算

    同Series一样:

    • 在运算中自动对齐不同索引的数据
    • 如果索引不对应,则补NaN

    创建DataFrame df1 不同人员的各科目成绩,月考一

    创建DataFrame df2 不同人员的各科目成绩,月考二
    有新学生转入

    ============================================
    练习6

    1. 假设ddd是期中考试成绩,ddd2是期末考试成绩,请自由创建ddd2,并将其与ddd相加,求期中期末平均值。

    2. 假设张三期中考试数学被发现作弊,要记为0分,如何实现?

    3. 李四因为举报张三作弊立功,期中考试所有科目加100分,如何实现?

    4. 后来老师发现有一道题出错了,为了安抚学生情绪,给每位学生每个科目都加10分,如何实现?

    ============================================
    qizhong = df
    qimo = df
    (qizhong + qimo)/2
    张三 李四
    语文 150.0 0.0
    数学 150.0 0.0
    英语 150.0 0.0
    理综 150.0 0.0
    qizhong.loc['数学','张三'] = 0
    qizhong
    张三 李四
    语文 150 0
    数学 0 0
    英语 150 0
    理综 150 0
    qizhong['李四'] += 100
    qizhong
    张三 李四
    语文 150 100
    数学 150 100
    英语 150 100
    理综 150 100
    qizhong += 10
    qizhong
    张三 李四
    语文 160 110
    数学 160 110
    英语 160 110
    理综 160 110

    股票项目

    https://www.joinquant.com/

    tushare官网tushare.orghttps://tushare.pro/

    • 使用tushare包获取某股票的历史行情数据。
    import tushare as ts
    df = ts.get_k_data('600519',start='2020-08-10')
    df.to_csv('./maotai.csv'# 持久化储存
    df = pd.read_csv('./maotai.csv')
    df
    Unnamed: 0 date open close high low volume code
    0 0 2020-08-10 1627.97 1633.99 1644.96 1608.11 23624.0 600519
    1 1 2020-08-11 1640.00 1642.51 1666.43 1640.00 35818.0 600519
    2 2 2020-08-12 1633.00 1626.95 1641.00 1605.25 27934.0 600519
    3 3 2020-08-13 1630.00 1635.00 1638.88 1609.00 20541.0 600519
    4 4 2020-08-14 1639.90 1661.00 1665.70 1631.00 37653.0 600519
    df.drop(labels='Unnamed: 0',axis=1,inplace=True)
    # drop函数中0是行。删除行,inplace=True:在原数据中删除。
    # 验证data列中数据的数据类型
    type(df['date'][2])  # str
    df.head(2)
    date open close high low volume code
    0 2020-08-10 1627.97 1633.99 1644.96 1608.11 23624.0 600519
    1 2020-08-11 1640.00 1642.51 1666.43 1640.00 35818.0 600519
    # 将date这一列的数据转成时间类型然后将其作为原数据的行索引
    df = pd.read_csv('./maotai.csv',index_col='date',parse_dates=['date'])
    # index_col:将列转为行索引,parse_dates:设置为时间类型
    df.drop(labels='Unnamed: 0',axis=1,inplace=True)
    df
    open close high low volume code
    date
    2020-08-10 1627.97 1633.99 1644.96 1608.11 23624.0 600519
    2020-08-11 1640.00 1642.51 1666.43 1640.00 35818.0 600519
    2020-08-12 1633.00 1626.95 1641.00 1605.25 27934.0 600519
    2020-08-13 1630.00 1635.00 1638.88 1609.00 20541.0 600519
    2020-08-14 1639.90 1661.00 1665.70 1631.00 37653.0 600519

    输出该股票所有收盘比开盘上涨1%以上的日期

    #(收盘-开盘)/开盘 > 0.01
    (df['close'] - df['open']) / df['open'] > 0.01
    #True:满足需求
    #false:不满足
    date
    2020-08-10    False
    2020-08-11    False
    2020-08-12    False
    2020-08-13    False
    2020-08-14     True
    dtype: bool
    #返回了满足需求的行数据
    df.loc[(df['close'] - df['open']) / df['open'] > 0.01]
    open close high low volume code
    date
    2020-08-14 1639.9 1661.0 1665.7 1631.0 37653.0 600519
    #获取了满足需求的日期
    df.loc[(df['close'] - df['open']) / df['open'] > 0.01].index

    # 结论:如果获取了一组布尔值,接下来改组布尔值就直接作为元数据的行索引
    DatetimeIndex(['2020-08-14'], dtype='datetime64[ns]', name='date', freq=None)
    • 输出该股票所有开盘比前日收盘跌幅超过2%的日期。
    • (开盘-前日收盘)/ 前日收盘 < -0.02
    # (df['open'] - df['close'].shift(1))/df['close'].shift(1) < -0.02
    # df['close'].shift(1):将close一列下移一列
    #满足需求的行数据
    df.loc[(df['open'] - df['close'].shift(1))/df['close'].shift(1) < -0.02].index
    • 假如我从2010年1月1日开始,每月第一个交易日买入1手股票,每年最后一个交易日卖出所有股票,到19年9月为止,我的收益如何?
    • 分析:
      • 规则:基于开盘价股票的买卖
      • 买:一个完整的年需要买12次股票,一次买入100只,一个完整的年需要买入1200只(单价:当天开盘价)
      • 卖:一个完整的年需要卖一次股票,一次卖出1200只
      • 备注:19年不是一个完整的年,该年只可以买入900只,并且卖不出去
    df_new = df['2010':'2019']  # 切片,['2010-01':'2019-09']也可以
    # 数据的重新取样的机制(resample):根据指定好的规则进行指定数据的提取
    df_monthly = df_new.resample('M').first() # 年:A,月:M
    # 计算出买股票一共花了多少钱
    cost_monry = df_monthly['open'].sum()*100
    cost_monry
    • 卖出所有的股票一共进账多少钱
      • 每年最后一个交易日以开盘价为单价进行卖出
    df_yearly = df_new.resample('A').last()
    df_yearly = df_yearly[:-1]
    recv_monry = df_yearly['open'].sum()*1200
    • 19年买入了900只股票没有卖出,剩余的股票也计算到总收益
      • 剩余股票的单价应该选择使用昨日的收盘价
    last_price = df.iloc[-1]['close']
    cunHuo_price = last_price * 900
    #计算总收益
    cunHuo_price+recv_monry-cost_monry # 528908.7

    处理丢失数据

    有两种丢失数据:

    • None
    • np.nan(NaN)

    None是Python自带的,其类型为python object。因此,None不能参与到任何计算中。

    np.nan(NaN)是浮点类型,能参与到计算中。但计算的结果总是NaN。

    pandas中None与np.nan都视作np.nan

    pandas处理空值操作

    • isnull()
    • notnull()
    • dropna(): 过滤丢失数据
    • fillna(): 填充丢失数据

    创建DataFrame,给其中某些元素赋值为nan

    (1)判断函数

    • isnull()

    • notnull()

    • df.notnull/isnull().any()/all()

    过滤df中的空值(只保留没有空值的行)

    df.dropna() 可以选择过滤的是行还是列(默认为行):axis中0表示行,1表示的列

    (3) 填充函数 Series/DataFrame

    • fillna():value和method参数。

    可以选择前向填充还是后向填充。

    method 控制填充的方式 bfill ffill

    练习7:

    1. 简述None与NaN的区别

    2. 假设张三李四参加模拟考试,但张三因为突然想明白人生放弃了英语考试,因此记为None,请据此创建一个DataFrame,命名为ddd3

    3. 老师决定根据用数学的分数填充张三的英语成绩,如何实现?
        用李四的英语成绩填充张三的英语成绩?
  • 相关阅读:
    第五章 面向方面编程___通知类型
    从 C++ 到ObjectiveC
    iPhone/Mac ObjectiveC内存管理教程和原理剖析(三)@property (retain)和@synthesize的默认实现
    两个操作字符串的方法:读取指定位置的字符和找出某个字符串的位置
    SQLITE3使用总结
    iphone中如何进行多线程编程
    sqlite数据库在IOS中的运用
    重载、覆盖、隐藏
    (转)c/c++ 内存管理
    iPhone/Mac ObjectiveC内存管理教程和原理剖析(四)系统自动创建新的autorelease pool
  • 原文地址:https://www.cnblogs.com/wby-110/p/13511035.html
Copyright © 2020-2023  润新知