I have three lists that contain x,y and z positions. For example:
x = [10,20,1]
y = [10,15,2]
z = [12,23,3]
I want to create a list using these that looks like:
xyz = [[10,10,12], [20,15,23], [1,2,3]]
These lists are huge (1 million entries).
What is a good way to do this?
Thanks!
You're looking for the zip builtin function:
>>> x = [10,20,1]
>>> y = [10,15,2]
>>> z = [12,23,3]
>>> zip(x, y, z)
[(10, 10, 12), (20, 15, 23), (1, 2, 3)]
This produces a list of tuples. If you absolutely need a list of lists, coerce those tuples manually:
>>> [list(t) for t in zip(x, y, z)]
[[10, 10, 12], [20, 15, 23], [1, 2, 3]]
Note that in Python 3, zip returns a lazy iterator instead of a list (the same as itertools.izip in Python 2). If your lists are that big, that may actually be preferable, but remember that iterators aren't subscriptable.
For Python 2.x you can use izip:
from itertools import izip
for a,b,c in izip(x,y,z):
# do something
This iterates across the lists instead of copying their data.
This is a manual way of doing it (if you're interested):
>>> xyz = []
>>> x = [10, 20, 1]
>>> y = [10, 15, 2]
>>> z = [12, 23, 3]
>>>
>>> for num in range(3): #Change 3 to however many numbers u want
... xyz.append([x[num], y[num], z[num]])
...
>>> print xyz
[[10, 10, 12], [20, 15, 23], [1, 2, 3]]
Hope this helps!
Related
I would like to return the duplicates in two different 2d lists. But I'm having trouble figuring out what code to write. For example I would like variable "a" to compare to variable "b" and return the duplicates. Here are my two 2d list below.
a = [[2,3,6,8],[4,5,7,8,10],[15,17,21,22],[12,13,14,23,25]]
b = [[4,5,6],[15,17,21,22],[2,3,4],[2,3,6,8],[5,7,8,12,15],[7,12,14,17,32],[5,6,7,12,14]]
I would like my results to be:
c = [[2,3,6,8],[15,17,21,22]]
You just need to check if a list in a is also in b or not.
a = [[2,3,6,8],[4,5,7,8,10],[15,17,21,22],[12,13,14,23,25]]
b = [[4,5,6],[15,17,21,22],[2,3,4],[2,3,6,8],[5,7,8,12,15],[7,12,14,17,32],[5,6,7,12,14]]
c=[]
for i in a:
if i in b:
c.append(i)
print(c)
Output:
[[2, 3, 6, 8], [15, 17, 21, 22]]
This should work, it should get you started -
import itertools
#Input lists
a = [[2,3,6,8],[4,5,7,8,10],[15,17,21,22],[12,13,14,23,25]]
b = [[4,5,6],[15,17,21,22],[2,3,4],[2,3,6,8],[5,7,8,12,15],[7,12,14,17,32],[5,6,7,12,14]]
#Take a product of both the lists ( a X b )
z = itertools.product(a,b)
#Uncomment the following to see what itertools.product does
#[i for i in z]
#Return only the elements which the pair of the same element repeats (using string match)
[i[0] for i in z if str(i[0])==str(i[1])]
[[2, 3, 6, 8], [15, 17, 21, 22]]
one liner list comprehension approach:
dups = [i for i in a if i in b]
output:
[[2, 3, 6, 8], [15, 17, 21, 22]]
Try this:
a = [[2,3,6,8],[4,5,7,8,10],[15,17,21,22],[12,13,14,23,25]]
b = [[4,5,6],[15,17,21,22],[2,3,4],[2,3,6,8],[5,7,8,12,15],[7,12,14,17,32],[5,6,7,12,14]]
c = []
for i in a + b:
if (a + b).count(i) > 1 and i not in c:
c.append(i)
#mulaixi's answer is OK but in output list you may see duplicates.
I currently have two arrays, one of which has several repeated values and another with unique values.
Eg array 1 : a = [1, 1, 2, 2, 3, 3]
Eg array 2 : b = [10, 11, 12, 13, 14, 15]
I was developing a code in python that looks at the first array and distinguishes the elements that are all the same and remembers the indices. A new array is created that contains the elements of array b at those indices.
Eg: As array 'a' has three unique values at positions 1,2... 3,4... 5,6, then three new arrays would be created such that it contains the elements of array b at positions 1,2... 3,4... 5,6. Thus, the result would be three new arrays:
b1 = [10, 11]
b2 = [12, 13]
b3 = [14, 15]
I have managed to develop a code, however, it only works for when there are three unique values in array 'a'. In the case there are more or less unique values in array 'a', the code has to be physically modified.
import itertools
import numpy as np
import matplotlib.tri as tri
import sys
a = [1, 1, 2, 2, 3, 3]
b = [10, 10, 20, 20, 30, 30]
b_1 = []
b_2 = []
b_3 = []
unique = []
for vals in a:
if vals not in unique:
unique.append(vals)
if len(unique) != 3:
sys.exit("More than 3 'a' values - check dimension")
for j in range(0,len(a)):
if a[j] == unique[0]:
b_1.append(c[j])
elif a[j] == unique[1]:
b_2.append(c[j])
elif a[j] == unique[2]:
b_3.append(c[j])
else:
sys.exit("More than 3 'a' values - check dimension")
print (b_1)
print (b_2)
print (b_3)
I was wondering if there is perhaps a more elegant way to perform this task such that the code is able to cope with an n number of unique values.
Well given that you are also using numpy, here's one way using np.unique. You can set return_index=True to get the indices of the unique values, and use them to split the array b with np.split:
a = np.array([1, 1, 2, 2, 3, 3])
b = np.array([10, 11, 12, 13, 14, 15])
u, s = np.unique(a, return_index=True)
np.split(b,s[1:])
Output
[array([10, 11]), array([12, 13]), array([14, 15])]
You can use the function groupby():
from itertools import groupby
from operator import itemgetter
a = [1, 1, 2, 2, 3, 3]
b = [10, 11, 12, 13, 14, 15]
[[i[1] for i in g] for _, g in groupby(zip(a, b), key=itemgetter(0))]
# [[10, 11], [12, 13], [14, 15]]
Given a list containing monthly numerical data, how can I easily convert this into quarterly data?
x= [5,8,3,4,5,6,1,2,5,3,11,8] #monthly data for Jan-Dec
Desired output:
[5+8+3, 4+5+6, 1+2+5, 3+11+8] #converted to quarterly data
I wanted to do something like [a+b+c for a,b,c in x] but x it says x is not iterable.
I don't think this is a duplicate. I am specifically looking for a list comprehension solution.
A list comprehension way:
[sum([x[i],x[i+1],x[i+2]]) for i in range(0,len(x),3)]
#[16, 15, 8, 22]
Or in a nicer way (thanks #JonClements):
[sum(x[i:i+3]) for i in range(0, len(x), 3)]
And a numpy way:
import numpy as np
np.sum(np.array(x).reshape(-1,3),axis=1)
#array([16, 15, 8, 22])
Not getting to crazy you could just slice them up and then work with each group
x= [5,8,3,4,5,6,1,2,5,3,11,8]
a, b, c, d = x[:3], x[3:6], x[6:9], x[9:12]
print(a, b, c, d)
(xenial)vash#localhost:~/python/stack_overflow$ python3.7 slice_q.py
[5, 8, 3] [4, 5, 6] [1, 2, 5] [3, 11, 8]
From here if you want to sum each group you could do something like this
lista = [a, b, c, d,]
for i in lista:
print(sum(i))
16
15
8
22
I have a function foo that returns an array with the shape (1000, 2)
how can I split it to two arrays a(1000) and b(1000)
I'm looking for something like this:
a;b = foo()
I'm looking for an answer that can easily generalize to the case in which the shape is (1000, 5) or so.
The zip(*...) idiom transposes a traditional more-dimensional Python list:
x = [[1,2], [3,4], [5,6]]
# get columns
a, b = zip(*x) # zip(*foo())
# a, b = map(list, zip(*x)) # if you prefer lists over tuples
a
# (1, 3, 5)
# get rows
a, b, c = x
a
# [1, 2]
Transpose and unpack?
a, b = foo().T
>>> a, b = np.arange(20).reshape(-1, 2).T
>>> a
array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18])
>>> b
array([ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19])
You can use numpy.hsplit.
x = np.arange(12).reshape((3, 4))
np.hsplit(x, x.shape[1])
This returns a list of subarrays. Note that in the case of a 2d input, the subarrays will be shape (n, 1). Unless you wrap a function around it to squeeze them to 1d:
def split_1d(arr_2d):
"""Split 2d NumPy array on its columns."""
split = np.hsplit(arr_2d, arr_2d.shape[1])
split = [np.squeeze(arr) for arr in split]
return split
a, b, c, d = split_1d(x)
a
# array([0, 4, 8])
d
# array([ 3, 7, 11])
You could just use list comprehensions, e.g.
(a,b)=([i[0] for i in mylist],[i[1] for i in mylist])
To generalise you could use a comprehension within a comprehension:
(a,b,c,d,e)=([row[i] for row in mylist] for i in range(5))
You can do this simply by using zip function like:
def foo(mylist):
return zip(*mylist)
Now call foo with as much dimension as you have in mylist, and it would do the requisite like:
mylist = [[1, 2], [3, 4], [5, 6]]
a, b = foo(mylist)
# a = (1, 3, 5)
# b = (2, 4, 6)
So this is a little nuts, but if you want to assign different letters to each sub-array in your array, and do so for any number of sub-arrays (up to 26 because alphabet), you could do:
import string
letters = list(string.ascii_lowercase) # get all of the lower-case letters
arr_dict = {k: v for k, v in zip(letters, foo())}
or more simply (for the last line):
arr_dict = dict(zip(letters, foo()))
Then you can access each individual element as arr_dict['a'] or arr_dict['b']. This feels a little mad-scientist-ey to me, but I thought it was fun.
Let's say I have:
a = [10,14,16]
b = [0,1,2]
and I want combine a and b into one list, as shown below:
print c
[[10, 0], [14, 1], [16, 2]]
I have tried to merge the two lists:
a + b
[10, 14, 16, 0, 1, 2]
but it's not same as what I want to achieve.
How can I do that in Python?
This is what zip() is for:
>>> a = [10,14,16]
>>> b = [0,1,2]
>>> zip(a, b)
[(10, 0), (14, 1), (16, 2)]
Note that this would get you a list of tuples. In case you want a list of lists:
>>> [list(item) for item in zip(a, b)]
[[10, 0], [14, 1], [16, 2]]
You could use zip built in function. It's very efficient compared to manual implementation.
In [52]: c = list(zip(a,b))
In [53]: c
Out[53]: [(10, 0), (14, 1), (16, 2)]
a = [10,14,16]
b = [0,1,2]
c = []
for i in range(len(a)):
c.append([a[i], b[i]])
print c
Or in one line:
print [[a[i], b[i]] for i in range(len(a))]
Outputs:
[[10, 0], [14, 1], [16, 2]]
using a simple for loop?
a = [10,14,16]
b = [0,1,2]
c = []
for i in range(len(a)):
try:
c.append([a[i],b[i]])
except KeyError:
c.append([a[i]])
print c
or by using a generator:
c = [ [a[i],b[i]] for i in range(len(a))]
for small lists you can do a "for" loop:
a = [10,14,16]
b = [0,1,2]
for i in range(len(a)):
out[i] = [a[i],b[i]]
Or for longer list you can use pandas to create a dataframe:
import pandas as pd
df = pd.dataframe([a,b],columns = ['a','b'])
out = df.T.values.tolist()
import numpy as np
np.array(a+b).reshape(2,3).T.tolist()