如何删除某个值后 Pandas 中的行?

How to delete rows in Pandas after a certain value?

我使用以下代码复制了一个 Pandas 系列:

data = np.array([1, 2, 3, 4, 5, np.nan, np.nan, np.nan, 9,10,11,12,13,14])
  
ser = pd.Series(data)
print(ser)

我只想 select NaN 值之前的列,这样我就只能得到值 1、2、3、4、5。我应该怎么做?

使用 boolean mask 分割系列。

您有两个选择,使用 notna 检查值是否不适用,并在第一个 True 之后扩展 FalseSeries.cummin.

ser[ser.notna().cummin()]

输出:

0    1.0
1    2.0
2    3.0
3    4.0
4    5.0
dtype: float64

或者,使用 isna, then extend the True values after the first True with Series.cummax 测试值是否为 NA,然后使用 ~:

反转掩码
ser[~ser.isna().cummax()]
其工作原理的可视化表示:
    data  notna  notna+cummin   isna  isna+cummax  ~(isna+cummax)
0    1.0   True          True  False        False            True
1    2.0   True          True  False        False            True
2    3.0   True          True  False        False            True
3    4.0   True          True  False        False            True
4    5.0   True          True  False        False            True
5    NaN  False         False   True         True           False
6    NaN  False         False   True         True           False
7    NaN  False         False   True         True           False
8    9.0   True         False  False         True           False
9   10.0   True         False  False         True           False
10  11.0   True         False  False         True           False
11  12.0   True         False  False         True           False
12  13.0   True         False  False         True           False
13  14.0   True         False  False         True           False

Series.isna and add Series.cummax for repeat Trues after first match and last invert mask by ~, filter in boolean indexing测试缺失值:

a = ser[~ser.isna().cummax()]
print(a)
0    1.0
1    2.0
2    3.0
3    4.0
4    5.0
dtype: float64

具有累积和的备选解决方案:

a = ser[ser.isna().cumsum().eq(0)]
print(a)
0    1.0
1    2.0
2    3.0
3    4.0
4    5.0
dtype: float64

详情:

print(ser.to_frame().assign(testna = ser.isna(), 
                            cummax = ser.isna().cumsum(),
                            invert = ser.isna().cumsum().eq(0)))
       0  testna  cummax  invert
0    1.0   False       0    True
1    2.0   False       0    True
2    3.0   False       0    True
3    4.0   False       0    True
4    5.0   False       0    True
5    NaN    True       1   False
6    NaN    True       2   False
7    NaN    True       3   False
8    9.0   False       3   False
9   10.0   False       3   False
10  11.0   False       3   False
11  12.0   False       3   False
12  13.0   False       3   False
13  14.0   False       3   False

print(ser.to_frame().assign(testna = ser.isna(), 
                            cummax = ser.isna().cummax(),
                            test0 = ~ser.isna().cummax()))

       0  testna  cummax   test0
0    1.0   False   False    True
1    2.0   False   False    True
2    3.0   False   False    True
3    4.0   False   False    True
4    5.0   False   False    True
5    NaN    True    True   False
6    NaN    True    True   False
7    NaN    True    True   False
8    9.0   False    True   False
9   10.0   False    True   False
10  11.0   False    True   False
11  12.0   False    True   False
12  13.0   False    True   False
13  14.0   False    True   False