convert data from 2d to 3d numpy array - python-2.7

If I have a 2d array like:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
And I want to end up with a 3d array like:
array([[[0, 4, 8],
[1, 5, 9]],
[[2, 6, 10],
[3, 7, 11]]])
How should I reshape the array to get what I want?

Reshape and permute axes -
In [11]: a # Input array
Out[11]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
In [12]: a.reshape(-1,2,2).transpose(1,2,0)
Out[12]:
array([[[ 0, 4, 8],
[ 1, 5, 9]],
[[ 2, 6, 10],
[ 3, 7, 11]]])
With np.moveaxis -
np.moveaxis(a.reshape(-1,2,2), 0,-1)
Generalizing it and assuming that you want the length along the first axis as half of no. of columns -
In [16]: m,n = a.shape
In [17]: a.reshape(m,-1,2).transpose(1,2,0)
Out[17]:
array([[[ 0, 4, 8],
[ 1, 5, 9]],
[[ 2, 6, 10],
[ 3, 7, 11]]])
If that length is supposed to be 2 -
In [15]: a.reshape(m,2,-1).transpose(1,2,0)
Out[15]:
array([[[ 0, 4, 8],
[ 1, 5, 9]],
[[ 2, 6, 10],
[ 3, 7, 11]]])

Related

Prolog: Create a List from a selection of a given List

I want to write a predicate in Prolog, which creates a all possible segments of a given Size of a given List and returns the un-selected elements as a List.
My Code so far:
select_seg(List, Segment, Rest, Size ):-
select_seg(List, Segment, Rest, Size, Size).
select_seg(_,_,_,_, 0):- !.
select_seg(List, [Head_Segs|Tail_Segs],[Head_Rest|Tail_Rest], Size,Acc ):-
select(Head_Segs, List, Head_Rest),
Acc >= 0,
New_Acc is Acc - 1,
select_seg(Head_Rest, Tail_Segs, Tail_Rest, Size, New_Acc).
When I call this predicate with:
select_seg([1,2,3,4,5,6,7,8,9], Seg, R ,3 ).
It returns:
Seg = [1, 2, 3|_],
R = [[2, 3, 4, 5, 6, 7, 8, 9], [3, 4, 5, 6, 7, 8, 9], [4, 5, 6, 7, 8, 9]|_] ;
Seg = [1, 2, 4|_],
R = [[2, 3, 4, 5, 6, 7, 8, 9], [3, 4, 5, 6, 7, 8, 9], [3, 5, 6, 7, 8, 9]|_] ;
Seg = [1, 2, 5|_],
R = [[2, 3, 4, 5, 6, 7, 8, 9], [3, 4, 5, 6, 7, 8, 9], [3, 4, 6, 7, 8, 9]|_] ;
This is desired output, except that the list of remaining elements contain three lists for each element in the Segment the List of remaining elements, but should only contain the last one as following:
Seg = [1, 2, 3|_],
R = [4, 5, 6, 7, 8, 9]|_] ;
Seg = [1, 2, 4|_],
R = [3, 5, 6, 7, 8, 9]|_] ;
Seg = [1, 2, 5|_],
R = [3, 4, 6, 7, 8, 9]|_] ;
I tried everything, but I am not able to come up with the right solution.
It's combining select with a variant of select:
select_len_seg(Len, L, Seg, Rem) :-
length(Seg, Len),
select_len_seg_(Seg, L, L, Rem).
select_len_seg_([], _, R, R).
select_len_seg_([H|T], F, R, Rem) :-
% Preventing "duplicates" such as [3,2,1]
select_forward(H, F, F0),
select(H, R, R0),
select_len_seg_(T, F0, R0, Rem).
select_forward(E, [H|T], F) :-
select_forward_(T, H, E, F).
select_forward_(T, H, H, T).
select_forward_([H|T], _, E, F) :-
select_forward_(T, H, E, F).
Results in swi-prolog:
?- select_len_seg(3, [1,2,3,4,5,6,7,8,9], S, R).
S = [1, 2, 3],
R = [4, 5, 6, 7, 8, 9] ;
S = [1, 2, 4],
R = [3, 5, 6, 7, 8, 9] ;
...
S = [6, 7, 9],
R = [1, 2, 3, 4, 5, 8] ;
S = [6, 8, 9],
R = [1, 2, 3, 4, 5, 7] ;
S = [7, 8, 9],
R = [1, 2, 3, 4, 5, 6] ;
false.

Nested lists addition

I have a nested list called a:
a = [[0, 1, 2, 3, 4], [10, 11, 12, 13, 14]]
My desired output is a new list (b) containing the first list in a: [0, 1, 2, 3, 4]. Then I want to append to this list all of the values in [10, 11, 12, 13, 14] added to the last number in [0, 1, 2, 3, 4]:
b = [0, 1, 2, 3, 4, 14, 15, 16, 17, 18]
# Your First List
a =[[0, 1, 2, 3, 4], [10, 11, 12, 13, 14]]
# Your Second List which is initalized as empty.
b = []
# Adding first list from (a) which is a[0] into second list
# a[0] = [0, 1, 2, 3, 4]
# a[1] = [10, 11, 12, 13, 14]
b.extend(a[0])
# b = [0, 1, 2, 3, 4]
# I then want to append to this list all of the values in [10, 11, 12, 13, 14] added
# the last number in [0, 1, 2, 3, 4].
# a[0] = [0, 1, 2, 3, 4]
# a[0][-1] = 4
last_val = a[0][-1]
second_list = a[1] # [10, 11, 12, 13, 14]
for item in second_list:
b.append(item+last_val)
print(b)
# b = [0, 1, 2, 3, 4, 14, 15, 16, 17, 18]

