如何根据条件过滤熊猫系列值

时间:2019-08-13 20:14:15

标签: python pandas numpy

我有一个pd.Series([-1, -1, -1, 0, 0, 0, -5, -5, 0, 0, 0, -1, -1, -1 , -1])的熊猫系列。如何将其转换为pd.Series([-1, 0, 0, 0, -5, -5, 0, 0, 0, -1])

要过滤的条件是,如果-1在一连串中大于或等于3,则保留第一个匹配项并丢弃其余的匹配项。

由于第一个-1的条纹是3,因此我们保留-1并将其余的丢弃。在第一个3值之后,条纹消失(因为该值现在为0)。同样,最后-1的条纹是4,因此我们保留-1并丢弃其余部分。

该过滤器仅适用于-1-5应该保留不变

谢谢

PS:我考虑过groupby,但是我认为它不符合我上面描述的streak方式

4 个答案:

答案 0 :(得分:2)

带有有条件的掩码:

In [43]: s = pd.Series([-1, -1, -1, 0, 0, 0, -5, -5, 0, 0, 0, -1, -1, -1 , -1])                                         

In [44]: m = (s.diff() == 0) & (s.eq(-1))                                                                               

In [45]: s[~m]                                                                                                          
Out[45]: 
0    -1
3     0
4     0
5     0
6    -5
7    -5
8     0
9     0
10    0
11   -1
dtype: int64

答案 1 :(得分:2)

使用一些SciPy工具-

http://example.com/foo?code=...&other_google_params=...&foo=bar

一个简单的人,希望它也能有更好的表现-

from scipy.ndimage.morphology import binary_opening,binary_erosion

def keep_first_neg1s(s, W=3):
    k1 = np.ones(W,dtype=bool)
    k2 = np.ones(2,dtype=bool)
    m = s==-1
    return s[~binary_erosion(binary_opening(m,k1),k2) | ~m]

在给定的示例def keep_first_neg1s_v2(s, W=3): m1 = binary_opening(a==-1, np.ones(W,dtype=bool)) return s[np.r_[True,~m1[:-1]]] 上运行-

s

答案 2 :(得分:1)

IIUC,熊猫遮罩和分组方式:

def remove_streaks(T):
  '''T is the threshold
  '''

  g = s.groupby(s.diff().ne(0).cumsum() + s.ne(-1).cumsum())
  mask = g.transform('size').lt(T).cumsum() + s.diff().ne(0).cumsum() 

  return s.groupby(mask).first()

>>> remove_streaks(4)
[-1, -1, -1, 0, 0, 0, -5, -5, 0, 0, 0, -1]

>>> remove_streaks(3)
[-1, 0, 0, 0, -5, -5, 0, 0, 0, -1]

答案 3 :(得分:0)

创建一个布尔掩码m,以标识值更改的位置。 Groupby上的m.cumsum()进行了变换,以标识具有-1 <3的组,并将其分配给掩码m1。布尔值m or m1和cumsum仅将数字为-1> = 3的组分隔为相同的数字。最后,使用duplicated进行切片。

m = s.diff().ne(0)
m1 = s.groupby(m.cumsum()).transform(lambda x: x.eq(-1).sum() < 3)
m2 = ~((m | m1).cumsum().duplicated())
s[m2]

分步
我将您的示例修改为包括案例-1有两个连续的行,我们应该保留。

s
Out[148]:
0    -1
1    -1
2    -1
3     0
4    -1
5    -1
6     0
7     0
8    -5
9    -5
10    0
11    0
12    0
13   -1
14   -1
15   -1
16   -1
dtype: int64

m = s.diff().ne(0)

Out[150]:
0      True
1     False
2     False
3      True
4      True
5     False
6      True
7     False
8      True
9     False
10     True
11    False
12    False
13     True
14    False
15    False
16    False
dtype: bool

m1 = s.groupby(m.cumsum()).transform(lambda x: x.eq(-1).sum() < 3)

Out[152]:
0     False
1     False
2     False
3      True
4      True
5      True
6      True
7      True
8      True
9      True
10     True
11     True
12     True
13    False
14    False
15    False
16    False
dtype: bool

m2 = ~((m | m1).cumsum().duplicated())

Out[159]:
0      True
1     False
2     False
3      True
4      True
5      True
6      True
7      True
8      True
9      True
10     True
11     True
12     True
13     True
14    False
15    False
16    False
dtype: bool

In [168]: s[m2]
Out[168]:
0    -1
3     0
4    -1
5    -1
6     0
7     0
8    -5
9    -5
10    0
11    0
12    0
13   -1
dtype: int64