python pandas による日付処理


pandasで日付の処理をしており、該当する日付がなければ新しい行を加えるという処理をしようとしています。  
そこで次のようなコードを書きました。  
リスト内には存在するのにin演算子には引っかからないという現象が起きてしまい、原因がさっぱりわかりません。もしよろしければ原因を教えてください。

[code]

    def complement_date(self,pandas_arr):
        keys = pandas_arr.keys()
        dates = pandas_arr[keys[0]]# date info in first index
        dateidx = START# START = datetime.datitme(2013,8,1,0,0)
        while END>=dateidx:
            if not pd.to_datetime(dateidx) in dates:
                pdb.set_trace()
                tmp = pd.Series([dateidx,0],index=keys)
                pandas_arr = pandas_arr.append(tmp,ignore_index=True)
            dateidx = dateidx + DAY# DAY = datetime.timedelta(days=1)
        return pandas_arr
    
[/code]

[![デバッグ画面](https://i.stack.imgur.com/xVs9w.png)](https://i.stack.imgur.com/xVs9w.png)




`in` は `Index` との比較になるためです。

[code]

    import pandas as pd
    dates = pd.Series(pd.date_range('2011-01-01', '2011-01-05', freq='D'))
    dates
    # 0   2011-01-01
    # 1   2011-01-02
    # 2   2011-01-03
    # 3   2011-01-04
    # 4   2011-01-05
    # dtype: datetime64[ns]
    
    t = pd.Timestamp('2011-01-01')
    t == dates[0]
    # True
    
    t in dates
    # False
    
    0 in dates
    # True
    
[/code]

値に含まれるかは以下で確認できます。

[code]

    (t == dates).any()
    # True
    
[/code]

* * *

コメントに対する追記:

> t in dates.values #False の解釈

まず、`dates.values` は `numpy.ndarray` 型を返します。そのため、以下の記載は `pandas` ではなく `NumPy`
の挙動に関する説明になります。

[code]

    dates.values
    # array(['2011-01-01T09:00:00.000000000+0900',
    #        '2011-01-02T09:00:00.000000000+0900',
    #        '2011-01-03T09:00:00.000000000+0900',
    #        '2011-01-04T09:00:00.000000000+0900',
    #        '2011-01-05T09:00:00.000000000+0900'], dtype='datetime64[ns]')
    
    type(dates.values)
    # <type 'numpy.ndarray'>
    
[/code]

`numpy.ndarray` は `in` 演算子をサポートしています。`NumPy` の日時型である
`numpy.datetime64`を渡せば期待通り動きます。

[code]

    import numpy as np
    
    np.datetime64('2011-01-01T09:00:00.000000000+0900') in dates.values
    # True
    
[/code]

`pandas` の `Timestamp` 型から `numpy.datetime64` 型への変換は `asm8` プロパティで可能です。そのため、
`in` を使う場合は下のようになります。

[code]

    t.asm8
    # numpy.datetime64('2011-01-01T09:00:00.000000000+0900')
    
    t.asm8 in dates.values
    # True
    
[/code]




`in` は `Index` との比較になるためです。

[code]

    import pandas as pd
    dates = pd.Series(pd.date_range('2011-01-01', '2011-01-05', freq='D'))
    dates
    # 0   2011-01-01
    # 1   2011-01-02
    # 2   2011-01-03
    # 3   2011-01-04
    # 4   2011-01-05
    # dtype: datetime64[ns]
    
    t = pd.Timestamp('2011-01-01')
    t == dates[0]
    # True
    
    t in dates
    # False
    
    0 in dates
    # True
    
[/code]

値に含まれるかは以下で確認できます。

[code]

    (t == dates).any()
    # True
    
[/code]

* * *

コメントに対する追記:

> t in dates.values #False の解釈

まず、`dates.values` は `numpy.ndarray` 型を返します。そのため、以下の記載は `pandas` ではなく `NumPy`
の挙動に関する説明になります。

[code]

    dates.values
    # array(['2011-01-01T09:00:00.000000000+0900',
    #        '2011-01-02T09:00:00.000000000+0900',
    #        '2011-01-03T09:00:00.000000000+0900',
    #        '2011-01-04T09:00:00.000000000+0900',
    #        '2011-01-05T09:00:00.000000000+0900'], dtype='datetime64[ns]')
    
    type(dates.values)
    # <type 'numpy.ndarray'>
    
[/code]

`numpy.ndarray` は `in` 演算子をサポートしています。`NumPy` の日時型である
`numpy.datetime64`を渡せば期待通り動きます。

[code]

    import numpy as np
    
    np.datetime64('2011-01-01T09:00:00.000000000+0900') in dates.values
    # True
    
[/code]

`pandas` の `Timestamp` 型から `numpy.datetime64` 型への変換は `asm8` プロパティで可能です。そのため、
`in` を使う場合は下のようになります。

[code]

    t.asm8
    # numpy.datetime64('2011-01-01T09:00:00.000000000+0900')
    
    t.asm8 in dates.values
    # True
    
[/code]

