Cumsum in Postgres with nulling every partiton - postgresql

I have this
device_id new_trip corridor_trip_id
a_10003750032338423796 true 1
a_10003750032338423796 false 1
a_10003750032338423796 false 1
a_1001349994099853586 true 3
a_1001349994099853586 false 3
a_1001349994099853586 false 3
a_1001349994099853586 false 3
a_1001349994099853586 true 3
a_1001349994099853586 false 3
a_1001349994099853586 true 3
a_1001349994099853586 false 3
I want to find the cumulative amount of corridor_trip_id as here
device_id new_trip corridor_trip_id
a_10003750032338423796 True 1
a_10003750032338423796 False 1
a_10003750032338423796 False 1
a_1001349994099853586 True 1
a_1001349994099853586 False 1
a_1001349994099853586 False 1
a_1001349994099853586 False 1
a_1001349994099853586 True 2
a_1001349994099853586 False 2
a_1001349994099853586 True 3
a_1001349994099853586 False 3

Related

Find aggregate time that each process is unhealthy

I'm trying to find the aggregate time each distinct process_name is unhealthy with sql as it is the only language I know. FALSE indicates a process is unhealthy until it switches to TRUE. If the process ends on False, I assume it is unhealthy until the end time in query.
The desired output would be something like: (process_name=A 4seconds |process_name=B 'x seconds')
ts
process_name
value
2022-06-30 09:30:00.856839-04
A
false
2022-06-30 09:30:00.856839-04
A
false
2022-06-30 09:30:05.857945-04
A
true
2022-06-30 09:30:05.857945-04
A
true
2022-06-30 09:30:14.58143-04
B
false
2022-06-30 09:30:19.581629-04
B
true
2022-06-30 09:32:07.383898-04
C
false
2022-06-30 09:32:07.383898-04
C
false
2022-06-30 09:32:12.385355-04
C
true
2022-06-30 09:32:12.385355-04
C
true
2022-06-30 09:32:16.562974-04
D
false
2022-06-30 09:32:51.606147-04
E
false
2022-06-30 09:32:51.606147-04
E
false
2022-06-30 09:32:53.481923-04
Z
false
2022-06-30 09:32:53.481923-04
Z
false
2022-06-30 09:32:53.737522-04
X
false
2022-06-30 09:32:53.737522-04
X
false
2022-06-30 09:32:56.6067-04
E
true
2022-06-30 09:32:56.6067-04
E
true
2022-06-30 09:32:58.482162-04
Z
true
2022-06-30 09:32:58.482162-04
Z
true
2022-06-30 09:32:58.73768-04
X
true
2022-06-30 09:32:58.73768-04
X
true
2022-06-30 09:33:41.574388-04
D
true
2022-06-30 09:33:52.562954-04
F
false
2022-06-30 09:33:52.562954-04
F
false
2022-06-30 09:33:57.988884-04
G
false
2022-06-30 09:33:57.988884-04
G
false

Julia dot operator and boolean

Suppose I have p = [true, true, false, false] and q = [true, false, true, false]. How can I logically "and" them, say like
p .&& q?
Use .& instead:
julia> p=[true, true, false, false]
4-element Array{Bool,1}:
1
1
0
0
julia> q=[true, false, true, false]
4-element Array{Bool,1}:
1
0
1
0
julia> p .& q
4-element BitArray{1}:
1
0
0
0
You have to be careful though as & works also on non-Bool elements:
julia> [11,12,13] .& [3,2,1]
3-element Array{Int64,1}:
3
0
1

SUM the same field on different CASE conditions

I have a table with the following fields.
code quantity active
1 23 true
1 35 true
1 25 false
1 37 false
2 30 true
2 43 true
2 43 false
2 45 true
3 49 false
3 26 false
3 30 true
3 46 false
3 46 false
3 27 true
4 42 false
4 23 false
4 48 true
4 35 false
4 45 true
and I have the following query:
SELECT code, CASE WHEN active THEN COUNT(*) ELSE 0 END AS "activeCodes",
CASE WHEN active=false THEN COUNT(*) ELSE 0 END AS "inactiveCodes"
FROM tbl_codes
GROUP BY code, active
ORDER BY code
and the result of it is the following table:
code activeCodes inactiveCodes
1 0 2
1 2 0
2 3 0
2 0 1
3 0 4
3 2 0
4 0 3
4 2 0
but the result that I expected is
code activeCodes inactiveCodes
1 2 2
2 3 1
3 4 2
4 2 3
which condition am I missing here? how can I get the result that I expected?
You have a sparse matrix which you can collapse by running a SUM. Probably something like this (not tested):
SELECT code
,SUM(CASE WHEN active THEN 1 ELSE 0 END) AS "activeCodes"
,SUM(CASE WHEN active=false THEN 1 ELSE 0 END) AS "inactiveCodes"
FROM tbl_codes
GROUP BY code
ORDER BY code

