如何过滤列中包含特定字符串的两行之间的数据框列?

How to filter dataframe columns between two rows that contain specific string in column?

我正在尝试了解如何 select 仅 select 数据框中两个特定行之间的那些行。这些行在其中一列中包含两个特定的字符串。我将用这个例子进一步解释。

我有以下数据框:

       String      Value
-------------------------
 0       Blue         45     
 1        Red         35   
 2      Green         75    
 3      Start         65   
 4     Orange         33   
 5     Purple         65   
 6       Teal         34
 7     Indigo         44
 8        End         32
 9     Yellow         22 
10        Red         14

“字符串”列中只有一个“开始”实例和一个“结束”实例。我只想要这个数据框的行在“字符串”列中包含“开始”和“停止”的行之间,所以我想生成这个输出数据框:

       String      Value
-------------------------  
 3      Start         65   
 4     Orange         33   
 5     Purple         65   
 6       Teal         34
 7     Indigo         44
 8        End         32

此外,我想保留我正在保留的那些行的顺序,因此保留“开始”、“橙色”、“紫色”、“蓝绿色”、“靛蓝”、“结束”的顺序。

我知道我可以通过以下方式索引这些特定的列:

index_start = df.index[df['String'] == 'Start']
index_end = df.index[df['String'] == 'End']    

但我不确定如何实际过滤掉不在这两个字符串之间的所有行。我如何在 python 中完成此操作?

您可以使用 eq + cummax 和过滤器构建布尔掩码:

out = df[df['String'].eq('Start').cummax() & df.loc[::-1, 'String'].eq('End').cummax()]

输出:

   String  Value
3   Start     65
4  Orange     33
5  Purple     65
6    Teal     34
7  Indigo     44
8     End     32

作为您 return 通过您的工作获得的索引值:

df.iloc[index_start.item(): index_end.item()]

这应该足够了,当您尝试按索引定位行时,iloc[] 很有用,它的工作方式与列表中的切片相同。

index_start = df.index[df['String'] == 'Start']
index_end = df.index[df['String'] == 'End']  
df.iloc[index_start[0]:index_end[0]+1]

更多信息:https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.iloc.html

如果两个值都存在,您暂时将“String”设置为索引:

df.set_index('String').loc['Start':'End'].reset_index()

输出:

   String  Value
0   Start     65
1  Orange     33
2  Purple     65
3    Teal     34
4  Indigo     44
5     End     32

或者,使用 isin(那么 Start/End 的顺序无关紧要):

m = df['String'].isin(['Start', 'End']).cumsum().eq(1)
df[m|m.shift()]

输出:

   String  Value
3   Start     65
4  Orange     33
5  Purple     65
6    Teal     34
7  Indigo     44
8     End     32