How to get element to element power in two arrays in python? - python

I have two arrays with 3 elements in each.
reduction_combs = [2, 3, 7]
elements = [3,6,8]
Is there a shortway to compute new array which is :
c = [2**3 , 3**6, 7**8]

This can be achieved using a simple list comprehension.
[x ** y for (x, y) in zip(elements, reduction_combs)]

Yes, you can just do [x**y for (x,y) in zip(reduction_combs, elements)]

You can also use map with lambda expressions passing two lists:
c = list(map(lambda x,y: x**y, reduction_combs, elements))
Where x and y will be values from reduction_combs and elements, respectively.

In addition to the zip method, this is another way using enumerate and list comprehension. Here j is the element of reduction_combs and i is the corresponding index using which you fetch the power to be raised from elements
c = [j**elements[i] for i, j in enumerate(reduction_combs)]

Using numpy arrays:
import numpy as np
a = np.array([2, 3, 7])
b = np.array([3, 6, 8])
a ** b
# output: array([8, 729,5764801])

You can do this either using numpy:
import numpy
reduction_combs = numpy.array([2, 3, 7])
elements = numpy.array([3, 6, 8])
c = reduction_combs ** elements
or if you want to do it with plain python, you might want to consider list comprehension:
c = [reduction_combs[i] ** elements[i] for i in range(len(reduction_combs))]
You should learn a bit more about what lists do in python and if you often work with arrays, get used to work with numpy!

If you like functional style as an alternative to the excellent list comprehension proposed by tda, here's a solution with operator.pow and itertools.starmap.
>>> from operator import pow
>>> from itertools import starmap
>>> list(starmap(pow, zip(reduction_combs, elements)))
[8, 729, 5764801]
In addition, since you tagged numpy, leveraging element-wise vectorized operations makes for a very straight forward solution.
>>> import numpy as np
>>> r = np.array(reduction_combs)
>>> e = np.array(elements)
>>>
>>> r**e
array([ 8, 729, 5764801])

You could use the numpy power function:
import numpy as np
reduction_combs = [2, 3, 7]
elements = [3, 6, 8]
print(np.power(reduction_combs, elements))
Output
[ 8 729 5764801]
If you want the output as a list simply do:
np.power(reduction_combs, elements).tolist()

One of the quick solution would be:
c = [a**b for a,b in zip(reduction_combs, elements)]
You can also try using numpy as below:
import numpy as np
c = np.power(reduction_combs, elements)

Using enumerate and pow
c = [pow(v, elements[i]) for i, v in enumerate(reduction_combs)]

Related

Array Prints like List but its a single integer in variable explorer? Why?

When ı print out the following code Q is prints like it suppose to be (3 5 7 9) sum of the numbers with the next one. but in the variable explorer its a single integer ı want to get the result Q as an array like
Q = [3, 5, 7, 9]
import numpy as np
A = [1, 2, 3, 4, 5]
for i in range(0,4):
Q = np.array(A[i]+A[i+1])
print(Q)
for i in range(0,4):
Q = []
Q.append(Q[i] + A[i]+A[i+1])
print(Q)
This also doesnt work
Currently you're just re-declaring Q each time and it's never added to some collection of values
Instead, start with an empty list (or perhaps a numpy array in your case) and outside of your loop and append the values to it at each loop cycle
Q is a numpy array, but it's not what you're expecting!
It has no dimensions and only references a single value
>>> type(Q)
<class 'numpy.ndarray'>
>>> print(repr(Q))
array(9)
>>> import numpy as np
>>> A = [1, 2, 3, 4, 5]
>>> Q = np.array([], dtype=np.uint8)
>>> for i in range(4):
... Q = np.append(Q, A[i]+A[i+1]) # reassign each time for np
...
>>> print(Q)
[3 5 7 9]
Note that numpy arrays should be reassigned via np.append, while a normal python list has a .append() method (which does not return the list, but directly appends to it)
>>> l = ['a', 'b', 'c'] # start with a list of values
>>> l.append('d') # use the append method
>>> l # display resulting list
['a', 'b', 'c', 'd']
If you're not forced to use a numpy array to begin with, this can be done with a list comprehension
The resulting list can also be made into a numpy array afterwards
>>> [(x + x + 1) for x in range(1, 5)]
[3, 5, 7, 9]
All together with simplified math
>>> np.array([x*2+3 for x in range(4)])
array([3, 5, 7, 9])
If you want to use Numpy, then use Numpy. Start with a Numpy array (one-dimensional, containing the values), which looks like this:
A = np.array([1, 2, 3, 4, 5])
(Yes, you initialize it from the list).
Or you can create that kind of patterned data using Numpy's built-in tool:
A = np.arange(1, 6) # it works similarly to the built-in `range` type,
# but it does create an actual array.
Now we can get the values to use on the left-hand and right-hand sides of the addition:
# You can slice one-dimensional Numpy arrays just like you would lists.
# With more dimensions, you can slice in each dimension.
X = A[:-1]
Y = A[1:]
And add the values together element-wise:
Q = X + Y # yes, really that simple!
And that last line is the reason you would use Numpy to solve a problem like this. Otherwise, just use a list comprehension:
A = list(range(1, 6)) # same as [1, 2, 3, 4, 5]
# Same slicing, but now we have to do more work for the addition,
# by explaining the process of pairing up the elements.
Q = [x + y for x, y in zip(A[:-1], A[1:])]

