5

これを行うための最も効率的な方法を探している、パンダの初心者。

私は一連のデータフレームを持っています。各 DataFrame には同じ列がありますが、インデックスが異なり、日付によってインデックスが作成されます。シリーズは、ティッカー シンボルによってインデックス化されます。したがって、Sequence の各項目は、個々の株式のパフォーマンスの 1 つの時系列を表します。

n 個のデータ フレームのリストをランダムに生成する必要があります。各データ フレームは、利用可能な株式の履歴のランダムな組み合わせのサブセットです。開始日と終了日が異なっていれば、重複があっても問題ありません。

この次のコードはそれを行いますが、非常に遅いので、もっと良い方法があるかどうか疑問に思っています:

コード

def random_sample(data=None, timesteps=100, batch_size=100, subset='train'):
    if type(data) != pd.Series:
        return None

    if subset=='validate':
        offset = 0
    elif subset=='test':
        offset = 200
    elif subset=='train':
        offset = 400

    tickers = np.random.randint(0, len(data), size=len(data))

    ret_data = []
    while len(ret_data) != batch_size:
        for t in tickers:
            data_t = data[t]
            max_len = len(data_t)-timesteps-1
            if len(ret_data)==batch_size: break
            if max_len-offset < 0: continue

            index = np.random.randint(offset, max_len)
            d = data_t[index:index+timesteps]
            if len(d)==timesteps: ret_data.append(d)

    return ret_data

プロファイル出力:

Timer unit: 1e-06 s

File: finance.py
Function: random_sample at line 137
Total time: 0.016142 s

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
   137                                           @profile
   138                                           def random_sample(data=None, timesteps=100, batch_size=100, subset='train'):
   139         1            5      5.0      0.0      if type(data) != pd.Series:
   140                                                   return None
   141
   142         1            1      1.0      0.0      if subset=='validate':
   143                                                   offset = 0
   144         1            1      1.0      0.0      elif subset=='test':
   145                                                   offset = 200
   146         1            0      0.0      0.0      elif subset=='train':
   147         1            1      1.0      0.0          offset = 400
   148
   149         1         1835   1835.0     11.4      tickers = np.random.randint(0, len(data), size=len(data))
   150
   151         1            2      2.0      0.0      ret_data = []
   152         2            3      1.5      0.0      while len(ret_data) != batch_size:
   153       116          148      1.3      0.9          for t in tickers:
   154       116         2497     21.5     15.5              data_t = data[t]
   155       116          317      2.7      2.0              max_len = len(data_t)-timesteps-1
   156       116           80      0.7      0.5              if len(ret_data)==batch_size: break
   157       115           69      0.6      0.4              if max_len-offset < 0: continue
   158
   159       100          101      1.0      0.6              index = np.random.randint(offset, max_len)
   160       100        10840    108.4     67.2              d = data_t[index:index+timesteps]
   161       100          241      2.4      1.5              if len(d)==timesteps: ret_data.append(d)
   162
   163         1            1      1.0      0.0      return ret_data
4

1 に答える 1

1

より高速な方法を見つける必要がありますか?あなたの現在の方法はそれほど遅くはありません。次の変更は単純化される可能性がありますが、必ずしも高速になるとは限りません。

ステップ1:データフレームのリストからランダムサンプル(置換あり)を取得します

rand_stocks = np.random.randint(0, len(data), size=batch_size) 

この配列rand_stocksは、一連のデータフレームに適用されるインデックスのリストとして扱うことができます。サイズはすでにバッチサイズであるため、whileループと156行目の比較は不要です。

つまり、次rand_stocksのように繰り返して在庫にアクセスできます。

for idx in rand_stocks: 
  stock = data.ix[idx] 
  # Get a sample from this stock. 

ステップ2:ランダムに選択した株式ごとにランダムなデータ範囲を取得します。

start_idx = np.random.randint(offset, len(stock)-timesteps)
d = data_t[start_idx:start_idx+timesteps]

私はあなたのデータを持っていませんが、これが私がそれをまとめる方法です:

def random_sample(data=None, timesteps=100, batch_size=100, subset='train'):
    if subset=='train': offset = 0  #you can obviously change this back
    rand_stocks = np.random.randint(0, len(data), size=batch_size)
    ret_data = []
    for idx in rand_stocks:
        stock = data[idx]
        start_idx = np.random.randint(offset, len(stock)-timesteps)
        d = stock[start_idx:start_idx+timesteps]
        ret_data.append(d)
    return ret_data

データセットの作成:

In [22]: import numpy as np
In [23]: import pandas as pd

In [24]: rndrange = pd.DateRange('1/1/2012', periods=72, freq='H')
In [25]: rndseries = pd.Series(np.random.randn(len(rndrange)), index=rndrange)
In [26]: rndseries.head()
Out[26]:
2012-01-02    2.025795
2012-01-03    1.731667
2012-01-04    0.092725
2012-01-05   -0.489804
2012-01-06   -0.090041

In [27]: data = [rndseries,rndseries,rndseries,rndseries,rndseries,rndseries]

機能のテスト:

In [42]: random_sample(data, timesteps=2, batch_size = 2)
Out[42]:
[2012-01-23    1.464576
2012-01-24   -1.052048,
 2012-01-23    1.464576
2012-01-24   -1.052048]
于 2012-11-05T21:10:18.563 に答える