2017-06-14 4 views
2

私は、日付とエンジンの2列のデータフレームを以下のように持っています。私はので、ここで最後の行が答えに含まれるべきではないパンダ:日付で重複しているアイテムを探す

"Is there any repeated engineID withing the time period 2016-01-01 to 2016-06-30 ?"

engineID Date 
1133  2016-01-24 
1133  2016-02-20 
1132  2016-03-11 
1643  2016-02-07 
1165  2016-02-24 
1724  2016-01-12 
1133  2016-11-23 

を伝えるために、クエリを必要としています。

最終的な答え:

engineID Date 
1133  2016-01-24 
1133  2016-02-20 

答えて

5

pandas
keep=False
betweenduplicatedを使用して、この答えは、新しいインデックスを作成し、その過程で、単純に2つのブール配列でブールインデックスを使用して、古いものを上書きするオーバーヘッドを回避できます。最初に、Date列の日付がbetweenであるかどうかが判断されます。 2番目は、重複があるかどうかを判断します。この回答で

df[df.Date.between('2016-01-01', '2016-06-30') & df.engineID.duplicated(keep=False)] 

    engineID  Date 
0  1133 2016-01-24 
1  1133 2016-02-20 

numpy
pd.factorizenp.bincount
私はbetween機能を置き換えるために、2つのブール配列を作成します。私はpd.factorizenp.bincoutを使って重複が何であるかを判断します。

d = df.Date.values 
s, e = pd.to_datetime(['2016-01-01', '2016-06-30']).values 
f, u = pd.factorize(df.engineID.values) 
m = np.bincount(f)[f] > 1 
df[(s <= d) & (d <= e) & m] 

    engineID  Date 
0  1133 2016-01-24 
1  1133 2016-02-20 

タイミング

%timeit df[df.Date.between('2016-01-01', '2016-06-30') & df.engineID.duplicated(keep=False)] 
1000 loops, best of 3: 1.12 ms per loop 

%%timeit 
d = df.Date.values 
s, e = pd.to_datetime(['2016-01-01', '2016-06-30']).values 
f, u = pd.factorize(df.engineID.values) 
m = np.bincount(f)[f] > 1 
df[(s <= d) & (d <= e) & m] 
1000 loops, best of 3: 398 µs per loop 

%%timeit 
d1 = df.set_index('Date').loc['2016-01-01':'2016-06-30'] 
d1[d1.duplicated(['engineID'], keep=False)].reset_index() 
100 loops, best of 3: 1.99 ms per loop 
4

を指標と日付を設定し、あなたがPartial String Indexingduplicatedを使用することができます。

df = df.set_index('Date') 
df_out = df.loc['2016-01-01':'2016-06-30'] 
df_out[df_out.duplicated(['engineID'],keep=False)].reset_index() 

出力:

 Date engineID 
0 2016-01-24  1133 
1 2016-02-20  1133 
+0

'df.set_index'は、オプション'インプレース= true'をを使用するか、あなたが正しい別の変数 –

+0

に割り当てる必要があります。私は訂正のためにそれを逃した。 –

関連する問題