74528


### 背景

時系列データの分析を行おうと思っております。  
各時刻ごとにseriesを作ってcorrを出そうとしているのですが、NaNになってうまく参照できません。（おそらくデータフレームのインデックスが悪さをしているものと思われます）

row_dataは以下で指定したデータフレームです。  
ドル円の価格データ、時刻（UTC）を格納してます。

[code]

    row_data = pd.DataFrame()
    row_data.index = pd.to_datetime( a_time ,unit='s' )
    
[/code]

以下はrow_dataの中身です。  
（黒塗りしている部分は学習させようとしているとある特徴量です、秘密となって申し訳ありません）

[![画像の説明をここに入力](https://i.stack.imgur.com/4ZaJs.png)](https://i.stack.imgur.com/4ZaJs.png)

### 欲しいもの

お尋ねしたいことは、インデックスを置き換えて各時間帯ごとのドル円の動きの相関を計算する方法です。

相関を計算したい背景としては、以下の二つがございます。

  1. 「この時間帯は売られている傾向にある」「この時間帯は価格がほとんど動かない」といった時間帯別の動きを分析したい
  2. 「この時間帯で売りだったら、同じ日の別の時間帯でも売りだな」といった同じ日のプライスアクションの推定に使いたい

時間帯別に分けるために、あえてrow_data.query('time.dt.hour % 24 == ？？')としてmodを計算しております。

もし叶うなら、price0 ～ price23という指定方法もスマートな記法でないので直したいです。

よろしくお願いいたします。

以下、問題のコード

[code]

    price0 = row_data.query('time.dt.hour % 24 == 0')["price"]
    price1 = row_data.query('time.dt.hour % 24 == 1')["price"]
    price2 = row_data.query('time.dt.hour % 24 == 2')["price"]
    price3 = row_data.query('time.dt.hour % 24 == 3')["price"]
    price4 = row_data.query('time.dt.hour % 24 == 4')["price"]
    price5 = row_data.query('time.dt.hour % 24 == 5')["price"]
    price6 = row_data.query('time.dt.hour % 24 == 6')["price"]
    price7 = row_data.query('time.dt.hour % 24 == 7')["price"]
    price8 = row_data.query('time.dt.hour % 24 == 8')["price"]
    price9 = row_data.query('time.dt.hour % 24 == 9')["price"]
    price10 = row_data.query('time.dt.hour % 24 == 10')["price"]
    price11 = row_data.query('time.dt.hour % 24 == 11')["price"]
    price12 = row_data.query('time.dt.hour % 24 == 12')["price"]
    price13 = row_data.query('time.dt.hour % 24 == 13')["price"]
    price14 = row_data.query('time.dt.hour % 24 == 14')["price"]
    price15 = row_data.query('time.dt.hour % 24 == 15')["price"]
    price16 = row_data.query('time.dt.hour % 24 == 16')["price"]
    price17 = row_data.query('time.dt.hour % 24 == 17')["price"]
    price18 = row_data.query('time.dt.hour % 24 == 18')["price"]
    price19 = row_data.query('time.dt.hour % 24 == 19')["price"]
    price20 = row_data.query('time.dt.hour % 24 == 20')["price"]
    price21 = row_data.query('time.dt.hour % 24 == 21')["price"]
    price22 = row_data.query('time.dt.hour % 24 == 22')["price"]
    price23 = row_data.query('time.dt.hour % 24 == 23')["price"]
    
    timedata = pd.DataFrame()
    timedata["price0"] = price0
    timedata["price1"] = price1
    timedata["price2"] = price2
    timedata["price3"] = price3
    timedata["price4"] = price4
    timedata["price5"] = price5
    timedata["price6"] = price6
    timedata["price7"] = price7
    timedata["price8"] = price8
    timedata["price9"] = price9
    timedata["price10"] = price10
    timedata["price11"] = price11
    timedata["price12"] = price12
    timedata["price13"] = price13
    timedata["price14"] = price14
    timedata["price15"] = price15
    timedata["price16"] = price16
    timedata["price17"] = price17
    timedata["price18"] = price18
    timedata["price19"] = price19
    timedata["price20"] = price20
    timedata["price21"] = price21
    timedata["price22"] = price22
    timedata["price23"] = price23
    
    timedata.corr()
    
[/code]

* * *

### 追記1

出力結果の画像：  
下図参照。対話型の環境で timedata.corr() と一文のみ叩いた結果です。  
（Google Colab使用）

[![画像の説明をここに入力](https://i.stack.imgur.com/J6tfz.png)](https://i.stack.imgur.com/J6tfz.png)

### 追記2

以下のコマンドを実行した結果を貼ります

[code]

    print(timedata.dtypes)
    
    price0     float64
    price1     float64
    price2     float64
    price3     float64
    price4     float64
    price5     float64
    price6     float64
    price7     float64
    price8     float64
    price9     float64
    price10    float64
    price11    float64
    price12    float64
    price13    float64
    price14    float64
    price15    float64
    price16    float64
    price17    float64
    price18    float64
    price19    float64
    price20    float64
    price21    float64
    price22    float64
    price23    float64
    dtype: object
    
[/code]

[code]

    print(timedata.head())
    
                             price0  price1  price2  ...  price21  price22  price23
    2020-02-14 00:04:53  107.592214     NaN     NaN  ...      NaN      NaN      NaN
    2020-02-15 00:04:03  108.605378     NaN     NaN  ...      NaN      NaN      NaN
    2020-02-16 00:03:05  104.148801     NaN     NaN  ...      NaN      NaN      NaN
    2020-02-17 00:04:56  104.670248     NaN     NaN  ...      NaN      NaN      NaN
    2020-02-18 00:02:49  102.353737     NaN     NaN  ...      NaN      NaN      NaN
    
[/code]

### 追記３

oriri様のコマンドを試したところ、同じく望む結果が得られました。ありがとうございました！

[code]

    #print(timedata.head())
    row_data['hour'] = row_data.time.dt.hour; row_data['idx'] = row_data.groupby(['hour']).cumcount(); t_df = row_data.pivot(index='idx', columns='hour', values='price');
    t_df
    
    ---------------------------------------------------------------------------
    hour    0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16  17  18  19  20  21  22  23
    idx                                                                                             
    0   101.466057  100.736002  100.613901  100.550625  100.040697  99.336579   99.565088   99.802942   99.615076   101.952404  101.723916  101.457435  101.356704  101.084811  101.348601  100.937615  100.536535  98.637930   99.698924   100.006355  99.449476   99.796364   99.678555   100.546013
    1   99.220459   98.619188   99.204835   98.989250   99.203553   99.896366   99.901667   99.571404   99.957212   100.023744  100.018346  99.273064   98.484291   98.480936   97.399156   98.063215   98.525274   98.860104   98.408608   98.352853   98.606536   98.449535   98.447897   98.291042
    2   103.406300  102.998132  103.018872  103.494632  103.299935  103.028391  103.057140  102.373089  102.546459  99.522024   99.020597   99.059842   99.045411   98.607208   98.365976   98.904512   100.218330  100.846127  101.373579  101.751316  102.223781  103.480178  102.521503  103.394961
    3   98.220579   98.334953   98.081711   97.962889   97.777987   97.718834   97.682106   98.161300   98.175861   103.356480  103.129635  103.046662  103.508397  102.966195  103.054323  103.265744  103.266786  103.617703  103.332107  103.747723  103.449175  102.776059  97.755187   98.859030
    4   98.042543   97.974252   98.381533   98.380449   98.831023   98.775352   98.675039   98.685778   98.556643   97.510241   98.027801   98.031343   97.685927   97.426084   97.828133   97.839126   97.759634   98.404448   97.237050   97.201989   97.516242   97.767862   98.191744   98.138238
    ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
    
    
[/code]


CC BY-SA 4.0
2021-03-08T11:50:41.460
74525
2021-03-12T10:03:26.523
2021-03-12T09:35:48.350
44249
44249
question
python python3 pandas google-colaboratory
Pythonのdataframeで、各時刻ごとにデータをグループ化して相関を計算する方法


[バックテスティングの改善に役立つForexヒストリカルデータの検索方法](https://forextester.jp/data/datasources)
から 「USDJPY 2001年1月 - 2021年02月28日」(`USDJPY.zip`)をダウンロードして、2020 年のデータを抽出します。

[code]

    $ unzip -p USDJPY.zip | grep -P 'USDJPY,2020\d{4},\d{2}0000,' > 2020_USDJPY_hourly.txt
    
[/code]

`pandas.read_csv`
で読み込んで、[pandas.pivot_table](https://pandas.pydata.org/pandas-
docs/stable/reference/api/pandas.pivot_table.html) で
`time_data`(dataframe)を作成します。

[code]

    import pandas as pd
    
    row_data = pd.read_csv(
      '2020_USDJPY_hourly.txt',
      header=None, usecols=[1, 2, 6], names=('date', 'time_', 'price'),
      parse_dates={'time': [0, 1]}
    )
    
    time_data = pd.pivot_table(
      row_data,
      index=row_data.time.dt.date,
      columns=row_data.time.dt.hour, values='price')
    
    print(time_data.head(10))
    =>
    time            0       1       2       3       4   ...      19      20      21      22      23
    time                                                ...                                        
    2020-01-01     NaN     NaN     NaN     NaN     NaN  ...     NaN     NaN     NaN     NaN  108.67
    2020-01-02  108.71  108.68  108.65  108.66  108.70  ...  108.51  108.53  108.54  108.56  108.53
    2020-01-03  108.53  108.39  108.19  108.05  108.17  ...  108.04  108.00  108.09     NaN     NaN
    2020-01-05     NaN     NaN     NaN     NaN     NaN  ...     NaN     NaN     NaN     NaN  107.79
    2020-01-06  107.96  108.06  107.93  108.02  108.04  ...  108.35  108.44  108.42  108.36  108.36
    2020-01-07  108.40  108.41  108.42  108.46  108.46  ...  108.53  108.52  108.54  108.44  108.44
    2020-01-08  107.99  107.85  108.01  108.38  108.35  ...  109.12  109.22  109.02  109.11  109.06
    2020-01-09  109.02  109.17  109.23  109.18  109.18  ...  109.44  109.50  109.49  109.51  109.46
    2020-01-10  109.48  109.48  109.53  109.52  109.52  ...  109.52  109.51  109.49     NaN     NaN
    2020-01-12     NaN     NaN     NaN     NaN     NaN  ...     NaN     NaN     NaN     NaN  109.52
    
    [10 rows x 24 columns]
    
[/code]

このデータフレームに `pandas.corr()` を適用します。

[code]

    print(time_data.corr())
    =>
    time        0         1         2         3   ...        20        21        22        23
    time                                          ...                                        
    0     1.000000  0.998382  0.994957  0.994449  ...  0.960008  0.959208  0.966937  0.969895
    1     0.998382  1.000000  0.996297  0.995821  ...  0.963861  0.963568  0.969982  0.972866
    2     0.994957  0.996297  1.000000  0.999167  ...  0.964468  0.965223  0.971737  0.974439
    3     0.994449  0.995821  0.999167  1.000000  ...  0.965086  0.966191  0.972655  0.975659
    4     0.993758  0.995235  0.998780  0.999420  ...  0.967782  0.969106  0.975706  0.978260
    5     0.992907  0.994802  0.997218  0.997928  ...  0.971550  0.972953  0.977688  0.980040
    6     0.991715  0.993290  0.996010  0.996716  ...  0.971927  0.973570  0.977406  0.979626
    7     0.991353  0.993005  0.995414  0.996074  ...  0.972183  0.974012  0.978173  0.980512
    8     0.989586  0.991248  0.994801  0.995423  ...  0.974502  0.976031  0.980188  0.982476
    9     0.989127  0.990321  0.992793  0.993327  ...  0.978027  0.979207  0.982307  0.984337
    10    0.987345  0.988976  0.990808  0.991402  ...  0.980707  0.981875  0.983737  0.985517
    11    0.984182  0.986479  0.988754  0.989333  ...  0.982878  0.984315  0.986281  0.987737
    12    0.981294  0.983719  0.985908  0.986504  ...  0.985817  0.986936  0.988243  0.989538
    13    0.979470  0.981863  0.983568  0.984141  ...  0.987895  0.988728  0.989782  0.990849
    14    0.977615  0.980218  0.980394  0.980647  ...  0.991935  0.992034  0.993162  0.994264
    15    0.974396  0.976925  0.977749  0.977743  ...  0.994198  0.993840  0.994864  0.995547
    16    0.970320  0.972823  0.972006  0.972138  ...  0.995696  0.994675  0.995603  0.995509
    17    0.966733  0.969695  0.970327  0.970445  ...  0.997612  0.996696  0.997372  0.997141
    18    0.965993  0.969202  0.969905  0.970339  ...  0.998055  0.997251  0.997702  0.997614
    19    0.961176  0.965142  0.966406  0.966674  ...  0.999221  0.998561  0.998875  0.998385
    20    0.960008  0.963861  0.964468  0.965086  ...  1.000000  0.998917  0.999069  0.998543
    21    0.959208  0.963568  0.965223  0.966191  ...  0.998917  1.000000  0.999632  0.999018
    22    0.966937  0.969982  0.971737  0.972655  ...  0.999069  0.999632  1.000000  0.999341
    23    0.969895  0.972866  0.974439  0.975659  ...  0.998543  0.999018  0.999341  1.000000
    
    [24 rows x 24 columns]
    
[/code]


CC BY-SA 4.0
2021-03-08T15:20:17.280
74528
2021-03-09T04:51:54.487
2021-03-09T04:51:54.487
74525
answer


問題の処理は, 時間ごとにデータを一つ一つ取り出し, それを column として DataFrameを構築しようとしているようですが, 最初のステップで
index が決定されているようです

[code]

    timedata = pd.DataFrame()
    timedata["price0"] = price0
    
[/code]

indexは, 特に何も指定していなければ行の indexであり, 最初の追加時点の indexは `0, 24, 48 … ` と続くはずです。  
これに続けて, 別の時間帯のデータを追加しようとしても, indexがマッチせず, そのためデータが存在しないままになるはず

この(一つ一つの)データ追加時に, (それぞれ) reset_index などで indexを割り振れば追加可能なはず  
(ただし, すべての時間帯のデータ数が同じ場合)

* * *

これらをもっと簡単にするには, Pandas らしく, ベクトルでデータ処理することです

[code]

    row_data['hour'] = row_data.time.dt.hour
    row_data['idx'] = row_data.groupby(['hour']).cumcount()
    timedata = row_data.pivot(index='idx', columns='hour', values='price')
    
[/code]


CC BY-SA 4.0
2021-03-12T10:03:26.523
74623
2021-03-12T10:03:26.523
43025
74525
answer