need to grab entire first element (array) in a multi-dimentional list of arrays python3

Apologies if this has already been asked, but I searched quite a bit and couldn't find quite the right solution. I'm new to python, but I'll try to be as clear as possible. In short, I have a list of arrays in the following format resulting from a joining a multiprocessing pool:
array = [[[1,2,3], 5, 47, 2515],..... [[4,5,6], 3, 35, 2096]]]
and I want to get all values from the first array element to form a new array in the following form:
print(new_array)
[1,2,3,4,5,6]
In my code, I was trying to get the first value through this function:
new_array = array[0][0]
but this only returns the first value as such:
print(new_array)
[1,2,3]
I also tried np.take after converting the array into a np array:
array = np.array(array)
new_array = np.take(results,0)
print(new_array)
[1,2,3]
I have tried a number of np functions (concatenate, take, etc.) to try and iterate this over the list, but get back the following error (presumably because the size of the array changes):
ValueError: autodetected range of [[], [1445.0, 1445.0, -248.0, 638.0, -108.0, 649.0]] is not finite
Thanks for any help!
You can achieve it without numpy using reduce:
from functools import reduce
l = [[[1,2,3], 5, 47, 2515], [[4,5,6], 3, 35, 2096]]
res = reduce(lambda a, b: [*a, *b], [x[0] for x in l])
Output
[1, 2, 3, 4, 5, 6]
Maybe it is worth mentioning that [*a, *b] is a way to concatenate lists in python, for example:
[*[1, 2, 3], *[4, 5, 6]] # [1, 2, 3, 4, 5, 6]
You could also use itertools' chain() function to flatten an extraction of the first subArray in each element of the list:
from itertools import chain
result = list(chain(*[sub[0] for sub in array]))

calculations using both a value from a list and the index of that value?

