Python 在表中的特定值之前获取n行

Python 在表中的特定值之前获取n行,python,pandas,for-loop,indexing,Python,Pandas,For Loop,Indexing,比如,我有以下数据帧: import pandas as pd dict = {'val':[3.2, 2.4, -2.3, -4.9, 3.2, 2.4, -2.3, -4.9, 2.4, -2.3, -4.9], 'label': [0, 2, 1, -1, 1, 2, -1, -1,1, 1, -1]} df = pd.DataFrame(dict) df val label 0 3.2 0 1 2.4 2 2 -2.3

比如,我有以下数据帧:

import pandas as pd
dict = {'val':[3.2, 2.4, -2.3, -4.9, 3.2, 2.4, -2.3, -4.9, 2.4, -2.3, -4.9], 
        'label': [0, 2, 1, -1, 1, 2, -1, -1,1, 1, -1]} 
df = pd.DataFrame(dict) 
df
     val    label
0    3.2     0
1    2.4     2
2   -2.3     1
3   -4.9    -1
4    3.2     1
5    2.4     2
6   -2.3    -1
7   -4.9    -1
8    2.4     1
9   -2.3     1
10  -4.9    -1
我想在列标签中取-1值之前的每n行(例如2行)。在给定的df中,首先-1出现在索引3处,我们在它前面取2行并删除索引3,然后-1出现在索引6处,我们再次在和之前保留2行。期望的输出如下:

    val     label
1    2.4     2
2   -2.3     1
4    3.2     1
5    2.4     2
6   -2.3    -1
8    2.4     1
9   -2.3     1
谢谢你的建议

这里有一个解决方案:

new_df = pd.DataFrame()
markers = df[df.label.eq(-1)].index
for marker in markers: 
    new_df = new_df.append(df[marker-2:marker])

new_df.reset_index().drop_duplicates().set_index("index")
结果:

       val  label
index            
1      2.4      2
2     -2.3      1
4      3.2      1
5      2.4      2
6     -2.3     -1
8      2.4      1
9     -2.3      1
输出:

   val  label
1  2.4      2
2 -2.3      1
4  3.2      1
5  2.4      2
6 -2.3     -1
8  2.4      1
9 -2.3      1

如果前两行中的标签为-1,这也应该起作用。如果可能,最好使用包含的
索引
方法,因为它们简洁且性能良好:

idx=df[df.label==-1]。索引
过滤的_idx=(idx-1).union(idx-2)
过滤的\u idx=过滤的\u idx[过滤的\u idx>0]
df_new=df.iloc[filtered_idx]
“”“输出
val标签
1  2.4      2
2 -2.3      1
4  3.2      1
5  2.4      2
6 -2.3     -1
8  2.4      1
9 -2.3      1
"""
for循环
解决方案的速度比较:

#创建大df:
将numpy作为np导入
df=pd.DataFrame(np.random.random((20000000,2)),列=[“val”,“label”])
df.loc[df.sample(分形=0.01).索引,“标签”]=-1
def矢量化_过滤器(df):
idx=df[df.label=-1]。索引
过滤的_idx=(idx-1).union(idx-2)
df_new=df.iloc[filtered_idx]
返回新的
def环路过滤器(df):
filter=df.loc[df['label']==-1]。索引
req_idx=[]
对于过滤器中的idx:
如果idx==0:
持续
elif idx==1:
请求idx.append(idx-1)
其他:
请求idx.append(idx-2)
请求idx.append(idx-1)
req_idx=列表(集合(req_idx))
df2=df.loc[df.index.isin(请求idx)]
返回df2
开始=时间。时间()
q=矢量化滤波器(df)
t1=时间。时间()-开始
开始=时间。时间()
q2=环路滤波器(df)
t2=时间。时间()-开始
t2/t1#~20在我的机器上

您想以矢量化的方式进行,还是循环就足够了?循环应该足够了谢谢您的回答。(idx-1)联合体(idx-2)部件做什么?idx-2在标签为-1之前有两行,主要是我不明白为什么(idx-1)@Sascha idx==Int64Index([3,6,7,10],dtype='int64'),idx-1==Int64Index([2,5,6,9],dtype='int64')。它只是将行值偏移-1,组合(在集合意义上)与idx偏移-2。另外:请参阅速度比较,了解为什么循环是个坏主意。对于较小的dfs来说这是可以的,但是您会发现它对于大数据来说不够快quickly@Sascha
idx
表示
-1
的索引
idx-1
表示紧靠
-1
之前的索引,同样地
idx-2
表示
-1
之前的索引,偏移量为2
union
这里与集合中的相同,它将两者结合起来
(idx-1)。union(idx-2)
将通过偏移量
1
2
为您提供
-1
之前的索引:这里有一个指向相关文档页面@Sascha yes的链接。您可以在jupyter或ipython中检查输出以查看索引值。对于两行以上的行,可能有更简洁的方法。我还注意到我刚刚修复了一个错误,索引将换行为负数。我认为这将重复索引5,这就是为什么在末尾会出现拖放重复。看看实际结果@anon01ah是的,只是没有重新分配给新的
   val  label
1  2.4      2
2 -2.3      1
4  3.2      1
5  2.4      2
6 -2.3     -1
8  2.4      1
9 -2.3      1