Combining 2-dimensional array (matrix) elements - arrays

I have a 2-dimensional array like [[1,2,3], [4,5,6], [7,8,9]].
So I need to combine every element with all the others form another sublists ang get an array like [[1,4,7], [1,4,8], [1,4,9], [2,4,7], [2,4,8], [2,4,9], [3,4,7], [3,4,8], [3,4,9], [1,5,7], [...], [...], ... etc] in Python3.
! The number of sublists may be different.
I have used different approaches with loops but nothing works correctly. How can I do that without using itertools? Thanks in advance!
I tried iterating arrays but I could not fully embody the idea.
arr = [[1,2,3], [4,5,6], [7,8,9]]
total = []
for i in arr[0]:
for index, j in enumerate(arr[1:]):
res = [i]
for indx, n in enumerate(j):
res.append(n)
for m in arr[index+1]:
res.append(m)
break
print(res)
And I got only this
[1, 4, 4, 5, 4, 6, 4]
[1, 7, 7, 8, 7, 9, 7]
[2, 4, 4, 5, 4, 6, 4]
[2, 7, 7, 8, 7, 9, 7]
[3, 4, 4, 5, 4, 6, 4]
[3, 7, 7, 8, 7, 9, 7] .. which is not correct.

Just use the cartesian product from itertools
from itertools import product
arr = [[1,2,3], [4,5,6], [7,8,9]]
prod = product(*arr)
print(list(prod))

Related

Sorting an array according to an element inside this array

I need to order my array according to an element of it, the reference element can vary.
For example, I would like the 3 to become the first element of the array and the 1, 2 to be put at the end.
array = [1, 2, 3, 4, 5, 6]
new_array = [3, 4, 5, 6, 1, 2]
The element may vary. If I start from 5, the behavior must be the same: the elements that precede are placed at the end, so I will have :
new_array = [5, 6, 1, 2, 3, 4]
If I understand correctly you want to rotate the array.
array
# [1, 2, 3, 4, 5, 6]
array.rotate(2) # or array.rotate(array.index(3))
# [3, 4, 5, 6, 1, 2]
https://apidock.com/ruby/v2_5_5/Array/rotate
Definitely use #rotate for this in actual use, but as an alternative, you could do something like #shift and #push until the desired element is at the beginning of the array.
def rotate(arr, elem)
arr2 = arr.clone
arr2.push(arr2.shift) until arr2.first == elem
arr2
end
irb(main):026:0> arr = [1, 2, 3, 4, 5, 6]
=> [1, 2, 3, 4, 5, 6]
irb(main):027:0> rotate(arr, 3)
=> [3, 4, 5, 6, 1, 2]
irb(main):028:0> arr
=> [1, 2, 3, 4, 5, 6]
Clearly, if elem is not in arr, this will run forever. You could implement some kind of check to ensure this doesn't happen, but that's just one reason you shouldn't actually do this as anything other than a learning exercise.
One approach would be to find the index of elem in arr and shift/push that many times. The &. operator may be useful in that situation to deal with the possibility of not finding elem in arr.

Rearrange array [1, 2, 3, 4, 5, 6] to [1, 3, 5, 2, 4, 6]

I'm looking for the royal road to rearrange an array of variable length like
[1, 2, 3, 4, 5, 6]
into something like this:
[1, 3, 5, 2, 4, 6]
The length of the array is always dividable by 3. So I could also have an array like this:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
which should be turned into:
[1, 4, 7, 2, 5, 8, 3, 6, 9]
A real example would look like this:
['X.1', 'X.2', 'Y.1', 'Y.2', 'Z.1', 'Z.2']
which I would like to turn into:
['X.1', 'Y.1', 'Z.1', 'X.2', 'Y.2', 'Z.2']
An array of size 3 or an empty array should remain unmodified.
How would I do that?
If a is the name of your NumPy array, you can write:
a.reshape(3, -1).ravel('f')
(This assumes that your array is divisible by 3, as you have stated.)
This method works by first viewing each chunk of len(a) / 3 elements as rows of a 2D array and then unravels that 2D array column-wise.
For example:
>>> a = np.array([1, 2, 3, 4, 5, 6])
>>> a.reshape(3, -1).ravel('f')
array([1, 3, 5, 2, 4, 6])
>>> b = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b.reshape(3, -1).ravel('f')
array([1, 4, 7, 2, 5, 8, 3, 6, 9])
no numpy solution:
>>> r = range(1,10)
>>> sum([r[i::len(r)/3] for i in range(len(r)/3)],[])
[1, 4, 7, 2, 5, 8, 3, 6, 9]
i used sum for concatenting lists as it is the most self contained and readable example. But as mentioned in the comments, it is certainly not the most efficient one. For efficiency, you can use list (in)comprehension:
>>> r = range(1,10)
>>> [x for y in [r[i::len(r)/3] for i in range(len(r)/3)] for x in y]
[1, 4, 7, 2, 5, 8, 3, 6, 9]
or any of the other methods mentioned here.
Using reshape and transpose (or T) will do :
import numpy as np
t = np.arange(1, 10)
t2 = np.reshape(t, [t.shape[0]/3, 3]).T.reshape(len(t))

