Pandas 格式處理、排序與篩選-Python 套件使用(三)

一、前言

恭喜各位來到第二篇 Pandas 囉!如果還不清楚什麼是 Pandas ,建議先看上一篇,了解基本使用方式。這邊讓大家繼續往下看更多更細的操作。跟著上一篇的格式,我們繼續沿用囉!

import pandas as pd
dic = {
    "date": ['2020/10/15', '2020/10/16', '2020/10/17', '2020/10/18', '2020/10/19',    '2020/10/20', '2020/10/21'],
    "open": [200, 300, 400, 500, 600, 700, 800],
    "close": [150, 250, 350, 450, 550, 650, 750],
}
df = pd.DataFrame(dic)
# 指定index
df = pd.DataFrame(dic, index=df['date'])

立即訂閱電子報,掌握最新資訊!

    電子郵件

    有興趣的主題
    量化交易金融知識台灣股市國內期貨海外期貨虛擬貨幣

    有興趣的量化交易軟體/平台
    不清楚MultiChartsTradingViewPythonXQMT4MT5

    還有什麼詢問的?

    好富投 1920x400
    好富投 978x258

    點我了解更多資訊


    二、基礎資訊:

    1. df.Info():

    這功能會幫你把此表格的基本資訊吐給你,有興趣的朋友可以更深入研究看看:

    # print(df.info())
    <class 'pandas.core.frame.DataFrame'>
    Index: 7 entries, 2020/10/15 to 2020/10/21
    Data columns (total 3 columns):
     #   Column  Non-Null Count  Dtype 
    ---  ------  --------------  ----- 
     0   date    7 non-null      object
     1   open    7 non-null      int64 
     2   close   7 non-null      int64 
    dtypes: int64(2), object(1)
    memory usage: 224.0+ bytes
    None

    2. df.describe():

    可以得到一張能快速瀏覽相關內部數據的統計資料,大家可以根據個人的使用情境決定是否需要。

    3.常見的四種模式:

    (1)df.to_dict(‘dict’):

    將 DataFrame 轉換為 index 為 key,內容各自對應順序為 key-value 的 dictionary 資料結構。

    (2)df.to_dict(‘list’):

    將 DataFrame 轉換為 column 為 key,整欄位為 list-value 的資料結構。

    (3)df.to_dict(‘index’):

    將 DataFrame 轉換為 index 為 key,該 row 為 list-value 的資料結構。

    (4)df.values.tolist():

    將 DataFrame 的 value 直接轉換為 list-list 的資料結構。

    # 列出 DataFrame 的 index/columns
    print(df.index)
    print(df.columns)
    
    # 表示將date資料轉移至index,下次呼叫value時,不會回傳 date,讓date成為key的概念。
    df.set_index("date" , inplace=True)
    print(df)
    
    # 重製index,取代現在的index
    df.reset_index(inplace=True) 
    print(df)
    
    
    # 以下四種操作要很熟悉
    print(df.to_dict('dict')) 
    
    print(df.to_dict('list'))  
    
    print(df.to_dict('index'))  
    
    print(df.values.tolist())  

    結果很長,我們直接看:

    # print(df.to_dict('dict'))  的結果
    {'date': {0: '2020/10/15', 1: '2020/10/16', 2: '2020/10/17', 3: '2020/10/18', 4: '2020/10/19', 5: '2020/10/20', 6: '2020/10/21'}, 'open': {0: 200, 1: 300, 2: 400, 3: 500, 4: 600, 5: 700, 6: 800}, 'close': {0: 150, 1: 250, 2: 350, 3: 450, 4: 550, 5: 650, 6: 750}}
    
    # print(df.to_dict('list')) 的結果
    {'date': ['2020/10/15', '2020/10/16', '2020/10/17', '2020/10/18', '2020/10/19', '2020/10/20', '2020/10/21'], 'open': [200, 300, 400, 500, 600, 700, 800], 'close': [150, 250, 350, 450, 550, 650, 750]}
    
    # print(df.to_dict('index'))   的結果
    {0: {'date': '2020/10/15', 'open': 200, 'close': 150}, 1: {'date': '2020/10/16', 'open': 300, 'close': 250}, 2: {'date': '2020/10/17', 'open': 400, 'close': 350}, 3: {'date': '2020/10/18', 'open': 500, 'close': 450}, 4: {'date': '2020/10/19', 'open': 600, 'close': 550}, 5: {'date': '2020/10/20', 'open': 700, 'close': 650}, 6: {'date': '2020/10/21', 'open': 800, 'close': 750}}
    
    # print(df.values.tolist()) 的結果
    [['2020/10/15', 200, 150], ['2020/10/16', 300, 250], ['2020/10/17', 400, 350], ['2020/10/18', 500, 450], ['2020/10/19', 600, 550], ['2020/10/20', 700, 650], ['2020/10/21', 800, 750]]

    範例中最後四種操作需要很熟練在運用上才會方便,在資料轉換上使用 pandas,可以將資料直接轉成想要的資料結構並且存成 csv,會大大加速資料處理整體的速度與操作步驟。

    在這些操作後,任何資料都能轉成 DataFrame。 DataFrame 基本上能轉成任何種資料形式,所以只要熟悉操作 pandas,就能將 csv 當成資料儲存的位置,將爬蟲當成資料來源,所有資料處理、轉換、增刪改,都交給 pandas 操作即可,是不是非常方便呢!

    Py 101209161710
    Py 101209161711

    三、Pandas DataFrame 的 4 種常見的操作:

    前置資料如下:

    import pandas as pd
    dic = {
        "date": ['2020/10/15', '2020/10/16', '2020/10/17', '2020/10/18', '2020/10/19', '2020/10/20', '2020/10/21'],
        "open": [200, 300, 400, 500, 600, 700, 800],
        "close": [150, 250, 350, 450, 550, 650, 750],
    }
    df = pd.DataFrame(dic)
    df = pd.DataFrame(dic, index=df['date'])
    df.set_index("date", inplace=True)
    
    print(df)

    1. 新增/修改Pandas DataFrame資料

    (1)df[‘colume_name’]:

    df["high"]=[111, 222, 333, 444, 555, 666, 777]
    print(df)
    
    """
    結果:
               open  close  high
    date                         
    2020/10/15   200    150   111
    2020/10/16   300    250   222
    2020/10/17   400    350   333
    2020/10/18   500    450   444
    2020/10/19   600    550   555
    2020/10/20   700    650   666
    2020/10/21   800    750   777
    """

    (2)df.insert:

    使用 insert 的方式,針對某一列直接插入整欄資料,就如同 list 的操作方式一樣:

    df.insert(0,"high",[111, 222, 333, 444, 555, 666, 777])
    print(df)
    
    """
    結果
               high  open  close
    date                         
    2020/10/15   111   200    150
    2020/10/16   222   300    250
    2020/10/17   333   400    350
    2020/10/18   444   500    450
    2020/10/19   555   600    550
    2020/10/20   666   700    650
    2020/10/21   777   800    750
    
    """

    (3)df.append:

    以 append 增加排(row)的方式新增資料,邏輯跟 list 類似。

    df = df.append({'open': 158, 'close' : 168}, ignore_index=True)
    print(df)

    用「ignore_index=True」能將資料新增到最後,也會自動產出一個新的 index。

      open  close
    0   200    150
    1   300    250
    2   400    350
    3   500    450
    4   600    550
    5   700    650
    6   800    750
    7   158    168 #這邊,可是因為忽略index故又變回原本的順序了

    (4)使用loc[n]針對順序插入row資料:

    df.loc['2021/12/31'] = [456, 4567]
    df.loc['2021/11/31'] = [789, 6789]
    print(df)
    
    """
    結果
               open  close
    date                   
    2020/10/15   200    150
    2020/10/16   300    250
    2020/10/17   400    350
    2020/10/18   500    450
    2020/10/19   600    550
    2020/10/20   700    650
    2020/10/21   800    750
    2021/12/31   456   4567 # 資料會新增在特定位置
    2021/11/31   789   6789 # 資料會新增在特定位置
    
    """

    有沒有發現,前面幾種方式將資料變成 index,而後面將資料照順序填入 row,在這裡其實是取代的意思,如果這數值存在就取代它,如果不存在則新增一筆。

    df.loc['2021/12/31'] = [456, 4567]
    df.loc['2020/10/16'] = [789, 6789]
    print(df)
    
    """
    結果
               open  close
    date                   
    2020/10/15   200    150
    2020/10/16   789   6789  # 原本存在會直接取代
    2020/10/17   400    350
    2020/10/18   500    450
    2020/10/19   600    550
    2020/10/20   700    650
    2020/10/21   800    750
    2021/12/31   456   4567 # 不存在的則會新增
    
    """

    2.刪除Pandas DataFrame資料

    # 使用 drop 指定欄位,記得要給定 axis=1 為欄。若 axis=0 為代表列
    drop_col = df.drop(['open'], axis=1)
    drop_row = df.drop(['2020/10/17'], axis=0)
    print(drop_col)
    print(drop_row)

    結果:

               close
    date             
    2020/10/15    150
    2020/10/16    250
    2020/10/17    350
    2020/10/18    450
    2020/10/19    550
    2020/10/20    650
    2020/10/21    750
    # 上面的 open colume 直接被 drop 掉。
    # 底下的 2020/10/17 row 也是被刪掉。
                open  close
    date                   
    2020/10/15   200    150
    2020/10/16   300    250
    2020/10/18   500    450
    2020/10/19   600    550
    2020/10/20   700    650
    2020/10/21   800    750
    

    3. 篩選Pandas DataFrame資料

    這小結會稍微難一點,因為針對取的 colume(縱向)或是 row(橫向)不同,那就可能會造成不同的取法與結果,也是一個需要熟練的部分,那主要會分成以下兩項:

    (1)df.loc:

    類似有順序的字典操作方式:

    # loc指向的是index的名稱
    print(df.loc["2020/10/19"]) #選 "2020/10/19" 的資料
    print(df.loc["2020/10/18", ['open']]) # 選"2020/10/18" 的open資料
    print(df.loc[:, ['open']] )# 選所有的open資料

    第一個結果:可以看出第一個值就是先選 row 的 index 名稱。

    第二個結果:表示選出指定的 row 之後,在針對該 row 去找對應的 colume,並取出那個欄位內的 value。

    第三個結果:則是跳過第一個,直接取出 colume = “open” 的資料

    # print(df.loc["2020/10/19"])
    open     600
    close    550
    Name: 2020/10/19, dtype: int64
    
    # print(df.loc["2020/10/18", ['open']])
    open    500
    Name: 2020/10/18, dtype: int64
    
    # print(df.loc[:, ['open']] )
                open
    date            
    2020/10/15   200
    2020/10/16   300
    2020/10/17   400
    2020/10/18   500
    2020/10/19   600
    2020/10/20   700
    2020/10/21   800

    (2)df.iloc:

    「iloc」語法,是更偏向於順序與 list切片式的做法。

    # iloc指向的是index的位置
    print(df.iloc[3])        # 取出第四個 row
    print(df.iloc[0:5, 0:1]) # 取出一個區塊 (row_idx=0, 1 and col_idx=0,1)
    print(df.iloc[1:4, :])   # 根據row index選擇
    print(df.iloc[:, 1:3])   # 根據column index選擇

    從結果中可以看出基本上邏輯就跟list一樣,主要是第三、四個結果作法與 loc一樣,都是對列、欄位下條件,進而取出需要的範圍

    注意這邊是範圍哦!跟上面的只取出指定資料不同,更像是在excel內用滑鼠框出一個區域的感覺,是不是很有感覺啊!

    # print(df.iloc[3])    的結果
    open     500
    close    450
    Name: 2020/10/18, dtype: int64
    
    # print(df.iloc[0:5, 0:1])  的結果
                open
    date            
    2020/10/15   200
    2020/10/16   300
    2020/10/17   400
    2020/10/18   500
    2020/10/19   600
    
    # print(df.iloc[1:4, :])   的結果
                open  close
    date                   
    2020/10/16   300    250
    2020/10/17   400    350
    2020/10/18   500    450
    
    # print(df.iloc[:, 1:3])  的結果
                close
    date             
    2020/10/15    150
    2020/10/16    250
    2020/10/17    350
    2020/10/18    450
    2020/10/19    550
    2020/10/20    650
    2020/10/21    750

    4.排序Pandas DataFrame資料

    首先先將取得的資料整理一下,做基本的處理。

    import pandas as pd
    new_dic = {
        "date": ['2020/10/15', '2020/10/16', '2020/10/17', '2020/10/18', '2020/10/19', '2020/10/20', '2020/10/21'],
       "open": [112, 157, 185, 112, 157, 185, 112],
        "close": [250, 250, 250, 125, 125, 125, 50],
    }
    df = pd.DataFrame(new_dic)
    df = pd.DataFrame(new_dic, index=df['date'])
    df.set_index("date", inplace=True)
    
    print(df)
    
    """
    結果
               open  close
    date                   
    2020/10/15   112    250
    2020/10/16   157    250
    2020/10/17   185    250
    2020/10/18   112    125
    2020/10/19   157    125
    2020/10/20   185    125
    2020/10/21   112     50
    
    """

    再來加入 sort 語法,排序 DataFrame 資料,這邊的邏輯就很像對表格做先後排序,跟電商網站選商品時,依照價格排序的感覺很像,都可以有先後順序的:

    # 將open列的數據依照數值大小進行小至大的排序
    sort_df = df.sort_values(['open'], ascending=True)
    print(sort_df) 
    
    # 將open、close列數據依照數值大小進行大至小排列
    sort_df = df.sort_values(['open','close'], ascending=False)
    print(sort_df) 

    結果:

    #  只針對open進行小到大的排列,但close不動
               open  close
    date                   
    2020/10/15   112    250
    2020/10/18   112    125
    2020/10/21   112     50
    2020/10/16   157    250
    2020/10/19   157    125
    2020/10/17   185    250
    2020/10/20   185    125
    
    # 第二個用法通常用在同個open值中有不同的close,並進行排序
               open  close
    date                   
    2020/10/17   185    250
    2020/10/20   185    125
    2020/10/16   157    250
    2020/10/19   157    125
    2020/10/15   112    250
    2020/10/18   112    125
    2020/10/21   112     50

    四、小結:

    看到這邊是不是眼花撩亂啊!沒關係,這種各類操作本來就是得常做才會,這很正常的!那既然各位都堅持到這邊了,就讓我們加把勁完成它吧!

    那一樣有任何心得或是想要討論,都歡迎底下留言哦!

      電子郵件

      有興趣的主題
      量化交易金融知識台灣股市國內期貨海外期貨虛擬貨幣

      有興趣的量化交易軟體/平台
      不清楚MultiChartsTradingViewPythonXQMT4MT5

      還有什麼詢問的?


      量化通粉絲社群,一起討論程式交易!

      加入LINE社群量化交易討論群」無壓力討論與分享!

      加入臉書社團「程式交易 Taiwan」即時獲取實用的資源!

      RoWay
      RoWay

      多年投資經驗的兩岸三地操盤手,曾任海外資產管理公司交易平台的產品經理、與各外商投資公司合作開發各式交易策略與系統。

      擅長用Python執行資料蒐集、整理、分析與交易;也善於用Multicharts、MetaTrader等系統建構並回測期貨、期權、區塊鏈策略進而完成投資組合管理。

      文章: 28

      發佈留言

      發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *