Pandas: conditional counting when multiple conditions are met
up vote
2
down vote
favorite
I have a dataframe as follows:
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
A and B are two Counters that work like this:
if((f>=50) or (f<50 & C<8)) then A increase by 1
if f<50 and C>8 then B increase by 1
the expected outcome should be like:
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
Please notice that when a A increases B keeps its value, and the other way around. They do not reset. Any idea about that?
Thank you in advance!
python pandas
add a comment |
up vote
2
down vote
favorite
I have a dataframe as follows:
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
A and B are two Counters that work like this:
if((f>=50) or (f<50 & C<8)) then A increase by 1
if f<50 and C>8 then B increase by 1
the expected outcome should be like:
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
Please notice that when a A increases B keeps its value, and the other way around. They do not reset. Any idea about that?
Thank you in advance!
python pandas
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I have a dataframe as follows:
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
A and B are two Counters that work like this:
if((f>=50) or (f<50 & C<8)) then A increase by 1
if f<50 and C>8 then B increase by 1
the expected outcome should be like:
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
Please notice that when a A increases B keeps its value, and the other way around. They do not reset. Any idea about that?
Thank you in advance!
python pandas
I have a dataframe as follows:
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
A and B are two Counters that work like this:
if((f>=50) or (f<50 & C<8)) then A increase by 1
if f<50 and C>8 then B increase by 1
the expected outcome should be like:
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
Please notice that when a A increases B keeps its value, and the other way around. They do not reset. Any idea about that?
Thank you in advance!
python pandas
python pandas
asked Nov 20 at 15:00
Luca91
1738
1738
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
up vote
5
down vote
accepted
For me working nice subtracting 1
with sub
and for removing possible -1
in first rows add 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)
3
@Lucas91 boolean series withcumsum
is the trick.
– Scott Boston
Nov 20 at 15:07
@jezrael, exccellent answer, may I know why there is a change in your output, and the expected output in question. there is no '4' in your df['B']
– pyd
Nov 20 at 16:21
add a comment |
up vote
5
down vote
Assumptions
df.C > 8
was meant to bedf.C >= 8
because that would be the compliment todf.C < 8
(df.f < 50) & (df.C < 8)
isn't necessary because of theor
statement anddf.f >= 50
on the other side of it.- Column
'A'
starting with0
seems to be a weird thing that needs special handling. It would be cleaner to assume that it begins with zero and starts incrementing at the firstTrue
In line with 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
In place
a = df.f.values >= 50
b = df.C.values < 8
c = a | b
df[['A', 'B']] = np.column_stack([c, ~c]).cumsum(0)
df
Reduced
c = (df.f.values >= 50) | (df.C.values < 8)
df.assign(A=c.cumsum(), B=(~c).cumsum())
With special handling
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
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53395791%2fpandas-conditional-counting-when-multiple-conditions-are-met%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
5
down vote
accepted
For me working nice subtracting 1
with sub
and for removing possible -1
in first rows add 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)
3
@Lucas91 boolean series withcumsum
is the trick.
– Scott Boston
Nov 20 at 15:07
@jezrael, exccellent answer, may I know why there is a change in your output, and the expected output in question. there is no '4' in your df['B']
– pyd
Nov 20 at 16:21
add a comment |
up vote
5
down vote
accepted
For me working nice subtracting 1
with sub
and for removing possible -1
in first rows add 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)
3
@Lucas91 boolean series withcumsum
is the trick.
– Scott Boston
Nov 20 at 15:07
@jezrael, exccellent answer, may I know why there is a change in your output, and the expected output in question. there is no '4' in your df['B']
– pyd
Nov 20 at 16:21
add a comment |
up vote
5
down vote
accepted
up vote
5
down vote
accepted
For me working nice subtracting 1
with sub
and for removing possible -1
in first rows add 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)
For me working nice subtracting 1
with sub
and for removing possible -1
in first rows add 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)
edited Nov 20 at 15:11
answered Nov 20 at 15:04
jezrael
316k22256333
316k22256333
3
@Lucas91 boolean series withcumsum
is the trick.
– Scott Boston
Nov 20 at 15:07
@jezrael, exccellent answer, may I know why there is a change in your output, and the expected output in question. there is no '4' in your df['B']
– pyd
Nov 20 at 16:21
add a comment |
3
@Lucas91 boolean series withcumsum
is the trick.
– Scott Boston
Nov 20 at 15:07
@jezrael, exccellent answer, may I know why there is a change in your output, and the expected output in question. there is no '4' in your df['B']
– pyd
Nov 20 at 16:21
3
3
@Lucas91 boolean series with
cumsum
is the trick.– Scott Boston
Nov 20 at 15:07
@Lucas91 boolean series with
cumsum
is the trick.– Scott Boston
Nov 20 at 15:07
@jezrael, exccellent answer, may I know why there is a change in your output, and the expected output in question. there is no '4' in your df['B']
– pyd
Nov 20 at 16:21
@jezrael, exccellent answer, may I know why there is a change in your output, and the expected output in question. there is no '4' in your df['B']
– pyd
Nov 20 at 16:21
add a comment |
up vote
5
down vote
Assumptions
df.C > 8
was meant to bedf.C >= 8
because that would be the compliment todf.C < 8
(df.f < 50) & (df.C < 8)
isn't necessary because of theor
statement anddf.f >= 50
on the other side of it.- Column
'A'
starting with0
seems to be a weird thing that needs special handling. It would be cleaner to assume that it begins with zero and starts incrementing at the firstTrue
In line with 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
In place
a = df.f.values >= 50
b = df.C.values < 8
c = a | b
df[['A', 'B']] = np.column_stack([c, ~c]).cumsum(0)
df
Reduced
c = (df.f.values >= 50) | (df.C.values < 8)
df.assign(A=c.cumsum(), B=(~c).cumsum())
With special handling
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
add a comment |
up vote
5
down vote
Assumptions
df.C > 8
was meant to bedf.C >= 8
because that would be the compliment todf.C < 8
(df.f < 50) & (df.C < 8)
isn't necessary because of theor
statement anddf.f >= 50
on the other side of it.- Column
'A'
starting with0
seems to be a weird thing that needs special handling. It would be cleaner to assume that it begins with zero and starts incrementing at the firstTrue
In line with 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
In place
a = df.f.values >= 50
b = df.C.values < 8
c = a | b
df[['A', 'B']] = np.column_stack([c, ~c]).cumsum(0)
df
Reduced
c = (df.f.values >= 50) | (df.C.values < 8)
df.assign(A=c.cumsum(), B=(~c).cumsum())
With special handling
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
add a comment |
up vote
5
down vote
up vote
5
down vote
Assumptions
df.C > 8
was meant to bedf.C >= 8
because that would be the compliment todf.C < 8
(df.f < 50) & (df.C < 8)
isn't necessary because of theor
statement anddf.f >= 50
on the other side of it.- Column
'A'
starting with0
seems to be a weird thing that needs special handling. It would be cleaner to assume that it begins with zero and starts incrementing at the firstTrue
In line with 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
In place
a = df.f.values >= 50
b = df.C.values < 8
c = a | b
df[['A', 'B']] = np.column_stack([c, ~c]).cumsum(0)
df
Reduced
c = (df.f.values >= 50) | (df.C.values < 8)
df.assign(A=c.cumsum(), B=(~c).cumsum())
With special handling
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
Assumptions
df.C > 8
was meant to bedf.C >= 8
because that would be the compliment todf.C < 8
(df.f < 50) & (df.C < 8)
isn't necessary because of theor
statement anddf.f >= 50
on the other side of it.- Column
'A'
starting with0
seems to be a weird thing that needs special handling. It would be cleaner to assume that it begins with zero and starts incrementing at the firstTrue
In line with 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
In place
a = df.f.values >= 50
b = df.C.values < 8
c = a | b
df[['A', 'B']] = np.column_stack([c, ~c]).cumsum(0)
df
Reduced
c = (df.f.values >= 50) | (df.C.values < 8)
df.assign(A=c.cumsum(), B=(~c).cumsum())
With special handling
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
edited Nov 20 at 15:56
answered Nov 20 at 15:30
piRSquared
151k22140282
151k22140282
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53395791%2fpandas-conditional-counting-when-multiple-conditions-are-met%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown