2017-10-03 5 views
1

を対応する値をアップサンプリングし、選択するために、私は3 clumnsとデータフレームがあります。
1. ID(int64型):オブジェクトID
2. DATETIME(datetime64 [NS]):日付と時刻オブジェクトの過去4つの値が収集されました。頻度は1時間よりも短くてもよく、または1時間より長くてもよい。 2つの連続した収集が1時間15分以上離れている場合、約15mn間隔の値が失われる可能性があります。
3. VALUES(文字列オブジェクト):カンマ区切りでオブジェクトの4つの値。各値は過去15分間の間隔でのオブジェクトの値です。たとえば、10 AMの収集値が「0,1,2,3」の場合、オブジェクトの値は9:45から10 AMの間で0、9:30から9:45 AMの間は1であることを意味します。パンダ - どのように新しいセルの

15分の頻度でこのデータフレームを再サンプリングし、巨大なデータフレームでループが長すぎるため、明示的なforループ(または最小限のループ)なしで15分間隔ごとに対応する値を保持したい...

ここで私は1つのオブジェクトのために持っているもののサンプルです:

012:

ID,COLLECTION_DATETIME,VALUES 
10000,2017-09-13 10:30:00,"2,1,0,3" 
10000,2017-09-13 11:00:00,"6,5,2,1" 
10000,2017-09-13 12:15:00,"0,0,0,2" 

そして、ここでは、私が取得したい結果です

ID,COLLECTION_DATETIME,VALUE 
10000,2017-09-13 09:45:00,3 
10000,2017-09-13 10:00:00,0 
10000,2017-09-13 10:15:00,1 
10000,2017-09-13 10:30:00,2 
10000,2017-09-13 10:45:00,5 
10000,2017-09-13 11:00:00,6 
10000,2017-09-13 11:15:00,NaN 
10000,2017-09-13 11:30:00,2 
10000,2017-09-13 11:45:00,0 
10000,2017-09-13 12:00:00,0 
10000,2017-09-13 12:15:00,0 

私はこのインデックスとして「COLLECTION_DATETIME」カラムを用いて行われ、15分の頻度、分離「値」カラム([「値」] DF。str.split(「」、展開=真でリサンプリングすることができる推測))と置き換えて、結果をdf.resample( '15分')の新しい列に何らかの形で反映させ、重複する間隔を削除しますが、それでもやり遂げることはできません アイデアや指示が役に立ちます。

+0

なぜ 'Nan'の代わりに0を?すべての値のサイズは4 – erasmortg

+0

です。この間隔でのオブジェクトの値は収集されなかったため、0ではない可能性があります.Nanの代わりに他の未使用の値(たとえば999)を使用できます。 – JustForFun

+0

10000,2017-09-13 10:30:00、 "2,1,0,3"はこのオブジェクトが10:15と10:30の間の値2を持つことを意味します(DATE_TIMEのために望ましい値)2017-09-13 10 :アップサンプリングされたデータフレームの30:00は2(過去15分間の過去の値))、10:00〜10:15,1:09:45〜10:0、3:09:30〜09:45 (==>これは上記の通りです) – JustForFun

答えて

0

あなたは使用することができます。

#change order of values 
df['VALUES'] = df['VALUES'].str[::-1] 
#repeat index by len of splitted values 
a = df['VALUES'].str.split(',') 
l = a.str.len() 
#flatten column VALUES 
df = df.loc[df.index.repeat(l)].assign(VALUES=np.concatenate(a)) 
#convert index to column and create unique index 
df = df.reset_index(drop=True) 

print (df) 
    index  ID COLLECTION_DATETIME VALUES 
0  0 10000 2017-09-13 10:30:00  3 
1  0 10000 2017-09-13 10:30:00  0 
2  0 10000 2017-09-13 10:30:00  1 
3  0 10000 2017-09-13 10:30:00  2 
4  1 10000 2017-09-13 11:00:00  1 
5  1 10000 2017-09-13 11:00:00  2 
6  1 10000 2017-09-13 11:00:00  5 
7  1 10000 2017-09-13 11:00:00  6 
8  2 10000 2017-09-13 12:15:00  2 
9  2 10000 2017-09-13 12:15:00  0 
10  2 10000 2017-09-13 12:15:00  0 
11  2 10000 2017-09-13 12:15:00  0 

#subtract timedelta by count each datetime 
a = pd.to_timedelta(df[::-1].groupby('index').cumcount() * 15, unit='T') 
df['COLLECTION_DATETIME'] = df['COLLECTION_DATETIME'] - a 
df = df.set_index('COLLECTION_DATETIME').drop('index', axis=1) 
#create unique DatetimeIndex and convert frequency 
df = df.groupby(level=0).first().asfreq('15min') 
#replace NaN by forward filling 
df['ID'] = df['ID'].ffill().astype(int) 
print (df) 
         ID VALUES 
COLLECTION_DATETIME    
2017-09-13 09:45:00 10000  3 
2017-09-13 10:00:00 10000  0 
2017-09-13 10:15:00 10000  1 
2017-09-13 10:30:00 10000  2 
2017-09-13 10:45:00 10000  5 
2017-09-13 11:00:00 10000  6 
2017-09-13 11:15:00 10000 NaN 
2017-09-13 11:30:00 10000  2 
2017-09-13 11:45:00 10000  0 
2017-09-13 12:00:00 10000  0 
2017-09-13 12:15:00 10000  0 
+0

非常にありがとう@jezrael – JustForFun

+0

最後に、これはデータフレーム内の1つのID(例のように)でうまくいきますが、多くのIDを使用すると正しい結果が得られません。groupby(level = 0).first最初のIDだけを残してください。 df ['ID']。をループせずに複数のIDの結果を得ることは可能ですか?()すべてのIDのすべての結果を連結しますか? – JustForFun

+0

残念ながら、パンダはそれをサポートしていないので、(常にユニークなインデックスが必要です。 – jezrael

関連する問題