熊猫:满足多个条件时的条件计数

Luc*_*a91 2 python pandas

我有一个数据帧如下:

                      dtm        f           C      A   B
0   2018-03-01 00:00:00 +0000   50.135  9.000000    0   0
1   2018-03-01 00:00:01 +0000   50.130  9.000000    0   0
2   2018-03-01 00:00:02 +0000   50.120  9.000000    0   0
3   2018-03-01 00:00:03 +0000   50.112  9.000000    0   0
4   2018-03-01 00:00:04 +0000   50.102  9.000000    0   0
5   2018-03-01 00:00:05 +0000   50.097  9.000000    0   0
6   2018-03-01 00:00:06 +0000   11.095  9.000000    0   0
7   2018-03-01 00:00:07 +0000   11.095  9.000000    0   0
8   2018-03-01 00:00:08 +0000   11.092  9.000000    0   0
9   2018-03-01 00:00:09 +0000   11.095  9.000000    0   0
10  2018-03-01 00:00:10 +0000   11.097  5.000000    0   0
11  2018-03-01 00:00:11 +0000   11.097  5.000000    0   0
12  2018-03-01 00:00:12 +0000   11.097  5.000000    0   0
13  2018-03-01 00:00:13 +0000   50.100  5.000000    0   0
14  2018-03-01 00:00:14 +0000   50.102  5.000000    0   0
15  2018-03-01 00:00:15 +0000   50.105  5.000000    0   0
16  2018-03-01 00:00:16 +0000   50.102  5.000000    0   0
17  2018-03-01 00:00:17 +0000   50.102  5.000000    0   0
Run Code Online (Sandbox Code Playgroud)

A和B是两个像这样工作的计数器:

  • if((f> = 50)或(f <50&C <8))则A增加1

  • 如果f <50且C> 8则B增加1

预期的结果应该是:

                      dtm           f         C     A   B
0   2018-03-01 00:00:00 +0000   50.135  9.000000    0   0
1   2018-03-01 00:00:01 +0000   50.130  9.000000    1   0
2   2018-03-01 00:00:02 +0000   50.120  9.000000    2   0
3   2018-03-01 00:00:03 +0000   50.112  9.000000    3   0
4   2018-03-01 00:00:04 +0000   50.102  9.000000    4   0
5   2018-03-01 00:00:05 +0000   50.097  9.000000    5   0
6   2018-03-01 00:00:06 +0000   11.095  9.000000    5   1
7   2018-03-01 00:00:07 +0000   11.095  9.000000    5   2   
8   2018-03-01 00:00:08 +0000   11.092  9.000000    5   3
9   2018-03-01 00:00:09 +0000   11.095  9.000000    5   4
10  2018-03-01 00:00:10 +0000   11.097  5.000000    6   4
11  2018-03-01 00:00:11 +0000   11.097  5.000000    7   4
12  2018-03-01 00:00:12 +0000   11.097  5.000000    8   4
13  2018-03-01 00:00:13 +0000   50.100  5.000000    9   4
14  2018-03-01 00:00:14 +0000   50.102  5.000000    10  4
15  2018-03-01 00:00:15 +0000   50.105  5.000000    11  4
16  2018-03-01 00:00:16 +0000   50.102  5.000000    12  4
17  2018-03-01 00:00:17 +0000   50.102  5.000000    13  4
Run Code Online (Sandbox Code Playgroud)

请注意,当A增加B保持其值时,反之亦然.他们不会重置.有什么想法吗?

先感谢您!

jez*_*ael 5

对我来说,工作不错减法1与sub和去除可能-1在第一行添加clip_lower:

m1 = (df.f >=50) | ((df.f<50) & (df.C<8))
m2 = (df.f<50) & (df.C>8)

df['A'] = m1.cumsum().sub(1).clip_lower(0)
df['B'] = m2.cumsum().sub(1).clip_lower(0)
Run Code Online (Sandbox Code Playgroud)

  • 带有`cumsum`的@ Lucas91布尔系列就是诀窍. (3认同)

piR*_*red 5