MATLAB - Find contour of a binary bit map?

I have a 10x10 binary bit map as follows. I am looking for an efficient way of finding its contour in MATLAB. (I have tried letting every value "look around" its neighbors' values and decide, but it is too inefficient. I expect the algorithm to scale up.)
false false false false false false false false false false
false false true true true true true true false false
false true true true true true true true true false
false true true true true true true true true false
false true true true true true true true true false
false true true true true true true true true false
false true true true true true true true true false
false true true true true true true true true false
false false true true true true true true false false
false false false false false false false false false false
Let's assume each boolean value resembles a square, and the left-bottom one sits over x: 0-1; y: 0-1. The output should be the points that form the boundary. You may assume the inner true block is alway convex.
This is dead simple. Use the bwperim command in MATLAB, assuming you have the image processing toolbox.
You can call the function like so:
out = bwperim(A); %//or
out = bwperim(A,conn);
The first way assumes that the pixel connectivity is a 4-pixel neighbourhood. This will only look at the north, south, east and west directions.
If you specify an additional parameter called conn which is a single number, you can override this behaviour and specify the kind of behaviour you want when looking at neighbouring pixels. For example, if conn=8, you would look at 8-pixel neighbourhoods for 2D (so N, NE, E, SE, S, SW, W, NW), or you can go into 3D if you have a 3D binary image... but for now, I'm assuming it's just 2D. For the best accuracy, use 8.
As such, we have:
A = [false false false false false false false false false false
false false true true true true true true false false
false true true true true true true true true false
false true true true true true true true true false
false true true true true true true true true false
false true true true true true true true true false
false true true true true true true true true false
false true true true true true true true true false
false false true true true true true true false false
false false false false false false false false false false];
out = bwperim(A,8);
And it looks like:
out =
0 0 0 0 0 0 0 0 0 0
0 0 1 1 1 1 1 1 0 0
0 1 1 0 0 0 0 1 1 0
0 1 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 1 0
0 1 1 0 0 0 0 1 1 0
0 0 1 1 1 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0
MATLAB outputs 1 for true and 0 for false.
As a bonus, this is what the shapes look like side by side:
Edit from the comments
Going with your comments, you wish to find the set of points that make the perimeter. As such, you can simply use the find command to do that for you.
[X,Y] = find(out == 1);
coords = [X Y];
What the find command does is that it searches your array and finds locations in the array that match the Boolean expression given in the parameter of find. In this case, we wish to find all co-ordinates that have a pixel in out equal to 1, and out is our perimeter image. As such, this effectively finds all pixels that are perimeter pixels.
We thus get:
coords =
3 2
4 2
5 2
6 2
7 2
8 2
2 3
3 3
8 3
9 3
2 4
9 4
2 5
9 5
2 6
9 6
2 7
9 7
2 8
3 8
8 8
9 8
3 9
4 9
5 9
6 9
7 9
8 9
X are the row co-ordinates, while Y are the column co-ordinates. I've placed X and Y into a single 2D array for better presentation, but you can take the X and Y variables by themselves for further processing.
Hope this helps!
Here's another option:
B = bwboundaries(A)
this will get the x-y coordinates of any boundary. see more info here...
Another option with image processing toolbox:
B = A - imerode(A,SE);
where SE is one of the kernels:
0 1 0 1 1 1
1 1 1 1 1 1
0 1 0 1 1 1
depending on which connectivity you want to use: first one for 8-connectivity, second one for 4-connectivity. For the difference between the two, recall that 8-connectivity allows diagonal neighbours.
With the image B, you can find all the points of the perimeters with the same technique displayed in another answer:
[Xp,Yp] = find(B);

How to apply logical indexing on multi-dimension matrix in matlab

My question is simple. I have an rgb image and a logical matrix. I want to set the pixel which is true in the corresponding element of logical matrix to (150,160,170).
For example:
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0
r= 1 1 1 1 1 g= 1 1 1 1 1 b=1 1 1 1 1 logical_mat =1 0 0 0 0
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0
I want it results in
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
r= 150 1 1 1 1 g= 160 1 1 1 1 b=170 1 1 1 1
150 150 1 1 1 160 160 1 1 1 170 170 1 1 1
150 150 150 1 1 160 160 160 1 1 170 170 170 1 1
I have tried logical index, if set pixel into same color is easy
lm = repmat(logical_mat,[1 1 3]);
rgb(lm) = 150;
But I dont know how to set the value channel by channel.
Thanks in advance.
You're already creating the right logical matrix:
lm = repmat(logical_mat,[1 1 3]);
You need to create a 3-channel color matrix the same size.
cm = repmat(cat(3,150,160,170), size(lm,1), size(lm,2))
Then, index into the color matrix with lm:
rgb(lm) = cm(lm);