2017-10-22 1 views
1

私は、ほぼ200万のエントリを持つDataFrameを持っています。このDataFrameのサブセットを作成したいと思います。大規模なデータセットから毎日1時間ごとに500件のエントリを抽出するにはどうすればよいですか?

特に、私が望むのは、データセット内の毎日の1時間ごとに500のエントリを取ることです。結果は新しいDataFrame resに保存する必要があります。 datetime_eventという列があり、datesは次のように作成されます。dates = pd.to_datetime(df['datetime_event'])

これは私のコードですが、終了するまでに数時間かかります。例えば、applylambdaを使用して、それを少し最適化することは可能ですか?

counter = 0 
current_hour = 0 
res = pd.DataFrame(columns=df.columns) 
for i in range(0,len(df.index)): 
    hour = dates.dt.hour[i] 
    if current_hour != hour: 
     current_hour = hour 
     counter = 0 
    if counter <= 500: 
     res.loc[i] = df.loc[i] 
     counter += 1 

UPDATE:

サンプルデータフレームdf

id datetime_event  title 
11 2017-05-01T00:00:08 AAA 
12 2017-05-01T00:00:08 BBB 
13 2017-05-01T00:00:08 CCC 
14 2017-05-01T00:00:09 BBB 
15 2017-05-01T00:00:09 DDD 
16 2017-05-01T01:01:00 EEE 
17 2017-05-01T01:01:01 EEE 
18 2017-05-01T01:01:09 DDD 
19 2017-05-01T01:01:09 EEE 
20 2017-05-01T01:01:11 EEE 

Iは、例えば、各時間の最初のN個のエントリ(最初の3つのエントリを含むであろうサブセットresを取得したいと思い下記の例のように):

id datetime_event  title 
11 2017-05-01T00:00:08 AAA 
12 2017-05-01T00:00:08 BBB 
13 2017-05-01T00:00:08 CCC 
16 2017-05-01T01:01:00 EEE 
17 2017-05-01T01:01:01 EEE 
18 2017-05-01T01:01:09 DDD 
+0

あなたが追加することができますいくつかのサンプルデータおよび所望の出力。検証可能なサンプルではなく、3つのエントリに対して500? – jezrael

+0

@ jezrael:私の更新を確認してください。この問題は、 'for'ループを使用しているときに長い計算時間で構成されています。この時間を短縮できる解決策を見つけたいと思います。 – Dinosaurius

答えて

2

用途:

df = df[df.groupby(pd.to_datetime(df['datetime_event']).dt.floor('H')).cumcount() < 3] 

print (df) 
    id  datetime_event title 
0 11 2017-05-01T00:00:08 AAA 
1 12 2017-05-01T00:00:08 BBB 
2 13 2017-05-01T00:00:08 CCC 
5 16 2017-05-01T01:01:00 EEE 
6 17 2017-05-01T01:01:01 EEE 
7 18 2017-05-01T01:01:09 DDD 

タイミング

df = pd.DataFrame({'datetime_event':pd.date_range('2000-01-01', freq='2T', periods=10**5)}) 

df['val'] = np.arange(len(df)) 


In [29]: %timeit df.groupby(pd.to_datetime(df['datetime_event']).dt.floor('H')).head(3) 
100 loops, best of 3: 15.8 ms per loop 

In [30]: %timeit df[df.groupby(pd.to_datetime(df['datetime_event']).dt.floor('H')).cumcount() < 3] 
100 loops, best of 3: 15.8 ms per loop 

df = pd.DataFrame({'datetime_event':pd.date_range('2000-01-01', freq='2S', periods=10**5)}) 

df['val'] = np.arange(len(df)) 

In [33]: %timeit df.groupby(pd.to_datetime(df['datetime_event']).dt.floor('H')).head(3) 
100 loops, best of 3: 14.1 ms per loop 

In [34]: %timeit df[df.groupby(pd.to_datetime(df['datetime_event']).dt.floor('H')).cumcount() < 3] 
100 loops, best of 3: 14.5 ms per loop 
+0

良いアイデア、私はそれを試してみてください。 – jezrael

+0

両方の解決策はいいですが、この場合は私は新しい列 'val'を作成する必要がないので、この方が好きです。 – Dinosaurius

+0

@Dinosaurius、私の答えの更新のセクションをチェックしてください - 私はそこに新しい列を追加しませんでした... ;-) – MaxU

3

UPDATE:

In [22]: df.groupby(pd.to_datetime(df['datetime_event']).dt.floor('H')).head(3) 
Out[22]: 
    id  datetime_event title 
0 11 2017-05-01T00:00:08 AAA 
1 12 2017-05-01T00:00:08 BBB 
2 13 2017-05-01T00:00:08 CCC 
5 16 2017-05-01T01:01:00 EEE 
6 17 2017-05-01T01:01:01 EEE 
7 18 2017-05-01T01:01:09 DDD 
+0

それは実際に素晴らしいです!それは即座に動作します! – Dinosaurius

+0

アップデートがよかったです。残念ながら、私は2つの答えを受け入れることはできません:)))ありがとうございました。 – Dinosaurius

+0

@Dinosaurius、確かに、いいえprob: – MaxU

関連する問題