『Pythonデータ分析とデータマイニング実戦』第十章学習——データ洗浄


本章のオンライン実験部分はモデルに重点を置いていないが,データの前処理にあり,本文にも具体的なコードはない.そこで,本稿では主にデータの前処理を記録し,主に用水イベント区分,用水時間長,総用水量,平均水流量などを含む.主に次の手順があります.
  • データ
  • を読み出す.
  • 区分用水事件
  • イベント開始時間と終了時間
  • を追加
  • 計算用水時間と平均水流量
  • 計算水流量変動
  • まとめ
  • データの読み込み
    データを読み込むコードは次のとおりです.
    import pandas as pd
    from pandas import Series,DataFrame
    import numpy as np
    data=pd.read_excel("D:/ProgramData/PythonDataAnalysiscode/chapter10/demo/data/water_heater.xls")

    分水事件
    本の中の1つの用水事件の説明によると、間隔が4分より大きいのは別の用水事件の始まりである.したがって、すべての水流量が0より大きい記録を選択し、4分間を閾値として各用水イベントを導出した後、用水イベント中の水流量が0の記録を埋め込み、イベント開始データ番号と終了データ番号を導出する.コードは次のとおりです.
    #      
    threshold=pd.Timedelta(minutes=4)
    data[u'    ']=pd.to_datetime(data[u'    '],format='%Y%m%d%H%M%S')
    data=data[data[u'   ']>0]
    d=data[u'    '].diff()>threshold
    data[u'    ']=d.cumsum()+1
    data_1=DataFrame(columns=[u'    ',u'        ',u'        '])
    start_list=[]
    end_list=[]
    data_all=data_0[0:0]
    #d.sum()+1    
    for i in range(1,d.sum()+2):
    
        x=data[data[u'    ']==i][:1].index[0]
        y=data[data[u'    ']==i][-1:].index[0]
        #     0       
        data_all=pd.concat([data_all,data_0[x:y+1]])
    
        start_list.append(x)
        end_list.append(y)
    data_1[u'    ']=np.arange(1,d.sum()+2)
    data_1[u'        ']=start_list
    data_1[u'        ']=end_list
    data_all=pd.concat([data_all,data[u'    ']],axis=1)
    #     
    data_all=data_all.fillna(method='ffill')
    data_all[u'    ']=data_all[u'    '].astype('int64')
    data_all[u'   ']=data_all[u'   '].astype('float64')

    イベント開始時間と終了時間の追加
    本書の意味では、各イベントの開始発生時間から送信しきい値の半分をイベント開始時間とし、各イベントの終了発生時間から送信しきい値の半分をイベント終了時間とする.コードは次のとおりです.
    #             
    #     2
    s=pd.Timedelta(seconds=2)    
    time_s_list=[]  
    time_e_list=[]
    for j in range(1,d.sum()+2):
        t1=data[data[u'    ']==j].iloc[0,0]-s/2
        t2=data[data[u'    ']==j].iloc[-1,0]+s/2
        time_s_list.append(t1)
        time_e_list.append(t2)
    data_1[u'      ']=time_s_list
    data_1[u'      ']=time_e_list

    水の時間と平均水流量を計算する
    総用水時間は、用水時間の長さに加えて停止時間の長さに等しく、一次水流量が0でない総時間は一度の用水時間の長さである.最後に、総用水時間長と用水時間長の減少を用いて停止時間長を求めることができ、水流量0の記録数を用いて1回の用水イベントにおける停止回数を得ることができる.毎回の用水時間に1回の用水を掛ける水流量が用水量であり、1回の用水イベントにおけるすべての水流量を加算すると総用水量であり、総用水量/用水時間が長くなると平均水流量である.コードは次のとおりです.
    #    
    data_1[u'     ']=data_1[u'      ']-data_1[u'      ']
    #        
    data_1[u'     ']=data_1[u'     ']/np.timedelta64(1,'s')
    #             ,        
    data_all[u'    ']=data_all[u'    '].diff()
    
    #              
    
    def get_time(x):
    
        if len(x)==1:
            dt=pd.Timedelta(seconds=0)
            dv=((dt+s)/np.timedelta64(1,'s'))*x.iloc[0,6]
            dc=0
    
        else:
            #       
            lindex=[]
            for k in range(len(x)):
                #    0,         
                if x.iloc[k,6]!=0:
                    lindex.append(k)
            #      ,      ,    0   
            dc=len(x)-len(lindex)
            #             
            dt=pd.Timedelta(seconds=0)
            dv=0
            ds=0
            for m in lindex:
                #    =(     0)         /2+         /2
                if m==0:
                    dt=dt+x.iloc[m+1,10]/2
    
                elif m==len(x)-1:
                    dt=dt+x.iloc[m,10]/2
    
                else:
                    dt=dt+(x.iloc[m,10])/2+(x.iloc[m+1,10])/2
                #    =       *   
                dv=dv+(dt/np.timedelta64(1,'s'))*x.iloc[m,6]
    
    
        return (dt,dv,dc)
    dt_list=[]
    dv_list=[]
    dc_list=[]
    for n in range(1,d.sum()+2):
        dt,dv,dc=get_time(data_all[data_all[u'    ']==n])
        dt_list.append(dt+s)
        dv_list.append(dv)
        dc_list.append(dc)
    data_1[u'    ']=dt_list
    
    #        
    data_1[u'    ']=data_1[u'    ']/np.timedelta64(1,'s')
    data_1[u'    ']=data_1[u'     ']-data_1[u'    ']
    data_1[u'    ']=dv_list
    data_1[u'    ']=dc_list
    data_1[u'      ']=data_1[u'    ']/data_1[u'    ']
    data_1[u'     ']=data_1[u'    ']/data_1[u'    ']

    水流変動の計算
    本の意味では、水流量の変動は(単回水流値-平均水流量)^2*持続時間/総水流量のある時間である.コードは次のとおりです.
    #        
    ds_list=[]
    for a in range(1,d.sum()+2):
        ddata=data_all[data_all[u'    ']==a]
    
        ds=0.0
        if len(ddata)==1:
            dt_b=s
            ds=ds+((ddata.iloc[0,6]-data_1.iloc[a-1,11])**2*(dt_b/np.timedelta64(1,'s')))/(data_1.iloc[a-1,6])
        else:
    
            for b in range(len(ddata)):
                if b==0:
                    dt_b=ddata.iloc[b+1,10]/2
    
                elif b==len(ddata)-1:
                    dt_b=ddata.iloc[b,10]/2
    
                else:
                    dt_b=(ddata.iloc[b,10])/2+(ddata.iloc[b+1,10])/2
                #((      -     )^2*    )/         
                ds_1=ddata.iloc[b,6]-data_1.iloc[a-1,11]
                ds_1=ds_1*ds_1
                #              
                ds_2=ds_1*(dt_b/np.timedelta64(1,'s'))
                ds=ds+ds_2/(data_1.iloc[a-1,6])
        ds_list.append(ds)
    data_1[u'     ']=ds_list

    まとめ
    この章のデータ変換には手間がかかりました.本には関連コードがないので、自分で理解して書くしかありません.初めて概念を見ると複雑ではないと思いますが、本当に自分で処理するのは面倒だと思いますが、作成の過程でpandas、list、関数の運用にも熟知しており、達成感もありません.最後に、上記のコードはすべて本人が本の中の各概念と公式に対する理解を通じて自分で書いたので、理解が間違ったり、複雑な方法を選んだりする可能性があります.もし誰かが間違いを発見したり、もっと良い方法があれば、一緒に議論してほしい.