Lodash: how to find max and min values of each id - lodash

My data array is
array = [{id: 2, name: "kent", status_id: 2, date_1: "2018-08-09", date_2: "2018-07-06"},{id: 2, name: "kent", status_id: 10, date_1: "2018-01-09", date_2: "2018-09-06"},{id: 3, name: "tracy", status_id: 2, date_1: "2018-05-03", date_2: "2018-10-02"},{id: 3, name: "tracy", status_id: 2, date_1: "2018-01-10", date_2: "2018-09-12"},{id: 3, name: "tracy", status_id: 10, date_1: "2018-02-10", date_2: "2018-09-02"},{id: 4, name: "lucy", status_id: 10, date_1: "2018-12-10", date_2: "2018-08-09"},{id: 5, name: "steve", status_id: 10, date_1: "2018-12-7", date_2: "2018-04-01"}]
If the id =2 I would like to find max(date_1) & min(date_2) for each id=2. Like my output should be,
id
2 max(date_1) min(date_2)
3 max(date_1) min(date_2)
4 max(date_1) min(date_2)
5 max(date_1) min(date_2)
I am using Lodash library. I would appreciate the help.

You can first groupBy id and then map each grouped values using mapValues since that will be a object. while mapping the grouped values you can use _.maxBy and _minBy to find max and min
var array = [{"id":2,"name":"kent","status_id":2,"date_1":"2018-08-09","date_2":"2018-07-06"},{"id":2,"name":"kent","status_id":10,"date_1":"2018-01-09","date_2":"2018-09-06"},{"id":3,"name":"tracy","status_id":2,"date_1":"2018-05-03","date_2":"2018-10-02"},{"id":3,"name":"tracy","status_id":2,"date_1":"2018-01-10","date_2":"2018-09-12"},{"id":3,"name":"tracy","status_id":10,"date_1":"2018-02-10","date_2":"2018-09-02"},{"id":4,"name":"lucy","status_id":10,"date_1":"2018-12-10","date_2":"2018-08-09"},{"id":5,"name":"steve","status_id":10,"date_1":"2018-12-7","date_2":"2018-04-01"}]
var res =
_(array)
.groupBy('id')
.mapValues(a => ({
max: _.maxBy(a, 'date_1').date_1,
min: _.minBy(a, 'date_2').date_2
})).value();
console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

Related

Can the right column be fixed in the bootstrap-vue table?

