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
Related
I have the following Dataframe, organized in panel data. It contains daily returns of many companies on different days following the IPO date. The day_diff represents the days that have passed since the IPO, and return_1 represents the daily individual returns for that specific day for that specific company, from which I have already added +1. Each company has its own company_tic and I have about 300 companies. My goal is to calculate the first component of the right-hand side of the equation below (so having results for each day_diff and company_tic, always starting at day 0, until the last day of data; e.g. = from day 0 to day 1, then from day 0 to day 2, from 0 to day 3, and so on until my last day, which is day 730). I have tried df.groupby(['company_tic', 'day_diff'])['return_1'].expanding().prod() but it doesn't work. Any alternatives?
Index day_diff company_tic return_1
0 0 xyz 1.8914
1 1 xyz 1.0542
2 2 xyz 1.0016
3 0 abc 1.4398
4 1 abc 1.1023
5 2 abc 1.0233
... ... ... ...
159236 x 3
Not sure to fully get what you want, but you might want to use cumprod instead of expanding().prod().
Here's what I tried :
df['return_1_prod'] = df.groupby('company_tic')['return_1'].cumprod()
Output :
day_diff company_tic return_1 return_1_prod
0 0 xyz 1.8914 1.891400
1 1 xyz 1.0542 1.993914
2 2 xyz 1.0016 1.997104
3 0 abc 1.4398 1.439800
4 1 abc 1.1023 1.587092
5 2 abc 1.0233 1.624071
I have following type of data
ingredients:
Milk
Apple
Rice
...
Then its purchased Date
26.10.2020
25.10.2020
etc
Each item is recorded when its purchased.
I want now to get at the right hand side to see how many times I bought apples, rice & milk.
As now I only see
Dates ---> 25.10.2020|24.10.2020
Rice 1 NULL
Milk 1 1
Apples NULL 1
My Goal is to see:
Dates ---> 25.10.2020|24.10.2020 SUM
Rice 1 NULL 1
Milk 1 1 2
Apples NULL 1 1
Thank you for your support!
The example of the data
Now I want to see at the end to total SUM, as there would be multiple days.
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
I have a table which contains a row for each day and number of hours an employee is employed.
Table 1
Employee Task Hours Date Sum (what I'm looking for)
A 123 4 1/1/2017 8
A 403 4 1/1/2017 8
B 123 3 1/1/2017 8
B 656 5 1/1/2017 8
A 303 1 1/2/2017 7
A 123 6 1/2/2017 7
What I am trying to do is take the sum of the Hours column grouped by Date. In other words, I want the sum of the Hours column where the Date = Date in the current row.
What you need is the EARLIER function.
The DAX for the calculated column is as follows:
Sum =
CALCULATE(
SUM(Table1[Hours]),
FILTER(
ALL(Table1) ,
Table1[Employee] = EARLIER(Table1[Employee]) &&
Table1[Date] = EARLIER(Table1[Date])
)
)
Result:
I don't think it's possible to make a new column, but you can achieve this using a measure.
Use the below DAX to create a measure and then use that in your visuals.
Sum = CALCULATE(Sum(Table1[Hours]), FILTER(ALL(Table1), Table1[Employee] = MAX(Table1[Employee]) && Table1[Date] = MAX(Table1[Date])))
I have a datatable called dtstore with 4 columns called section, department, palletnumber and uniquenumber. I am trying to make a new datatable called dtmulti which has an extra column called multi which shows the count for the number of duplicate rows...
dtstore
section | department | palletnumber | batchnumber
---------------------------------------------------
pipes 2012 1234 21
taps 2011 5678 345
pipes 2012 1234 21
taps 2011 5678 345
taps 2011 5678 345
plugs 2009 7643 63
dtmulti
section | department | palletnumber | batchnumber | multi
----------------------------------------------------------
pipes 2012 1234 21 2
taps 2011 5678 345 3
I have tried lots of approaches but my code always feels clumsy and bloated, is there an efficient way to do this?
Here is the code I am using:
Dim dupmulti = dataTable.AsEnumerable().GroupBy(Function(i) i).Where(Function(g) g.Count() = 2).Select(Function(g) g.Key)
For Each row In dupmulti multirow("Section") = dup("Section")
multirow("Department") = dup("Department")
multirow("PalletNumber") = dup("PalletNumber")
multirow("BatchNumber") = dup("BatchNumber")
multirow("Multi") = 2
Next
Assumptions of the code below these lines: the DataTable containing the original information is called dup. It might contain any number of duplicates and all of them can be defined by just looking at the first column.
'Creating final table from the columns in the original table
Dim multirow As DataTable = New DataTable
For Each col As DataColumn In dup.Columns
multirow.Columns.Add(col.ColumnName, col.DataType)
Next
multirow.Columns.Add("multi", GetType(Integer))
'Looping though the groupped rows (= no duplicates) on account of the first column
For Each groups In dup.AsEnumerable().GroupBy(Function(x) x(0))
multirow.Rows.Add()
'Adding all the cells in the corresponding row except the last one
For c As Integer = 0 To dup.Columns.Count - 1
multirow(multirow.Rows.Count - 1)(c) = groups(0)(c)
Next
'Adding the last cell (duplicates count)
multirow(multirow.Rows.Count - 1)(multirow.Columns.Count - 1) = groups.Count
Next