假设

  • df.C > 8本来应该是df.C >= 8因为那将是对它的赞美df.C < 8
  • (df.f < 50) & (df.C < 8)因为or声明而df.f >= 50在声明的另一边是没有必要的.
  • 'A'从一开始的列0似乎是一个需要特殊处理的奇怪的事情.假设它从零开始并在第一个开始递增会更清楚True

符合 assign

a = df.f.values >= 50
b = df.C.values < 8
c = a | b

df.assign(A=c.cumsum(), B=(~c).cumsum())

                          dtm       f    C   A  B
0   2018-03-01 00:00:00 +0000  50.135  9.0   1  0
1   2018-03-01 00:00:01 +0000  50.130  9.0   2  0
2   2018-03-01 00:00:02 +0000  50.120  9.0   3  0
3   2018-03-01 00:00:03 +0000  50.112  9.0   4  0
4   2018-03-01 00:00:04 +0000  50.102  9.0   5  0
5   2018-03-01 00:00:05 +0000  50.097  9.0   6  0
6   2018-03-01 00:00:06 +0000  11.095  9.0   6  1
7   2018-03-01 00:00:07 +0000  11.095  9.0   6  2
8   2018-03-01 00:00:08 +0000  11.092  9.0   6  3
9   2018-03-01 00:00:09 +0000  11.095  9.0   6  4
10  2018-03-01 00:00:10 +0000  11.097  5.0   7  4
11  2018-03-01 00:00:11 +0000  11.097  5.0   8  4
12  2018-03-01 00:00:12 +0000  11.097  5.0   9  4
13  2018-03-01 00:00:13 +0000  50.100  5.0  10  4
14  2018-03-01 00:00:14 +0000  50.102  5.0  11  4
15  2018-03-01 00:00:15 +0000  50.105  5.0  12  4
16  2018-03-01 00:00:16 +0000  50.102  5.0  13  4
17  2018-03-01 00:00:17 +0000  50.102  5.0  14  4
Run Code Online (Sandbox Code Playgroud)

到位

a = df.f.values >= 50
b = df.C.values < 8
c = a | b

df[['A', 'B']] = np.column_stack([c, ~c]).cumsum(0)
df
Run Code Online (Sandbox Code Playgroud)

减少

c = (df.f.values >= 50) | (df.C.values < 8)

df.assign(A=c.cumsum(), B=(~c).cumsum())
Run Code Online (Sandbox Code Playgroud)

有特殊处理

a = df.f.values >= 50
b = df.C.values < 8
c0 = a | b
c1 = ~c0

c0[0] = False
c1[0] = False

df.assign(A=c0.cumsum(), B=c1.cumsum())

                          dtm       f    C   A  B
0   2018-03-01 00:00:00 +0000  50.135  9.0   0  0
1   2018-03-01 00:00:01 +0000  50.130  9.0   1  0
2   2018-03-01 00:00:02 +0000  50.120  9.0   2  0
3   2018-03-01 00:00:03 +0000  50.112  9.0   3  0
4   2018-03-01 00:00:04 +0000  50.102  9.0   4  0
5   2018-03-01 00:00:05 +0000  50.097  9.0   5  0
6   2018-03-01 00:00:06 +0000  11.095  9.0   5  1
7   2018-03-01 00:00:07 +0000  11.095  9.0   5  2
8   2018-03-01 00:00:08 +0000  11.092  9.0   5  3
9   2018-03-01 00:00:09 +0000  11.095  9.0   5  4
10  2018-03-01 00:00:10 +0000  11.097  5.0   6  4
11  2018-03-01 00:00:11 +0000  11.097  5.0   7  4
12  2018-03-01 00:00:12 +0000  11.097  5.0   8  4
13  2018-03-01 00:00:13 +0000  50.100  5.0   9  4
14  2018-03-01 00:00:14 +0000  50.102  5.0  10  4
15  2018-03-01 00:00:15 +0000  50.105  5.0  11  4
16  2018-03-01 00:00:16 +0000  50.102  5.0  12  4
17  2018-03-01 00:00:17 +0000  50.102  5.0  13  4
Run Code Online (Sandbox Code Playgroud)