I want right fixed columns in the bootstrap-vue table
but, the Sticky function in the document is only fixed to the left.
Is there a way to fix the right side or last columns?
I want both the left and right columns being fixed in place.
documnet : https://bootstrap-vue.org/docs/components/table#sticky-columns
<template>
<div>
<div class="mb-2">
<b-form-checkbox v-model="stickyHeader" inline>Sticky header</b-form-checkbox>
<b-form-checkbox v-model="noCollapse" inline>No border collapse</b-form-checkbox>
</div>
<b-table
:sticky-header="stickyHeader"
:no-border-collapse="noCollapse"
responsive
:items="items"
:fields="fields"
>
<!-- We are using utility class `text-nowrap` to help illustrate horizontal scrolling -->
<template #head(id)="scope">
<div class="text-nowrap">Row ID</div>
</template>
<template #head()="scope">
<div class="text-nowrap">
Heading {{ scope.label }}
</div>
</template>
</b-table>
</div>
</template>
<script>
export default {
data() {
return {
stickyHeader: true,
noCollapse: false,
fields: [
{ key: 'id', stickyColumn: true, isRowHeader: true, variant: 'primary' },
'a',
'b',
{ key: 'c', stickyColumn: true, variant: 'info' },
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l'
],
items: [
{ id: 1, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
{ id: 2, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
{ id: 3, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
{ id: 4, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
{ id: 5, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
{ id: 6, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
{ id: 7, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
{ id: 8, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
{ id: 9, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
{ id: 10, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 }
]
}
}
}
</script>
It's possible by overriding bootstrap's CSS with some of our own. First make sure the last column has the stickyColumn: true option plus whatever other options you want to give it:
...
'i',
'j',
'k',
{ key: "l", stickyColumn: true, isRowHeader: true, variant: "primary" },
This will ensure it has a classname we can easily select on. Apply styling that gives the last sticky column in the table an attribute of right: 0:
<style>
.b-table-sticky-column:last-child {
right: 0;
}
</style>
codesandbox example

RowNumber Window Query for Hiscores Ranking - Django

I'm trying to build a game hiscore view with rankings for my Django site, and I'm having some issues.
The query I have is the following:
row_number_rank = Window(
expression=RowNumber(),
partition_by=[F('score_type')],
order_by=F('score').desc()
)
hiscores = Hiscore.objects.annotate(rank=row_number_rank).values()
The query above works perfectly, and properly assigns each row a rank according to how it compares to other scores within each score type.
The result of this is the following:
{ 'id': 2, 'username': 'Bob', 'score_type': 'wins', 'score': 12, 'rank': 1 }
{ 'id': 1, 'username': 'John', 'score_type': 'wins', 'score': 5, 'rank': 2 }
{ 'id': 4, 'username': 'John', 'score_type': 'kills', 'score': 37, 'rank': 1 }
{ 'id': 3, 'username': 'John', 'score_type': 'kills', 'score': 5, 'rank': 2 }
{ 'id': 5, 'username': 'Bob', 'score_type': 'kills', 'score': 2, 'rank': 3 }
The issue comes in when I want to retrieve only a specific user's scores from the above results. If I append a filter(username="Bob") the query is now:
row_number_rank = Window(
expression=RowNumber(),
partition_by=[F('score_type')],
order_by=F('score').desc()
)
hiscores = Hiscore.objects.annotate(rank=row_number_rank).filter(username='Bob').values()
Unexpectedly, adding this filter step has yielded the following incorrect results:
{ 'id': 2, 'username': 'Bob', 'score_type': 'wins', 'score': 12, 'rank': 1 }
{ 'id': 5, 'username': 'Bob', 'score_type': 'kills', 'score': 2, 'rank': 1 }
Randomly, the rank on the id=5 entry has decided to change to 1 instead of its correct value of 3.
Why would adding this filter step modify the values of the fields in the QuerySet, instead of just excluding the proper elements from it?
Thanks.

How input data in line chart in Pentaho?

I want to make this chart in Pentaho CDE:
based in this chart (I think that is the most similar from among CCC Components):
(The code is in this link.)
but I don't know how I can adapt my data input to that graph.
For example, I want to consume the data with this format:
[Year, customers_A, customers_B, cars_A, cars_B] [2014, 8, 4, 23, 20]
[2015, 20, 6, 30, 38]
How I can input my data in this chart?
Your data should come as an object such as this:
data = {
metadata: [
{ colName: "Year", colType:"Numeric", colIndex: 1},
{ colName: "customers_A", colType:"Numeric", colIndex: 2},
{ colName: "customers_B", colType:"Numeric", colIndex: 3},
{ colName: "cars_A", colType:"Numeric", colIndex: 4},
{ colName: "cars_B", colType:"Numeric", colIndex: 5}
],
resultset: [
[2014, 8, 4, 23, 20],
[2015, 20, 6, 30, 38]
],
queryInfo: {totalRows: 2}
}

pandas: aggregate array during groupby, equivalent of SQL's array_agg?

I've got this dataframe:
df1 = pd.DataFrame([
{ 'id': 1, 'spend': 60, 'store': 'Stockport' },
{ 'id': 2, 'spend': 68, 'store': 'Didsbury' },
{ 'id': 3, 'spend': 70, 'store': 'Stockport' },
{ 'id': 4, 'spend': 35, 'store': 'Didsbury' },
{ 'id': 5, 'spend': 16, 'store': 'Didsbury' },
{ 'id': 6, 'spend': 12, 'store': 'Didsbury' },
])
I've grouped it by store and got the total spend by store:
df.groupby("store").agg({'spend': 'sum'})\
.reset_index().sort_values("spend", ascending=False)
store spend
Didsbury 131
Stockport 130
Is there a way I can get the IDs for each store as a column in the grouped object? Like the equivalent of ARRAY_AGG in Postgres? So the desired output would be:
store spend ids
Didsbury 131 [2,4,5,6]
Stockport 130 [1,3]
We can use named_aggregations, which is an aggregation method available since pandas >= 0.25.0.
Notice how we can instantely rename our column to "ids":
df1.groupby('store').agg(
spend=('spend', 'sum'),
ids=('id', list)
).reset_index()
store spend ids
0 Didsbury 131 [2, 4, 5, 6]
1 Stockport 130 [1, 3]
You can pass list like aggregation function for id column:
df = (df1.groupby("store").agg({'spend': 'sum', 'id':list})
.reset_index()
.sort_values("spend", ascending=False))
print (df)
store spend id
0 Didsbury 131 [2, 4, 5, 6]
1 Stockport 130 [1, 3]

rethinkdb: secondary compound indexes / aggregation queries and intermediate documents generation

Let's assume such table content where for the same product_id, we have as many rows than updates during status==1 (published) and finally status==0 (unpublished) and then becomes==2 (deleted)
{id: <auto>, product_id: 1, last_updated: 2015-12-1, status: 1, price: 1}
{id: <auto>, product_id: 2, last_updated: 2015-12-1, status: 1, price: 10}
{id: <auto>, product_id: 1, last_updated: 2015-12-2, status: 1, price: 2}
{id: <auto>, product_id: 1, last_updated: 2015-12-3, status: 0, price: 2}
{id: <auto>, product_id: 2, last_updated: 2015-12-2, status: 0, price: 10}
{id: <auto>, product_id: 3, last_updated: 2015-12-2, status: 1, price: 123}
{id: <auto>, product_id: 1, last_updated: 2015-12-4, status: 2, price: 2}
{id: <auto>, product_id: 2, last_updated: 2015-12-4, status: 2, price: 10}
Now, I am trying to find a way, maybe using a secondary compound index, do get for example, given a date like in col1 (using r.time)
DATE STATUS==1 STATUS==0 STATUS==2
2015-12-1 [101, 102] [] []
2015-12-2 [103, 106] [105] []
2015-12-3 [106] [104, 105] []
2015-12-4 [] [] [107, 108]
The difficulty here, is that a product_id document is still to be considered as the most recent status as long as its last_updated date is less or equal to the provided date.
I try by grouping by product_id, then take the max('last_updated'), then only keep each reduction unique document if status==1
I have in mind to have an index for each status / given_date
Or another solution, would be to insert in another table the result of an aggregation which would only store a unique document per date, containing all the initial documents ids matching the same criteria, and so on...
And then later perform joins using these intermediate records to fetch the values of each product_id at the given date/status.
something like:
{
date: <date_object>,
documents: [
{id: document_id, status: 1},
{id: document_id, status: 1},
{id: document_id, status: 2},
{id: document_id, status: 0},
...
]
}
Please advise
Edit 1:
This is an example of a query I try to run to analyse my data, here it is for example to get an overview of the statuses for each group with more than 1 document:
r.db('test').table('products_10k_sample')
.group({index: 'product_id'})
.orderBy(r.desc('last_updated'))
.ungroup()
.map(function(x){
return r.branch(
x('reduction').count().gt(1),
x('reduction').map(function(m){
return [m('last_updated').toISO8601(), m('status'), m('product_id')]
}),
null
)
})