熊猫:按日期查找重复项目

时间:2017-06-14 03:29:22

标签: python pandas numpy

我的数据框有两列日期和引擎,如下所示。我需要一个查询来告诉

"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

2 个答案:

答案 0 :(得分:5)

<强> pandas
betweenduplicatedkeep=False 一起使用 这个答案避免了创建新索引的开销,并在此过程中通过简单地使用带有两个布尔数组的布尔索引来覆盖旧索引。第一个确定Date列中的日期是between必需日期。第二个确定是否有重复。

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功能。我使用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

答案 1 :(得分: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