I need to perform a calculation on a list using both the values of that list, and the index of those values, eg:
a = [1,2,3,4,5]
b= a[1]*1
but for all values of a, to get:
b = [1,4,9,16,25]
Is this possible to do without a for loop? I could put it in one, but it would change the structure of my code for the worse. This is meant to be used by a wide variety of users with varying skill levels, so I'm willing to sacrifice speed for ease of readability.
You can use list comprehension and enumerate() function, that provides the index as well as value of the element, simultaneously. Example -
b = [elem * (i+1) for i, elem in enumerate(a)]
Demo -
>>> a = [1,2,3,4,5]
>>> b = [elem * (i+1) for i, elem in enumerate(a)]
>>> b
[1, 4, 9, 16, 25]
If its fine to use numpy library , most probably a faster solution would be to use numpy's vectorised multiplication . Example -
In [1]: import numpy as np
In [2]: a = [1,2,3,4,5]
In [3]: a_arr = np.array(a)
In [4]: b = a_arr * np.arange(1,a_arr.shape[0]+1)
In [5]: b
Out[5]: array([ 1, 4, 9, 16, 25])
Though numpy method may be a bit more complex to understand that the list comprehension.
I recommend you to use map built-in function and let your code be simpler.
a = [1,2,3,4,5]
b = map(lambda x: x*x, a)
print b
# [1, 4, 9, 16, 25]
If you want to dynamically enter your list, you would use range built-in function (It's available for python2):
b = map(lambda x: x*x, range(1,6))
print b
# [1, 4, 9, 16, 25]

Python -Intersection of multiple lists?

I am playing with python and am able to get the intersection of two lists:
result = set(a).intersection(b)
Now if d is a list containing a and b and a third element c, is there an built-in function for finding the intersection of all the three lists inside d? So for instance,
d = [[1,2,3,4], [2,3,4], [3,4,5,6,7]]
then the result should be
[3,4]
set.intersection(*map(set,d))
for 2.4, you can just define an intersection function.
def intersect(*d):
sets = iter(map(set, d))
result = sets.next()
for s in sets:
result = result.intersection(s)
return result
for newer versions of python:
the intersection method takes an arbitrary amount of arguments
result = set(d[0]).intersection(*d[1:])
alternatively, you can intersect the first set with itself to avoid slicing the list and making a copy:
result = set(d[0]).intersection(*d)
I'm not really sure which would be more efficient and have a feeling that it would depend on the size of the d[0] and the size of the list unless python has an inbuilt check for it like
if s1 is s2:
return s1
in the intersection method.
>>> d = [[1,2,3,4], [2,3,4], [3,4,5,6,7]]
>>> set(d[0]).intersection(*d)
set([3, 4])
>>> set(d[0]).intersection(*d[1:])
set([3, 4])
>>>
You can get the intersection of an arbitrary number sets using set.intersection(set1, set2, set3...). So you just need to convert your lists into sets and then pass them to this method as follows:
d = [[1,2,3,4], [2,3,4], [3,4,5,6,7]]
set.intersection(*[set(x) for x in d])
result:
{3, 4}
#user3917838
Nice and simple but needs some casting to make it work and give a list as a result. It should look like:
list(reduce(set.intersection, [set(item) for item in d ]))
where:
d = [[1,2,3,4], [2,3,4], [3,4,5,6,7]]
And result is:
[3, 4]
At least in Python 3.4
Lambda reduce.
from functools import reduce #you won't need this in Python 2
l=[[1, 2, 3, 4], [2, 3, 4], [3, 4, 5, 6, 7]]
reduce(set.intersection, [set(l_) for l_ in l])
I find reduce() to be particularly useful. In fact, the numpy documents recommend using reduce() to intersect multiple lists: numpy.intersect1d reference
To answer your question:
import numpy as np
from functools import reduce
# apply intersect1d to (a list of) multiple lists:
reduce(np.intersect1d, [list_1, list_2, ... list_n])

Concise vector adding in Python? [duplicate]

This question already has answers here:
Element-wise addition of 2 lists?
(17 answers)
Closed 5 years ago.
I often do vector addition of Python lists.
Example: I have two lists like these:
a = [0.0, 1.0, 2.0]
b = [3.0, 4.0, 5.0]
I now want to add b to a to get the result a = [3.0, 5.0, 7.0].
Usually I end up doing like this:
a[0] += b[0]
a[1] += b[1]
a[2] += b[2]
Is there some efficient, standard way to do this with less typing?
UPDATE: It can be assumed that the lists are of length 3 and contain floats.
If you need efficient vector arithmetic, try Numpy.
>>> import numpy
>>> a=numpy.array([0,1,2])
>>> b=numpy.array([3,4,5])
>>> a+b
array([3, 5, 7])
>>>
Or (thanks, Andrew Jaffe),
>>> a += b
>>> a
array([3, 5, 7])
>>>
I don't think you will find a faster solution than the 3 sums proposed in the question. The advantages of numpy are visible with larger vectors, and also if you need other operators. numpy is specially useful with matrixes, witch are trick to do with python lists.
Still, yet another way to do it :D
In [1]: a = [1,2,3]
In [2]: b = [2,3,4]
In [3]: map(sum, zip(a,b))
Out[3]: [3, 5, 7]
Edit: you can also use the izip from itertools, a generator version of zip
In [5]: from itertools import izip
In [6]: map(sum, izip(a,b))
Out[6]: [3, 5, 7]
While Numeric is excellent, and list-comprehension solutions OK if you actually wanted to create a new list, I'm surprised nobody suggested the "one obvious way to do it" -- a simple for loop! Best:
for i, bi in enumerate(b): a[i] += bi
Also OK, kinda sorta:
for i in xrange(len(a)): a[i] += b[i]
If you think Numpy is overkill, this should be really fast, because this code runs in pure C (map() and __add__() are both directly implemented in C):
a = [1.0,2.0,3.0]
b = [4.0,5.0,6.0]
c = map(float.__add__, a, b)
Or alternatively, if you don't know the types in the list:
import operator
c = map(operator.add, a, b)
How about this:
a = [x+y for x,y in zip(a,b)]
Or, if you're willing to use an external library (and fixed-length arrays), use numpy, which has "+=" and related operations for in-place operations.
import numpy as np
a = np.array([0, 1, 2])
b = np.array([3, 4, 5])
a += b
[a[x] + b[x] for x in range(0,len(a))]
For the general case of having a list of lists you could do something like this:
In [2]: import numpy as np
In [3]: a = np.array([[1, 1, 1], [2, 2, 2], [3, 3, 3],[4, 5, 6]])
In [4]: [sum(a[:,i]) for i in xrange(len(a[0]))]
Out[4]: [10, 11, 12]
If you're after concise, try...
vectors = [[0.0, 1.0, 2.0],[3.0, 4.0, 5.0]]
[sum(col) for col in zip(*vectors)]
Though I can't speak for the performance of this.
list(map(lambda x:x[0]+x[1], zip(a,b)))
a = map(lambda x, y: x + y, a, b)
You could create a function that gets the size of the array, loops through it and creating a return array which it returns.
An improvement (less memory consumption) of the comprehension list
import itertools
a = [x+y for x,y in itertools.izip(a,b)]
Actually if you are not sure that a will be consume then I would even go with generator expression:
(x+y for x,y in itertools.izip(a,b))

Categories