Understanding Python list.append behavior

Why in the following example is appending to the big_l in the for loop changes also the last lists already added to the big_l?
l=[1,2,3,4,5]
big_l=[]
def f(ll):
x=ll.pop(0)
ll.append(x)
return ll
for i in range(4):
big_l.append(l)
print l,big_l
l=f(l)
It prints:
[1, 2, 3, 4, 5] - [[1, 2, 3, 4, 5]]
[2, 3, 4, 5, 1] - [[2, 3, 4, 5, 1], [2, 3, 4, 5, 1]]
[3, 4, 5, 1, 2] - [[3, 4, 5, 1, 2], [3, 4, 5, 1, 2], [3, 4, 5, 1, 2]]
[4, 5, 1, 2, 3] - [[4, 5, 1, 2, 3], [4, 5, 1, 2, 3], [4, 5, 1, 2, 3], [4, 5, 1, 2, 3]]

Find largest independent set in list

I have python lists like follows
>>>[[2, 0, 10], [2, 0, 11], [2, 1, 12], [2, 1, 13], [4, 3, 5], [4, 3, 7], [7, 6, 8], [7, 6, 10], [10, 9, 2], [10, 9, 11], [13, 14, 15]]
>>>[[0, 1, 3], [0, 1, 6], [3, 2, 0], [3, 2, 6], [3, 4, 5]]
I want to extract largest list set containing uncommon values. For example, for latter list, the largest independent set should be [[0, 1, 6], [3, 4, 5]], whereas for the former, it should be [[2, 0, 12], [4, 3, 5], [7, 6, 8], [10, 9, 11], [13, 14, 15]]. It may be similar with maximum independent set problem, but I have no idea about this as I know nothing about graphs. So any suggestion to solve this problem? Thanks in advance.

Python How to sort a list of list with certain conditions

I have list of list and I want to sort the list by 4 index by alphabetically but there are cases where it will be none or empty so those cases needed to be at the bottom.
For further clarfication - It should be sorted by AaBbCc then either None or empty if fine. I just want the first items to be aplhabetically orderd case insenstive.
from operator import itemgetter
list_of_list = [[0,1,2,3,'Ab'],[0,1,2,3,'bA'],[0,1,2,3,' '],[0,1,2,3,'None'], [0,1,2,3,''],[0,1,2,3,'Ca'] ]
list_of_list = sorted(list_of_list, key=itemgetter(4))
print list_of_list
Output: [[0, 1, 2, 3, ''], [0, 1, 2, 3, ' '], [0, 1, 2, 3, 'Ab'], [0, 1, 2, 3, 'Ca'], [0, 1, 2, 3, 'None'], [0, 1, 2, 3, 'bA']]
Should be outputed as such:
[[0, 1, 2, 3, 'Ab'], [0, 1, 2, 3, 'bA'],[0, 1, 2, 3, 'Ca'], [0, 1, 2, 3, 'None'], [0, 1, 2, 3, ''], [0, 1, 2, 3, ' ']]
You can try this:
>>> list_of_list = [[0, 1, 2, 3, 'Ab'],
[0, 1, 2, 3, 'bA'],
[0, 1, 2, 3, ' '],
[0, 1, 2, 3, None],
[0, 1, 2, 3, ''],
[0, 1, 2, 3, 'Ca']]
>>> list_of_list = sorted(list_of_list,
key=lambda x: x[4] if isinstance(x[4], basestring) else "",
reverse=True)
>>> print list_of_list
[[0, 1, 2, 3, 'bA'], [0, 1, 2, 3, 'Ca'], [0, 1, 2, 3, 'Ab'], [0, 1, 2, 3, ' '], [0, 1, 2, 3, None], [0, 1, 2, 3, '']]
What this does is use the fourth element as sort key if it is a string, else it will use the empty string as comparison key.
Alternately you could split your list in two lists, only sort the first one, and append the remaining elements like this:
list_of_list = sorted(x
for x in list_of_list
if isinstance(x[4], basestring) and len(x[4].strip())) + \
[x
for x in list_of_list
if not isinstance(x[4], basestring) or not len(x[4].strip())]
print list_of_list
yields
[[0, 1, 2, 3, 'Ab'], [0, 1, 2, 3, 'Ca'], [0, 1, 2, 3, 'bA'], [0, 1, 2, 3, ' '], [0, 1, 2, 3, None], [0, 1, 2, 3, '']]
It is not entirely clear if there are other sorting criteria that you need to follow, and this solution is not totally pretty, but at least it sorts the strings in front and keeps the rest at the back.