pandas DataFrameのドキュメントを参考にしています: http://pandas.pydata.org/pandas-docs/stable/dsintro.html
時系列のような計算でDataFrameに値を繰り返し入力したいと考えています。 基本的には、A列、B列、タイムスタンプの行でDataFrameを初期化し、すべて0またはすべてNaNとします。
その後、初期値を追加して、このデータを調べて、前の行から新しい行を計算します。
現在、以下のようなコードを使用していますが、なんだか醜い気がして、DataFrameで直接これを行う方法や、もっと良い方法があるはずです。 注:Python2.7を使用しています。
import datetime as dt
import pandas as pd
import scipy as s
if __name__ == '__main__':
base = dt.datetime.today().date()
dates = [ base - dt.timedelta(days=x) for x in range(0,10) ]
dates.sort()
valdict = {}
symbols = ['A','B', 'C']
for symb in symbols:
valdict[symb] = pd.Series( s.zeros( len(dates)), dates )
for thedate in dates:
if thedate > dates[0]:
for symb in valdict:
valdict[symb][thedate] = 1+valdict[symb][thedate - dt.timedelta(days=1)]
print valdict
ここにいくつかの提案があります。
インデックスにdate_range
を使う。
import datetime
import pandas as pd
import numpy as np
todays_date = datetime.datetime.now().date()
index = pd.date_range(todays_date-datetime.timedelta(10), periods=10, freq='D')
columns = ['A','B', 'C']
注:空のDataFrame(NaN
s付き)を作成するには、次のように記述します:。
df_ = pd.DataFrame(index=index, columns=columns)
df_ = df_.fillna(0) # with 0s rather than NaNs
このような計算をデータに対して行うには、numpyの配列を使います。
data = np.array([np.arange(10)]*3).T
そこで、DataFrameを作成します。
In [10]: df = pd.DataFrame(data, index=index, columns=columns)
In [11]: df
Out[11]:
A B C
2012-11-29 0 0 0
2012-11-30 1 1 1
2012-12-01 2 2 2
2012-12-02 3 3 3
2012-12-03 4 4 4
2012-12-04 5 5 5
2012-12-05 6 6 6
2012-12-06 7 7 7
2012-12-07 8 8 8
2012-12-08 9 9 9
***単純に空のデータフレームを作成して、後で入力されたデータフレームで埋めたい場合は、次のようにします。
この例では、this pandas docを使って新しいデータフレームを作成し、appendを使ってoldDFのデータをnewDFに書き込んでいます。
これを見てください。
newDF = pd.DataFrame() #creates a new dataframe that's empty
newDF = newDF.append(oldDF, ignore_index = True) # ignoring index is optional
# try printing some data from newDF
print newDF.head() #again optional
***コラム名を最初から決めておきたい場合は、次のようにします。
import pandas as pd
col_names = ['A', 'B', 'C']
my_df = pd.DataFrame(columns = col_names)
my_df
***データフレームにレコードを追加したい場合は、次のようにするとよいでしょう。
my_df.loc[len(my_df)] = [2, 4, 5]
また、辞書を渡したい場合もあります。
my_dic = {'A':2, 'B':4, 'C':5}
my_df.loc[len(my_df)] = my_dic
ただし、my_dfに別のデータフレームを追加したい場合は次のようにします:。
col_names = ['A', 'B', 'C']
my_df2 = pd.DataFrame(columns = col_names)
my_df = my_df.append(my_df2)
ループ内で行を追加している場合は、パフォーマンスの問題を考慮してください:
最初の1000レコード程度の "my_df.loc"ではパフォーマンスが向上しますが、ループ内のレコード数を増やすと徐々に遅くなります。
大きなループの中で処理を行う場合(10Mレコード程度):
この2つを組み合わせて使うのが良いでしょう。
データフレームにilocでサイズが1000程度になるまで埋め、それを元のデータフレームに追加し、一時的なデータフレームを空にします。
そうすれば、パフォーマンスは10倍くらいになります。