Is there any functional difference between array_upper and array_length? - arrays

The postgres docs on these 2 array functions are pretty weak.
I've tried both functions a few different ways and they seem to return the same results.
SELECT array_length(array[[1, 2], [3, 4], [5, 6]], 1);
SELECT array_upper(array[[1, 2], [3, 4], [5, 6]], 1);
SELECT array_length(array[[1, 2], [3, 4], [5, 6]], 2);
SELECT array_upper(array[[1, 2], [3, 4], [5, 6]], 2);

Yes, there is a difference. PostgreSQL array subscripts start at one by default but they don't have to:
By default PostgreSQL uses a one-based numbering convention for arrays, that is, an array of n elements starts with array[1] and ends with array[n].
[...]
Subscripted assignment allows creation of arrays that do not use one-based subscripts. For example one might assign to myarray[-2:7] to create an array with subscript values from -2 to 7.
[...]
By default, the lower bound index value of an array's dimensions is set to one. To represent arrays with other lower bounds, the array subscript ranges can be specified explicitly before writing the array contents.
In general, you need to use array_lower and array_upper instead of assuming that the array will start at 1 and end at array_length(a, n).

Related

Find all array with second highest elements in a list

Assuming that I have a list of arrays in Python 3.2, and I want to output an array that contains every array elements, together with their index position in the list, which have the highest second elements. How can I achieve this goal in the most scalable way (i.e., without having to use the nested for-loop )?
Input
a = [[2,3], [1,4,5], [1,4,6,2], [3,3,5], [9,4]]
Expected Output
res = [[[1,4,5], 1], [[1, 4, 6,2], 2], [[9,4], 4]]
Can someone please help assist me on how to do this without using nested for-loop?
You could do:
b = max(a, key=lambda x:x[1])[1]
[[j, i] for i, j in enumerate(a) if j[1]==b]
Out[6]: [[[1, 4, 5], 1], [[1, 4, 6, 2], 2], [[9, 4], 4]]

Quicker way of adding x to every second element in all nested arrays

