在第一次出现值之前删除所有行

Ste*_*ter 5 python-2.7 pandas

我有一个像这样的 df:

Year  ID Count
1997  1  0
1998  2  0
1999  3  1
2000  4  0
2001  5  1
Run Code Online (Sandbox Code Playgroud)

我想在第一次出现1in Countwhich之前删除所有行,这会给我:

Year  ID Count
1999  3  1
2000  4  0
2001  5  1
Run Code Online (Sandbox Code Playgroud)

我可以在第一次出现后删除所有行,如下所示:

df=df.loc[: df[(df['Count'] == 1)].index[0], :]
Run Code Online (Sandbox Code Playgroud)

但我似乎无法遵循切片逻辑使其相反。

Max*_*axU 5

您可以使用cumsum()方法:

In [13]: df[(df.Count == 1).cumsum() > 0]
Out[13]:
   Year  ID  Count
2  1999   3      1
3  2000   4      0
4  2001   5      1
Run Code Online (Sandbox Code Playgroud)

解释:

In [14]: (df.Count == 1).cumsum()
Out[14]:
0    0
1    0
2    1
3    1
4    2
Name: Count, dtype: int32
Run Code Online (Sandbox Code Playgroud)

针对 500K 行 DF 的计时:

In [18]: df = pd.concat([df] * 10**5, ignore_index=True)

In [19]: df.shape
Out[19]: (500000, 3)

In [20]: %timeit df[(df.Count == 1).idxmax():]
100 loops, best of 3: 3.7 ms per loop

In [21]: %timeit df[(df.Count == 1).cumsum() > 0]
100 loops, best of 3: 16.4 ms per loop

In [22]: %timeit df.loc[df[(df['Count'] == 1)].index[0]:, :]
The slowest run took 4.01 times longer than the fastest. This could mean that an intermediate result is being cached.
100 loops, best of 3: 7.02 ms per loop
Run Code Online (Sandbox Code Playgroud)

结论:@piRSquared 的idxmax()解决方案显然是赢家......


piR*_*red 5

我会做:

df[(df.Count == 1).idxmax():]
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明


df.Count == 1返回一个布尔数组。 idxmax()将标识最大值的索引。我知道最大值将是True,当有多个Trues 时,它将返回找到的第一个的位置。这正是你想要的。顺便说一下,那个值是2。最后,我2使用df[2:]. 我在上面的答案中将所有内容放在一行中。