Finding the biggest and smallest values with most counts in histogram - vb.net

I built a program to create a text based histogram from an image.
Now I need to pick up the data from the text file and find the biggest value with most counts and the smallest value with most counts.
This is an example from a generated text file:
0 1
1000 80
10004 2
10005 200
10006 2
1002 73
105 10
On the left, I have listed the pixel values and on the other side the counts.
So, here I get the value 10005 as the biggest with the highest count (200) and the value 1000 as the smallest with the highest count (80).
I know how to read the text file line by line, split the values and put them in an array.
The question is, how can I get what I want by the fastest way assuming that I'm working with large images generating long lists of values (hundreds) in the histogram text files?

The definition of minimum and maximum value is somewhat controversial here, but, following the description, the underlying logic could be that a minimun can be determined when a maximum has been found.
So, we could order the list (some hundreds lines of data is not really much) by descending (higher values first), evaluate a maximum value and, after that, determine the minimum:
Dim bitmapData = File.ReadAllLines("[Data File Path]").
Select(Function(bd) bd.Split(New String() {" "c}, StringSplitOptions.RemoveEmptyEntries).
Select(Function(n) Integer.Parse(n)).ToArray()).
OrderByDescending(Function(value) value(0)).ToList()
Dim max() As Integer = bitmapData(0)
Dim min() As Integer = {bitmapData(0)(0), 0}
For i As Integer = 1 To bitmapData.Count - 1
If bitmapData(i)(1) > max(1) Then
If bitmapData(i + 1)(0) < bitmapData(i)(0) Then
max = bitmapData(i)
End If
ElseIf bitmapData(i)(0) < max(0) Then
If bitmapData(i)(1) >= min(1) Then
min = bitmapData(i)
End If
End If
Next
Using your data sample and a comparison array of values, the results are:
Min ( 1030, 251) Min ( 1000, 80)
Max (10001, 260) Max (10005, 200)
--------------------------------------------
0 1 0 1
10001 260 1000 80
1000 80 10004 2
10004 2 10005 200
10005 200 10006 2
10006 2 1002 73
1002 73 105 10
105 10
50 250
51 220
1026 201
1030 251
1031 250
10009 252
10008 250
10007 251
Assuming that the data source is represented by two different arrays (named Pixels and Counts, here) which need to be synchronized (paired indexed values), you just need to substitute the BitmapData array with the Pixelsand Counts array:
Dim Pixels As Integer() = [Integer Source]
Dim Counts As Integer() = [Integer Source]
Dim max() As Integer = {Pixels(0), Counts(0)}
Dim min() As Integer = {Pixels(0), 0}
For i As Integer = 1 To Pixels.Count - 1
If Counts(i) > max(1) Then
If Pixels(i + 1) < Pixels(i) Then
max = {Pixels(i), Counts(i)}
End If
ElseIf Pixels(i) < max(0) Then
If Counts(i) >= min(1) Then
min = {Pixels(i), Counts(i)}
End If
End If
Next

Related

How to iterate over rows and get max values of any previous rows

I have this dataframe:
pd.DataFrame({'ids':['a','b','c','d','e','f']
,'id_order':[1,2,3,4,5,6]
,'value':[1000,500,3000,2000,1000,5000]})
What I want is to iterate over the rows and get the maximum value of all previous rows.
For example, when I iterate to id_order==2 I would get 1000 (from id_order 1).
When I move forward to id_order==5 I would get 3000 (from id_order 3)
The desired outcome should be as follows:
pd.DataFrame({'ids':['a','b','c','d','e','f']
,'id_order':[1,2,3,4,5,6]
,'value':[1000,500,2000,3000,1000,5000]
,'outcome':[0,1000,1000,2000,3000,3000]})
This will be done on a big dataset so efficiency is also a factor.
I would greatly appreciate your help in this.
Thanks
You can shift the value column and take the cumulative maximum:
df["outcome"] = df.value.shift(fill_value=0).cummax()
Since shifting nullifies the first entry we fill it with 0.
>>> df
ids id_order value outcome
0 a 1 1000 0
1 b 2 500 1000
2 c 3 3000 1000
3 d 4 2000 3000
4 e 5 1000 3000
5 f 6 5000 3000

Is it possible to set a dynamic window frame bound in SQL OVER(ROW BETWEEN ...)-Clause?