Sum every 3 elements of an array in ruby

Is there any efficient and short way to sum every 3 elements of an array?
ar = [1, 2, 3, 4, 5, 6, 7, 8, 1]
sum_ar = [6, 15, 16]
first 3 elements 1+2+3=6
next 3 elements 4+5+6=15
next 3 elements 7+8+1=15
...
if there are only two elements left, sum them
I could do something like this:
y=0
s=ar.size/3
((0..s).step(3).to_a).each do |i|
sum_ar[y]=ar[i..i+2].inject(:+)
y=y+1
end
but then I will miss the elements in case of such an array, where the size is not an exactly multiply of a 3:
ar=[1, 2, 3, 4, 5, 6, 7, 8]
A short way with Enumerable#each_slice:
[1, 2, 3, 4].each_slice(3).map { |e| e.inject(:+) } # => [6, 4]

How to select a portion of a NumPy array efficiently?

I'm switching from Matlab/octve to Numpy/Scipy.
To select a segment of a Matlab array, it was quite easy.
e.g.
>> x = [1, 2, 3, 4; 5, 6, 7, 8; 9, 10, 11, 12]
x =
1 2 3 4
5 6 7 8
9 10 11 12
>> y = x(2:3, 1:2)
y =
5 6
9 10
How can the same thing be done with NumPy when
x = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
As Indexing > Other indexing options in the NumPy documentation mentions,
The slicing and striding works exactly the same way it does for lists and tuples except that they can be applied to multiple dimensions as well.
For your example, this means
import numpy as np
x = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
# array([[ 1, 2, 3, 4],
# [ 5, 6, 7, 8],
# [ 9, 10, 11, 12]])
x[1:3, 0:2]
# => array([[ 5, 6],
# [ 9, 10]])
Most notable difference to Matlab is probably that indexing is zero-based (i.e., first element has index 0) and that index ranges (called 'slices' in Python) are expressed with an exclusive upper bound: l[4:7] gets l[4], l[5] and l[6] (the 3rd to the 7th element), but not l[7] (the 8th element).
The Python tutorial's section on lists will give you a feeling for how indexing and slicing works for normal (1-dimensional) collections.

How do I arrange an array as table rows?

I am trying to learn the Ruby way of array processing. What is a succinct way to write the following function?
def columnize(items, n_cols)
Items is a 1D array of arbitrary length. I want to return an array of rows, each having a length of n_cols, that includes all of the items column-wise, possibly with nils padding the last column. For example:
items = [1, 2, 3, 4, 5, 6, 7]
table = columnize items, 3
This should produce a table of:
[[1, 4, 7],
[2, 5, nil],
[3, 6, nil]]
Note that it's possible for the last column to be all nils as in:
columnize [1, 2, 3, 4, 5, 6, 7, 8, 9], 4
This is a real problem I need to solve for report generation. I have a Ruby newbie solution that is not very satisfying and can post it if desired.
You want to use Matrix class.
items = [1, 2, 3, 4, 5, 6, 7]
require 'matrix'
# ⇒ true
m = Matrix.build(3) { |row, col| items[row+col*3] }
# ⇒ Matrix[[1, 4, 7], [2, 5, nil], [3, 6, nil]]
Ruby's Array class has transpose which is designed to convert rows into columns. Using it in conjunction with fill and Enumerable's each_slice gives:
require 'pp'
def columnize(items, cols)
ary = items.dup.fill(nil, items.size, cols - items.size % cols )
ary.each_slice(ary.size / cols).to_a.transpose
end
items = [1, 2, 3, 4, 5, 6, 7]
pp columnize(items, 3)
pp columnize [1, 2, 3, 4, 5, 6, 7, 8, 9], 4
Which outputs:
[[1, 4, 7], [2, 5, nil], [3, 6, nil]]
[[1, 4, 7, nil], [2, 5, 8, nil], [3, 6, 9, nil]]
Except for filling rows that only have nil elements, this will do:
first, *rest = items.each_slice((items.length/n_cols).ceil).to_a
first.zip(*rest)

Resources