How can I Select nth element from an array's 2nd dimension? - sql

I have a 2-dimensional int array, and I'd like to get the 2nd element from every array in the 2nd dimension. So for example, I'd like to get 2,4, and 6 from the array literal '{{1,2},{3,4},{5,6}'. Is this possible? I've searched the docs but I haven't found anything that can do what I want.

unnest(arr[:][2:2]) will give you a table expression for what you want (where arr is the name of your array column)
If you want to get a 1 dimensional array of those elements, you can use array(select * from unnest(arr[:][2:2])) (because arr[:][2:2] is still a 2 dimensional one).
http://rextester.com/VLOJ18858

Related

Inconsistent behavior when slicing a 2d array in PostgreSQL

Let's say I have a 2d array:
# SELECT ARRAY[ARRAY[1,2], ARRAY[3,4]];
array
---------------
{{1,2},{3,4}}
(1 row)
Now, if I want to get the first element of each inner array, adding (...)[:][1] will do the trick:
# SELECT (ARRAY[ARRAY[1,2], ARRAY[3,4]])[:][1];
array
-----------
{{1},{3}}
(1 row)
BUT: If I want to obtain the second element of each inner array, I have to opt for adding (...)[:][2:2], as (...)[:][2] would return the untouched array again
# SELECT (ARRAY[ARRAY[1,2], ARRAY[3,4]])[:][2];
array
---------------
{{1,2},{3,4}}
(1 row)
# SELECT (ARRAY[ARRAY[1,2], ARRAY[3,4]])[:][2:2];
array
-----------
{{2},{4}}
(1 row)
What is the reason for this inconsistent behavior?
I think the documentation explains this pretty well:
If any dimension is written as a slice, i.e., contains a colon, then all dimensions are treated as slices. Any dimension that has only a single number (no colon) is treated as being from 1 to the number specified.
That is, when you are using slices, Postgres expects all dimensions to be slices. Those that are not are defaulted to 1:n.

Fastest way to find two minimum values in each column of NumPy array

If I want to find the minimum value in each column of a NumPy array, I can use the numpy.amin() function. However, is there a way to find the two minimum values in each column, that is faster than sorting each column?
You can simply use np.partition along the columns to get smallest N numbers -
N = 2
np.partition(a,kth=N-1,axis=0)[:N]
This doesn't actually sort the entire data, simply partitions into two sections such that smallest N numbers are in the first section, also called as partial-sort.
Bonus (Getting top N elements) : Similarly, to get the top N numbers per col, simply use negative kth value -
np.partition(a,kth=-N,axis=0)[-N:]
Along other axes and higher dim arrays
To use it along other axes, change the axis value. So, along rows, it would be axis=1 for a 2D array and extend the same way for higher dimension ndarrays.
Use the min() method, and specify the axis you want to average over:
a = np.random.rand(10,3)
a.min(axis=0)
gives:
array([0.04435587, 0.00163139, 0.06327353])
a.min(axis=1)
gives
array([0.01354386, 0.08996586, 0.19332211, 0.00163139, 0.55650945,
0.08409907, 0.23015718, 0.31463493, 0.49117553, 0.53646868])

Removed the last element from a json[]?

I have a json[] array (_result_group) in PostgreSQL 9.4, and I want to remove its last json element (_current). I prepared with:
_result_group := (SELECT array_append(_result_group,_current));
And tried to remove with:
SELECT _result_group[1:array_length(_result_group,1) -1] INTO _result_group;
But it didn't work.
How to do this?
To remove the last element from any array (including json[]) with the means of Postgres 9.4, obviously within plpgsql code:
_result_group := _result_group[1:cardinality(_result_group)-1];
Assuming a 1-dimensional array with default subscripts starting with 1.
You get an empty array for empty array input and null for null.
According to the manual, cardinality() ...
returns the total number of elements in the array, or 0 if the array is empty
Then just take the array slice from 1 to cardinality -1.
Then again, your attempt should work as well:
SELECT _result_group[1:array_length(_result_group,1) -1] INTO _result_group;
For non-standard array subscripts see:
Normalize array subscripts for 1-dimensional array so they start with 1

PostgreSQL - return the number of elements in one array appear in another array

I have a table with two columns. Each column should contain an array (int[]) but some are null.
I want to create a third column that counts how many elements of the first array appear in the second array, duplicates included.
For example,
array_1 = {23277,23277}
array_2 = {23638,23187,23201,23612,28322,27953,23277,23173,23794,28796,23291,23714}
The result is 2. Because two (both) items of array_1 are within array_2.
Similarly, if I have:
array_1 = {23201,23612,2001,23201}
array_2 = {23638,23187,23201,23612,28322,27953,23277,23173,23794,28796,23291,23714}
Result is 3 because three elements of array_1 are in array_2.
Trying the && operator only returns True or False.
Do I need to write a custom agg function that would unnest array_1 and then count?
I am using PostgreSQL 9.6.
Any help or guidance would be greatly appreciated.

How to identify the indices for the nth smallest values in a multi dimensional array in VBA?

I currently have a 3 dimensional array full of different values. I would like to find the indices corresponding to the "nth" smallest values in the array. For example... If the 3 smallest values were 0.1, 0.2 and 0.3 I would like to see, in order, the indices for these values. Any help would be greatly appreciated.
A possible way to approach this would be adding an original index dimension into your 3rd array, then sorting, by the current values to find out the smallest item and returning the original index. Take a look into this: VBA array sort function?