3

日中の価格を 10 分ごとに記録したファイルがあります。[0:41] 1 日に 1 回。各日付は 42 回繰り返されます。以下のマルチインデックスは、繰り返される日付を常に 1 つに「折りたたむ」必要があります。

  • 62,035 行 x 3 列あります[date, time, price]

  • 10 分間の料金の差を取得する関数を作成し、差をそれぞれの固有の日付に制限したいと思います。

つまり、09:30 が各日の最初で、16:20 が最後です。16:20 から 09:30 までの価格の差を重複させることはできません。違いは、データフレーム内の一意の日付ごとに、09:40 ~ 09:30 で始まり、16:20 ~ 16:10 で終わる必要があります。

これが私の試みです。どんな提案でも大歓迎です。

def diffSeries(rounded,data):

'''This function accepts a column called rounded from 'data'
 The 2nd input 'data' is a dataframe 
'''

df=rounded.shift(1)
idf=data.set_index(['date', 'time'])  
data['diff']=['000']

  for i in range(0,length(rounded)):

    for day in idf.index.levels[0]:


      for time in idf.index.levels[1]:

        if idf.index.levels[1]!=1620:

          data['diff']=rounded[i]-df[i]

        else:
          day+=1
          time+=2

data[['date','time','price','II','diff']].to_csv('final.csv')

return data['diff']

次に、次のように呼び出します。

data=read_csv('file.csv')

rounded=roundSeries(data['price'],5) 

diffSeries(rounded,data)

トレースバックで - Assertion Error.

4

2 に答える 2

1

groupby を使用してから、適用して目的を達成できます。

diffs = data.groupby(lambda idx: idx[0]).apply(lambda row: row - row.shift(1))

完全な例として、11 月 14 日から 11 月 16 日までのテスト データ セットを作成するとします。

import pandas as pd
from numpy.random import randn
from datetime import time

# Create date range with 10 minute intervals, and filter out irrelevant times
times = pd.bdate_range(start=pd.datetime(2012,11,14,0,0,0),end=pd.datetime(2012,11,17,0,0,0), freq='10T')
filtered_times = [x for x in times if x.time() >= time(9,30) and x.time() <= time(16,20)]
prices = randn(len(filtered_times))

# Create MultiIndex and data frame matching the format of your CSV
arrays = [[x.date() for x in filtered_times]
         ,[x.time() for x in filtered_times]]
tuples = zip(*arrays)

m_index = pd.MultiIndex.from_tuples(tuples, names=['date', 'time'])
data = pd.DataFrame({'prices': prices}, index=m_index)

次のような DataFrame を取得する必要があります。

                       prices
date       time              
2012-11-14 09:30:00  0.696054
           09:40:00 -1.263852
           09:50:00  0.196662
           10:00:00 -0.942375
           10:10:00  1.915207

上記のように、最初のインデックスでグループ化し、各行の前の行を減算することで違いを取得できます。

diffs = data.groupby(lambda idx: idx[0]).apply(lambda row: row - row.shift(1))

次のようなものが得られます。

                       prices
date       time              
2012-11-14 09:30:00       NaN
           09:40:00 -1.959906
           09:50:00  1.460514
           10:00:00 -1.139036
           10:10:00  2.857582

日付でグループ分けしているため、16:20~09:30は機能が適用されません。

DataFrame の代わりに TimeSeries を使用することを検討することをお勧めします。これにより、この種のデータの柔軟性が大幅に向上します。CSV ファイルから DataFrame を既に読み込んでいると仮定すると、簡単にそれを TimeSeries に変換し、同様の関数を実行して違いを取得できます。

dt_index = pd.DatetimeIndex([datetime.combine(i[0],i[1]) for i in data.index])
# or dt_index = pd.DatetimeIndex([datetime.combine(i.date,i.time) for i in data.index]) 
# if you don't have an multi-level index on data yet
ts = pd.Series(data.prices.values, dt_index)
diffs = ts.groupby(lambda idx: idx.date()).apply(lambda row: row - row.shift(1))

ただし、リサンプリングなどの組み込みの時系列関数にアクセスできるようになりました。pandas の時系列の詳細については、こちらを参照してください。

于 2012-11-17T01:52:15.397 に答える
0

@MattiJohn の構成では、2007 年 1 月 3 日から 2012 年 8 月 30 日にかけて 42 回 (10 分間隔) 実行すると、長さ 86,772 のフィルター処理されたリストが得られます。データ クリーニングの問題を観察します。

ここで、csv からの価格データの長さは 62,034 です。したがって、次のように .csv から単純にインポートするだけでは問題があります。

filtered_times = [x for x in times if x.time() >= time(9,30) and x.time() <= time(16,20)]
DF=pd.read_csv('MR10min.csv')
prices = DF.price
 # I.E. rather than the generic: prices = randn(len(filtered_times))  above.

実際のデータが「あるべき」長さを下回っているという事実は、データ クリーニングの問題があることを意味します。多くの場合、bdate_time が生成する完全な時間がありません(市場での半日など、休日)

あなたのソリューションはエレガントです。しかし、実際のデータと事前に規定されたデータフレームとの間の不一致を克服する方法がわかりません。

2 番目の TimesSeries の提案では、最初の提案と同様の日時インデックスを作成する必要があるようです。たとえば、目的の実際のデータを取得するために次の 2 行を使用するとします。

DF=pd.read_csv('MR10min.csv')
data=pd.DF.set_index(['date','time'])


dt_index = pd.DatetimeIndex([datetime.combine(i[0],i[1]) for i in data.index])

以下を生成します。

TypeError: combine() argument 1 must be datetime.date, not str

利用可能な実際のデータによって完全に通知された bdate_time 配列を作成するにはどうすればよいですか?

(@MattiJohn) と、この議論の継続に関心のあるすべての人に感謝します。

于 2012-12-10T23:07:33.203 に答える