Consider the following table, describing a patients medication plan. For example, the first row describes that the patient with patient_id = 1 is treated from timestamp 0 to 4. At time = 0, the patient has not yet become any medication (kum_amount_start = 0). At time = 4, the patient has received a kumulated amount of 100 units of a certain drug. It can be assumed, that the drug is given in with a constant rate. Regarding the first row, this means that the drug is given with a rate of 25 units/h.
patient_id
starttime [h]
endtime [h]
kum_amount_start
kum_amount_end
1
0
4
0
100
1
4
5
100
300
1
5
15
300
550
1
15
18
550
700
2
0
3
0
150
2
3
6
150
350
2
6
10
350
700
2
10
15
700
1100
2
15
19
1100
1500
I want to add the two columns "kum_amount_start_last_6hr" and "kum_amount_end_last_6hr" that describe the amount that has been given within the last 6 hours of the treatment (for the respective timestamps start, end).
I'm stuck with this problem for a while now.
I tried to tackle it with something like this
SUM(kum_amount) OVER (PARTITION BY patient_id ROWS BETWEEN "dynmaic window size" AND CURRENT ROW)
but I'm not sure whether this is the right approach.
I would be very happy if you could help me out here, thanks!

Get Sum of Required Values in DataTable VB.Net

I have a datatable with the following fields:
Day
Date
Room Rate
No of Person
Amount
The data is as follows:
Day Date Room No. Room Rate No. of Person Amount
1 4/9/2018 101 900.00 2 1, 800.00
2 4/10/2018 101 900.00 2 1, 800.00
3 4/10/2018 101 900.00 2 1, 800.00
1 4/9/2018 102 1000.00 3 3, 000.00
2 4/10/2018 102 1000.00 3 3, 000.00
3 4/10/2018 102 1000.00 3 3, 000.00
I would like to get the total amount by getting the sum of Amount. But, the last day for each Room should not be included. With the above example, the total amount would be 9, 600.00 since Room 101 and Room 102 of day 3 is not included.
I tried to use the datatable compute function, but this will not be effective:
Convert.ToInt32(DataSet.Tables("dt_Lodging").Compute("SUM(Amount)", "Day = 3")
Day will not be limited to 3. If we have days 1 to 5, day 5 is the one which will not be included in Total.
Try his line
Dim Amount As Decimal = T.Rows.OfType(Of DataRow).GroupBy(Function(X) CStr(X("RoomNo"))).Sum(Function(Room) Room.Take(Room.Count - 1).Sum(Function(X) pDec(X("Amount"))))
But your question is not clear abount name of RoomNo column. And the query has some presumptions according to your question.
It will not work when the room number repeats in different periods. Or when the rows are not sorted by date.
This solution is not optimized in any way. It just calculates the value.
Does room rate vary by date? Room rate*Number of nights would be better solution. You should work with nights of stay instead of days anyway.
EDIT:
Full code version
Public Sub Test()
Dim R As DataRow, i As Integer
Using T As New DataTable
T.Columns.Add("RoomNo", GetType(String))
T.Columns.Add("Amount", GetType(Decimal))
For i = 1 To 3
R = T.NewRow
R("RoomNo") = "101"
R("Amount") = 1800
T.Rows.Add(R)
R = T.NewRow
R("RoomNo") = "102"
R("Amount") = 3000
T.Rows.Add(R)
Next
Dim Amount As Decimal = T.Rows.OfType(Of DataRow).GroupBy(Function(X) CStr(X("RoomNo"))).Sum(Function(Room) Room.Take(Room.Count - 1).Sum(Function(X) CDec(X("Amount"))))
Debugger.Break()
End Using
End Sub

vb.net many choices in 1 loop

I have an array of numbers , i want to get some numbers only in loop.
I want to get from 1 to 20 and from 40 to 50
My Code:
For i As Integer = 1 To 50
Next
But this code gets all the numbers(from 1 to 50).
I wish you can help me.
Thanks
Well, either do this:
For i As Integer = 1 to 20
Next
For i As Integer = 40 to 50
Next
or this
For i As Integer = 1 to 20
If 20 < i OrElse i < 40 Then Continue
Next

Converting columns into rows in a collection using linq

I need to convert the following columns into rows using linq
Id Numb1 Numb2 Numb3
100 1 2 3
200 10 20 30
into
Id Numbers Code
100 1 A
100 2 D
100 3 R
200 10 E
200 20 T
200 30 H
This should work if you're okay hard-coding which columns will get pivoted. For each item you select its numbers and flatten the resulting list. This query gets translated to a SelectMany() statement.
From item in items _
From number in { item.Numb1, item.Numb2, item.Numb3 } _
Select New Class2 With { .Id = item.Id, .Number = number }