我的数据框有两列日期和引擎,如下所示。我需要一个查询来告诉
"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
答案 0 :(得分:5)
<强> pandas
强>
将between
和duplicated
与keep=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.factorize
和np.bincount
在这个答案中,我创建了两个布尔数组来替换between
功能。我使用pd.factorize
和np.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 Indexing和duplicated
:
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