Array Multiplication & Sum with JQ? - arrays

{
"pricexquant": [
[
"20233.54000000",
"0.00877000"
],
[
"20233.39000000",
"0.00999000"
]
]
}
for an array of arrays with 2 elements as strings, how would jq multiply element 1 * element 2 in each array? and from that generate a new array...
eg.
{
[
"177.4481458"
],
[
"200.310561"
]
}
and for that sum the total across all?

.pricexquant|map(map(tonumber)|.[0] * .[1])|add
yields
379.5797119

Related

Iterating over arrays simultaneously using jq

I'm describing the output I'd like to have using jq
Here my json file
{
"partitions": [
{
"replicas": [
0,
1,
2
],
"log_dirs": [
"any",
"any",
"any"
]
},
{
"replicas": [
2,
0,
1
],
"log_dirs": [
"any",
"any",
"any"
]
},
[...]
I would like, for every object in partitions[] to replace the value of the i th string in log_dirs[] by its concatenation with the i th number in replicas[] in order to have something like this
{
"partitions": [
{
"replicas": [
0,
1,
2
],
"log_dirs": [
"any0",
"any1",
"any2"
]
},
{
"replicas": [
2,
0,
1
],
"log_dirs": [
"any2",
"any0",
"any1"
]
},
[...]
Use a reduce loop with a range
.partitions[] |= reduce range(0; ( .replicas | length ) ) as $r
( . ; .log_dirs[$r] += ( .replicas[$r] | tostring ) )
The reduce expression works by iterating over the entire log_dirs array upto the length of replicas list and modifying each entry .log_dirs[$r] (here r runs from 0 - length of replicas) by appending the corresponding value at replicas[$r]. Since replicas contains numerics, it needs to be converted to string for the append operation.
jqplay - demo
I'm not quite happy with this, but it does work:
jq '.partitions[] |= . + (
. as $p | {
log_dirs: [
range(.replicas | length) |
"\($p.log_dirs[.])\($p.replicas[.])"
]
}
)' in.json

Filtering out the unique values between 2 mongodb arrays using mongodb 3.4

I have 2 arrays:
"array1": [
"057a7",
"05790",
"0575d",
"0579f",
"0576b",
"05784",
"05775"
]
"array2": [
"0579f",
"057a7",
"05790",
"05784",
"0575d",
"0576a",
"0576b",
"05775"
]
I have tried $setDifference, $setUnion and $setIntersection and these only output the elements that match. I would like to output the one that does not ("0576a"). The examples I find in stack overflow only seem to show you how to output the duplicates and not the unique values. The final output should be an array like so:
"final_array": ["0576a"]
Trying to do this in mongodb aggregation and not have to tap into mapReduce.
{
"$project": {
"_id": 0,
"unique": {
"$setDifference": [
"$array2",
"$array1"
]
}
}
}
The following should work for you:
db.collection('test').aggregate({
$project: {
"unique": {
$concatArrays: [
{ $setDifference: [ "$array1", "$array2" ] },
{ $setDifference: [ "$array2", "$array1" ] }
]
}
}
})
The key thing to understand about $setDifference is that the argument order matters since according to the documentation it...
...takes two sets and returns an array containing the elements that only
exist in the first set; i.e. performs a relative complement of the
second set relative to the first.
That's why you'll have to look at your arrays from both directions which will give you all unique elements and then you can simply merge the two results using $concatArrays.

Convert elements in a numpy array to string

I wrote the following script to load data from CSV file in numpy array form:
import numpy
sample = numpy.genfromtxt('sample_cor.csv', delimiter = ',')
print sample
and this sample looked like:
[[ 259463.392 2737830.062 ]
[ 255791.4823 2742050.772 ]
[ 249552.4949 2746152.328 ]
[ 247925.1228 2746422.143 ]
[ 262030.4697 2728966.229 ]
[ 260462.1936 2731412.856 ]
[ 260644.0281 2735003.027 ]
[ 268588.7974 2732835.097 ]]
now I want to extract every row in this array to string with a comma, for example, I expected row 1 to be converted to 259463.392,2737830.062, row 2 to be 255791.4823,2742050.772, and so on.
I tried the code below:
ss = numpy.array_str(sample[0])
print ss
print type(ss)
and got the result maybe not what I want,
[ 259463.392 2737830.062]
<type 'str'>
(I used coords = '259467.2,2737833.87' and got the string form which was what I want:
259467.2,2737833.87)
How to convert elements in a numpy array to string with a comma?
Here's an approach using join method -
[",".join(item) for item in a.astype(str)]
Sample run -
In [141]: a
Out[141]:
array([[ 259463.392 , 2737830.062 ],
[ 255791.4823, 2742050.772 ],
[ 249552.4949, 2746152.328 ],
[ 247925.1228, 2746422.143 ],
[ 262030.4697, 2728966.229 ],
[ 260462.1936, 2731412.856 ],
[ 260644.0281, 2735003.027 ],
[ 268588.7974, 2732835.097 ]])
In [142]: [",".join(item) for item in a.astype(str)]
Out[142]:
['259463.392,2737830.062',
'255791.4823,2742050.772',
'249552.4949,2746152.328',
'247925.1228,2746422.143',
'262030.4697,2728966.229',
'260462.1936,2731412.856',
'260644.0281,2735003.027',
'268588.7974,2732835.097']

Getting array elements using array index in mongoDB

Consider following collection in mongoDB :
{a:[4,2,8,71,21]}
{a:[24,2,2,1]}
{a:[4,1]}
{a:[4,2,8,21]}
{a:[2,8,71,21]}
{a:[4,2,8]}
How can I get following results in a most easily:
Getting nth element of array
{a:4}
{a:24}
{a:4}
{a:4}
{a:2}
{a:4}
Getting elements 2 to 4
{a:[8,71,21]}
{a:[2,1]}
{a:[]}
{a:[8,21]}
{a:[71,21]}
{a:[8]}
And other similar queries.
What you are looking for is the $slice projection.
Getting a number of elements from the beginning of an array
You can pass a simple $limit with a number of values to return (eg. 1):
> db.mycoll.find({}, {_id: 0, a: { $slice: 1}})
{ "a" : [ 4 ] }
{ "a" : [ 24 ] }
{ "a" : [ 4 ] }
{ "a" : [ 4 ] }
{ "a" : [ 2 ] }
{ "a" : [ 4 ] }
Getting a range of elements
You can pass an array with parameters of ( $skip, $limit ).
Note: to match your expected output you would have to find elements 3 to 5 (skip the first 2 elements, return the next 3):
> db.mycoll.find({}, {_id: 0, a: { $slice: [2,3]}})
{ "a" : [ 8, 71, 21 ] }
{ "a" : [ 2, 1 ] }
{ "a" : [ ] }
{ "a" : [ 8, 21 ] }
{ "a" : [ 71, 21 ] }
{ "a" : [ 8 ] }
Getting the nth element of array
Pass the number of elements to $skip and a value of 1 for the limit.
For example, to find the second element you need to skip 1 entry:
> db.mycoll.find({}, {_id: 0, a: { $slice: [1,1]}})
{ "a" : [ 2 ] }
{ "a" : [ 2 ] }
{ "a" : [ 1 ] }
{ "a" : [ 2 ] }
{ "a" : [ 8 ] }
{ "a" : [ 2 ] }
Note that the $slice operator:
always returns an array
will return an empty array for documents that match the find criteria but return an empty result for the $slice selection (eg. if you ask for the 5th element of an array with only 2 elements)

initialise list with every element is a an associative array and last elment of the associative array is two d array in perl?

I'm trying to create a database .Each element in list contains details in the form of associative array and the last element of each of these associative array is a 2-d array,i need help initializing it ..
You need to say much more about what it is you are trying to do, but this may help: it initialises a Perl data structure in the way you have described. Note that there can be no "last" element of a hash (a better name than "associative array") as hashes are unordered. I have used the customers field of the data to hold the 2D array you talked about.
use strict;
use warnings;
my #list = (
{
id => 1,
name => 'cattle',
customers => [
[ 'World Bank', 'Space Marines', 'Undersea Exploration' ],
[ 1, 2, 3 ],
[ 0.0500, 0.6322, 0.9930 ],
],
},
{
id => 2,
name => 'arable',
customers => [
[ 'Jack Spratt', 'Molly Malone', 'The Whistler' ],
[ 4, 5, 6 ],
[ 0.0022, 0.1130, 0.6930 ],
],
},
{
id => 3,
name => 'seafood',
customers => [
[ 'Tai Chi School of Fishery', 'Latin Intermediary College', 'Ping Pong Gymnastics' ],
[ 7, 8, 9 ],
[ 0.0012, 0.8540, 0.9817 ],
],
},
);

Resources