I have a nested array in ruby, similar to the one below, but with quite a few more nested arrays.
arr=[[1,2,3],[4,5,6],[7,8,9]]
Is there a way to get every second element within the nested array, and add x to that element? I have used the code below, but if there is a quicker way I'd love to know.
x = 5
arr[0][1], arr[1][1], arr[2][1] = arr[0][1]+x, arr[1][1]+x, arr[2][1]+x
I have tried to use arr.map!{|f,l| [f, l + 1]}, but I get the result arr == [[1, 3], [4, 6], [7, 9]]
EDIT:
So the outcome should be arr == [[1,2+x,3],[4,5+x,6],[7,8+x,9]]
Any time you find yourself writing that kind of code over and over, you should look to use a loop! Ruby commonly uses iterators for performing looping. Array#each is an iterator which loops over an Array, and lets you operate on each element one at a time.
Since you know that you want to add x to the second element in each, this is trivially:
arr.each {|e| e[1] += x }
This mutates arr (and arr's subarrays) in place. If you want to return a mutated copy, you would use map, which is like each except the return value is the output of the block, rather than the input to it.
# First we clone each subarray with Array#dup, then we iterate the
# clones, adding x to the second element. Because we're using `map`
# the result will be a new array, rather than the original arr, leaving
# the original unmodified.
new_arr = arr.map(&:dup).each {|e| e[1] += x }
You're close! You can use map to loop through each sub-array and the ruby += operator to add x to the second element of each. The trick with map is that you'll need to return the entire sub-array in each loop, which would look like:
arr.map { |a| a[1] += x; a }
#=> [[1, 7, 3], [4, 10, 6], [7, 13, 9]]
Here's another one:
arr = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
x = 5
arr.map { |a, b, c| [a, b + x, c] }
#=> [[1, 7, 3], [4, 10, 6], [7, 13, 9]]
Note that map returns a new array. If you want to modify the existing array, there's map!.

Algorithm Logic, Splitting Arrays

I'm not looking for a solution just pseudo code or logic that would help me derive an answer.
Given an array:
[1,2,3,4]
I want to split this into two arrays of varying lengths and contents whose sum lengths are equal to the length of the given array. It would be ideal without repetition.
Example output:
[[1],[2, 3, 4]]
[[1, 2], [3, 4]]
[[1, 3], [2, 4]]
[[1, 4],[2, 3]]
[[1, 2, 3], [4]]
[[2], [1, 3, 4]]
[[2, 4], [1, 3]]
[[3], [1, 2, 4]]
More example:
[[1, 3, 4, 6, 8], [2, 5, 7]] //this is a possible combination of 1 through 8
//array
Intuitions:
First attempt involved pushing the starting number array[i] to the result array[0], the second loop moving the index for the third loop to start iterating as is grabbed sublists. Then fill the other list with remaining indices. Was poorly conceived...
Second idea is permutations. Write an algorithm that reorganizes the array into every possible combination. Then, perform the same split operation on those lists at different indexes keeping track of unique lists as strings in a dictionary.
[1,2,3,4,5,6,7,8]
^
split
[1,2,3,4,5,6,7,8]
^
split
[1,3,4,5,6,7,8,2]
^
split
I'm confident that this will produce the lists i'm looking for. However! i'm afraid it may be less efficient than I'd like due to the need for sorting when checking for duplicates and permutations is expensive in the first place.
Please respond with how you would approach this problem, and why.
Pseudocode. The idea is to start with an item in one of the bags, and then to place the next item once in the same bag, once in the other.
function f(A):
// Recursive function to collect arrangements
function g(l, r, i):
// Base case: no more items
if i == length(A):
return [[l, r]]
// Place the item in the left bag
return g(l with A[i], r, i + 1)
// Also return a version where the item
// is placed in the right bag
concatenated with g(l, r with A[i], i + 1)
// Check that we have at least one item
if A is empty:
return []
// Start the recursion with one item placed
return g([A[0]], [], 1)
(PS see revisions for JavaScript code.)

numpy using multidimensional index array on another multidimensional array

I have a 2 multidimensional arrays, and I'd like to use one as the index to produce a new multidimensional array. For example:
a = array([[4, 3, 2, 5],
[7, 8, 6, 8],
[3, 1, 5, 6]])
b = array([[0,2],[1,1],[3,1]])
I want to use the first array in b to return those indexed elements in the first array of a, and so on. So I want the output to be:
array([[4,2],[8,8],[6,1]])
This is probably simple but I couldn't find an answer by searching. Thanks.
This is a little tricky, but the following will do it:
>>> a[np.arange(3)[:, np.newaxis], b]
array([[4, 2],
[8, 8],
[6, 1]])
You need to index both the rows and the columns of the a array, so to match your b array you would need an array like this:
rows = np.array([[0, 0],
[1, 1],
[2, 2]])
And then a[rows, b] would clearly return what you are after. You can get the same result relying on broadcasting as above, replacing the rows array with np.arange(3)[:, np.newaxis], which is equivalent to np.arange(3).reshape(3, 1).

How to extract lines in an array, which contain a certain value? (numpy, scipy)

I have an numpy 2D array and I want it to return coloumn c where (r, c-1) (row r, coloumn c) equals a certain value (int n).
I don't want to iterate over the rows writing something like
for r in len(rows):
if array[r, c-1] == 1:
store array[r,c]
, because there are 4000 of them and this 2D array is just one of 20 i have to look trough.
I found "filter" but don't know how to use it (Found no doc).
Is there an function, that provides such a search?
I hope I understood your question correctly. Let's say you have an array a
a = array(range(7)*3).reshape(7, 3)
print a
array([[0, 1, 2],
[3, 4, 5],
[6, 0, 1],
[2, 3, 4],
[5, 6, 0],
[1, 2, 3],
[4, 5, 6]])
and you want to extract all lines where the first entry is 2. This can be done like this:
print a[a[:,0] == 2]
array([[2, 3, 4]])
a[:,0] denotes the first column of the array, == 2 returns a Boolean array marking the entries that match, and then we use advanced indexing to extract the respective rows.
Of course, NumPy needs to iterate over all entries, but this will be much faster than doing it in Python.
Numpy arrays are not indexed. If you need to perform this specific operation more effeciently than linear in the array size, then you need to use something other than numpy.

Resources