This question already has answers here:
Transpose list of lists
(14 answers)
Closed last year.
I have a numpy array like this:
array = [[1, 3, 5, 7], [2, 4, 6, 8]]
I would like to concatenate them element-wise. Most of the solutions I have found are able to do this with two separate 2d arrays, but I would like to do this within a single 2d array.
Desired output:
array = [[1, 2], [3, 4], [5, 6], [7, 8]]
Just only line code
array = [[1, 3, 5, 7], [2, 4, 6, 8]]
print(list(zip(*array)))
output :
[(1, 2), (3, 4), (5, 6), (7, 8)]
ljdyer is almost right, but you have only one array, so you can do this:
list(zip(*array))
This is a zip operation. Try:
arr1 = [1, 3, 5, 7]
arr2 = [2, 4, 6, 8]
print(list(zip(arr1,arr2)))
Output:
[(1, 2), (3, 4), (5, 6), (7, 8)]
Or for numpy arrays you have the stack operation:
import numpy as np
a = np.array([1, 3, 5, 7])
b = np.array([2, 4, 6, 8])
c = np.stack((a,b), axis = 1)
print(c)
See https://www.delftstack.com/howto/numpy/python-numpy-zip/
The following code will concatenate array element wise in each column
import numpy as np
array = np.array([[1, 3, 5, 7], [2, 4, 6, 8]])
res = []
for i in range(array.shape[1]):
res.append(array[:, i])
res = np.array(res)
print(res.tolist())
Numpy transpose:
In [382]: np.transpose([[1, 3, 5, 7], [2, 4, 6, 8]])
Out[382]:
array([[1, 2],
[3, 4],
[5, 6],
[7, 8]])
If it already is a numpy array (as opposed to just a list of lists),you can use the T shortcut:
In [383]: arr = np.array([[1, 3, 5, 7], [2, 4, 6, 8]])
In [384]: arr
Out[384]:
array([[1, 3, 5, 7],
[2, 4, 6, 8]])
In [385]: arr.T
Out[385]:
array([[1, 2],
[3, 4],
[5, 6],
[7, 8]])
list-zip is a well known list version of transpose:
In [386]: list(zip(*arr))
Out[386]: [(1, 2), (3, 4), (5, 6), (7, 8)]
Note the result is a list of tuples.
Related
I'm new to numpy, I don't understand how the following works:
np.array([range(i, i + 3) for i in [2, 4, 6]])
and the output is:
array([[2, 3, 4],[4, 5, 6],[6, 7, 8]])
Do you understand list comprehensions? range?
In [12]: [range(i, i + 3) for i in [2, 4, 6]]
Out[12]: [range(2, 5), range(4, 7), range(6, 9)]
np.array converts the range objects to lists, and then builds the array.
In [13]: [list(range(i, i + 3)) for i in [2, 4, 6]]
Out[13]: [[2, 3, 4], [4, 5, 6], [6, 7, 8]]
In [14]: np.array([list(range(i, i + 3)) for i in [2, 4, 6]])
Out[14]:
array([[2, 3, 4],
[4, 5, 6],
[6, 7, 8]])
So basically it's just a variation on the textbook example of making an array from a list of lists:
In [15]: np.array([[1,2,3],[10,11,12]])
Out[15]:
array([[ 1, 2, 3],
[10, 11, 12]])
So I have a Numpy Array with a bunch of numpy arrays inside of them. I want to group them based on the position in their individual array.
For Example:
If Matrix is:
[[1, 2], [2, 3], [4, 5], [6, 7]]
Then the code should return:
[[1, 2, 4, 6], [2, 3, 5, 7]]
This is becuase 1, 2, 4, 6 are all the first elements in their individual arrays, and 2, 3, 5, 7 are the second elements in their individual arrays.
Anyone know some function that could do this. Thanks.
Answer in Python.
Using numpy transpose should do the trick:
a = np.array([[1, 2], [2, 3], [4, 5], [6, 7]])
a_t = a.T
print(a_t)
array([[1, 2, 4, 6],
[2, 3, 5, 7]])
Your data as a list:
In [101]: alist = [[1, 2], [2, 3], [4, 5], [6, 7]]
In [102]: alist
Out[102]: [[1, 2], [2, 3], [4, 5], [6, 7]]
and as a numpy array:
In [103]: arr = np.array(alist)
In [104]: arr
Out[104]:
array([[1, 2],
[2, 3],
[4, 5],
[6, 7]])
A standard idiom for 'transposing' lists is:
In [105]: list(zip(*alist))
Out[105]: [(1, 2, 4, 6), (2, 3, 5, 7)]
with arrays, there's a transpose method:
In [106]: arr.transpose()
Out[106]:
array([[1, 2, 4, 6],
[2, 3, 5, 7]])
The first array is (4,2) shape; its transpose is (2,4).
I am trying to map 2 numpy arrays as [x, y] similar to what zip does for lists and tuples.
I have 2 numpy arrays as follows:
arr1 = [1, 2, 3, 4]
arr2 = [5, 6, 7, 8]
I am looking for an output as np.array([[[1, 5], [2, 6], [3, 7], [4, 8]]])
I tried this but it maps every value and not with same indices. I can add more if conditions here but is there any other way to do so without adding any more if conditions.
res = [arr1, arr2] for a1 in arr1 for a2 in arr2]
You are looking for np.dstack
Stack arrays in sequence depth wise (along third axis).
np.dstack([arr1, arr2])
array([[[1, 5],
[2, 6],
[3, 7],
[4, 8]]])
IIUC, one way is to use numpy.vstack() followed by transpose():
import numpy as np
arr1 = np.array([1, 2, 3, 4])
arr2 = np.array([5, 6, 7, 8])
print(np.vstack([arr1, arr2]).transpose())
#array([[1, 5],
# [2, 6],
# [3, 7],
# [4, 8]])
Or you could pass the output of zip to the array constructor:
print(np.array(zip(arr1, arr2)))
#array([[1, 5],
# [2, 6],
# [3, 7],
# [4, 8]])
The built in zip command is the job for you here. It'll do exactly what you're asking.
arr1 = [1,2,3,4]
arr2 = [5,6,7,8]
list(zip(arr1, arr2))
[(1, 5), (2, 6), (3, 7), (4, 8)]
https://docs.python.org/3/library/functions.html#zip
If I have a list of lists and want to find all the possible combination from each different indices, how could I do that?
For example:
list_of_lists = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
I want to find
all_possibility = [[1, 5, 9], [1, 8, 6], [4, 2, 9], [4, 8, 3], [7, 2, 6], [7, 5, 3]]
where
[1,5,9]: 1 is 1st element of [1, 2, 3], 5 is 2nd element of [4, 5, 6], 9 is 3rd element of [7, 8, 9].
[1,8,6]: 1 is 1st element of [1, 2, 3], 8 is 2nd element of [7, 8, 9], 6 is 3rd element of [4, 5, 6].
and so on.
(Edited) Note: I would like the result to be in the same order as the original element of the list. [1, 8, 6] but not [1, 6, 8] because 8 is the 2nd element of [7, 8, 9].
What you're looking for is the Cartesian product, in Python itertools.product:
>>> import itertools
>>> list_of_lists = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> all_possibility = list(itertools.product(*list_of_lists))
>>> print(all_possibility)
[(1, 4, 7), (1, 4, 8), (1, 4, 9), (1, 5, 7), (1, 5, 8), (1, 5, 9), (1, 6, 7), (1, 6, 8),
(1, 6, 9), (2, 4, 7), (2, 4, 8), (2, 4, 9), (2, 5, 7), (2, 5, 8), (2, 5, 9), (2, 6, 7),
(2, 6, 8), (2, 6, 9), (3, 4, 7), (3, 4, 8), (3, 4, 9), (3, 5, 7), (3, 5, 8), (3, 5, 9),
(3, 6, 7), (3, 6, 8), (3, 6, 9)]
If you want permutations based on the indices rather than the values, you can use itertools.combinations to get the possible indices, then use those indices to get the respective values from the sub-lists, like this:
>>> list_of_lists = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> length = 3
>>> all_indices = list(itertools.permutations(range(length), length))
>>> all_possibility = [[l[i] for l,i in zip(list_of_lists, indices)] for indices in all_indices]
>>> print(all_possibility)
[[1, 5, 9], [1, 6, 8], [2, 4, 9], [2, 6, 7], [3, 4, 8], [3, 5, 7]]
I have to consider the indices as well. For example, (1, 4, 7) is excluded because 1, and 4 both are the 1st element from the list of the lists (from [1, 2, 3] and [4, 5, 6]). And actually (1, 4, 7) all of them are from the first component of the nested list. I need the cases with all the different indices.
So you actually just want to get the possible permutations of a “list selector” for each index in the output, i.e. these are what you are trying to get:
>>> list(itertools.permutations(range(3), 3))
[(0, 1, 2), (0, 2, 1), (1, 0, 2), (1, 2, 0), (2, 0, 1), (2, 1, 0)]
And once you have that, you just need to translate into your list_of_lists where you access each index from the specified sublist:
>>> [[list_of_lists[k][i] for i, k in enumerate(comb)] for comb in itertools.permutations(range(3), 3)]
[[1, 5, 9], [1, 8, 6], [4, 2, 9], [4, 8, 3], [7, 2, 6], [7, 5, 3]]
In a spirit of #poke's approach, here is the cases for number of elements differ than the number of the list in the lists. (Previously, there are 3 elements in individual list where 3 sub-lists in the list).
list_of_lists = [[1, 2], [3, 4], [5, 6], [7, 8]]
We expect every (0, 1) pairs from the list of lists, or
all_possibility = [[1, 4], [1, 6], [1, 8], [3, 2], [3, 6], [3, 8], \
[5, 2], [5, 4], [5, 8], [7, 2], [7, 4], [7, 6]]
The code:
permutation_cases = list(itertools.permutations(range(2), 2))
select_from = list(itertools.combinations(range(len(list_of_lists)), 2))
all_possibility = []
for selecting_index in select_from:
selected = [list_of_lists[i] for i in selecting_index ]
cases = list([selected[k][i] for i, k in enumerate(comb)] for comb in permutation_cases)
for item in cases:
all_possibility.append(item)
print(all_possibility)
I have a fairly last list of data like this:
data = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
I'm trying to zip it so that that I get something like this:
zipped_data = [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
I know I could do that with
l = [(data[0]), (data[1]), (data[2])]
zipped_data = zip(*l)
But I would like to write a list comprehension to do that for any number of items in data. I tried this, but it didn't work.
s = [zip(i) for i in data]
s
[[(1,), (2,), (3,)], [(4,), (5,), (6,)], [(7,), (8,), (9,)]]
Can anyone identify where I've gone wrong here? Thanks.
Try the *:
In [2]: lis=[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
In [3]: zip(*lis)
Out[3]: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
If you really want to rewrite zip as a list comprehension, then this is how I would do it:
In [25]: data = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
In [26]: [tuple(lis[j] for lis in data) for j in range(min(len(l) for l in data))]
Out[26]: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
In [27]: data = [[1, 2, 3], [4, 5, 6], [7, 8]]
In [28]: [tuple(lis[j] for lis in data) for j in range(min(len(l) for l in data))]
Out[28]: [(1, 4, 7), (2, 5, 8)]
Though, zip(*data) is definitely a better way to go about this
I would do it with zip but here is done with list comprehension
def zip_lists(lists):
"""
Assuming all lists have the same length
>>> zip_lists([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
>>> zip_lists([[1, 2], [3, 4], [5, 6], [7, 8]])
[[1, 3, 5, 7], [2, 4, 6, 8]]
"""
return [[l[x] for l in lists] for x in range(len(lists[0]))]