Adding value to array - python

I want to add values from one array to another array after making some calculation, here I did it using for loop but I want efficient way doing so. Please help me.. thanx
from numpy import *
arr = array([1,2,3,4,5])
arr1 = []
for i in arr:
arr1.append(i+5)
print(arr1)
nArray = array(arr1)
print(nArray)
Output :
[6, 7, 8, 9, 10]
[ 6 7 8 9 10]

You should have just done:
nArray = arr + 5

You could use the map builtin function from Python, it takes a function and an iterable as input and returns something that you can give to the list function, so for instance:
list(map(lambda x: x + 5, arr))
But this would be for python built-in list
Since you are using numpy however, you can just add 5 to the numpy array as arr1 = arr + 5 as suggested by fountainhead

Related

How can I build a complementary array in numpy

I have an array of numbers corresponding to indices of another array.
index_array = np.array([2, 3, 5])
What I want to do is to create another array with the numbers 0, 1, 4, 6, 7, 8, 9. What I have thought is:
index_list = []
for i in range(10):
if i not in index_array:
index_list.append(i)
This works but I don't know if there is a more efficient way to do it or even a built-in function for it.
Probably the simplest solution is just to remove unwanted indices from the set:
n = 10
index_array = [2, 3, 5]
complement = np.delete(np.arange(n), index_array)
You can use numpy.setdiff1d to efficiently collect the unique value from a "universal array" that aren't in your index array. Passing assume_unique=True provides a small speed up.
When assume_unique is True, the result will be sorted so long as the input is sorted.
import numpy as np
# "Universal set" to take complement with respect to.
universe = np.arange(10)
a = np.array([2,3,5])
complement = np.setdiff1d(universe, a, assume_unique=True)
print(complement)
Results in
[0 1 4 6 7 8 9]

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:])]

Numpy array with values that update

Is it possible to create a automatically updating Numpy array?
For example:
a = numpy.array([1,2,3,4])
b = numpy.array([a[0]+1,a[1]+2,a[2]+3,a[3]+4])
a[0] = 5
Output:
>>>print(b)
>>>[6, 4, 6, 8]
Not if the array elements are stored by value. However numpy supports arrays of objects, so you could store lamdas or something and achieve something similar...although it's probably not what you want.
Ex:
a = np.array([1])
b = np.array([ lambda: a[0] + 1 ])
a[0] = 5
print (b[0]())
# 6

How to get element to element power in two arrays in 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)]

Replace multiple elements in numpy array with 1

In a given numpy array X:
X = array([1,2,3,4,5,6,7,8,9,10])
I would like to replace indices (2, 3) and (7, 8) with a single element -1 respectively, like:
X = array([1,2,-1,5,6,7,-1,10])
In other words, I replaced values at indices (2, 3) and (7,8) of the original array with a singular value.
Question is: Is there a numpy-ish way (i.e. without for loops and usage of python lists) around it? Thanks.
Note: This is NOT equivalent of replacing a single element in-place with another. Its about replacing multiple values with a "singular" value. Thanks.
A solution using numpy.delete, similar to #pault, but more efficient as it uses pure numpy indexing. However, because of this efficient indexing, it means that you cannot pass jagged arrays as indices
Setup
a = np.array([1,2,3,4,5,6,7,8,9,10])
idx = np.stack([[2, 3], [7, 8]])
a[idx] = -1
np.delete(a, idx[:, 1:])
array([ 1, 2, -1, 5, 6, 7, -1, 10])
I'm not sure if this can be done in one step, but here's a way using np.delete:
import numpy as np
from operator import itemgetter
X = np.array(range(1,11))
to_replace = [[2,3], [7,8]]
X[list(map(itemgetter(0), to_replace))] = -1
X = np.delete(X, list(map(lambda x: x[1:], to_replace)))
print(X)
#[ 1 2 -1 5 6 7 -1 10]
First we replace the first element of each pair with -1. Then we delete the remaining elements.
Try np.put:
np.put(X, [2,3,7,8], [-1,0]) # `0` can be changed to anything that's not in the array
print(X[X!=0]) # whatever You put as an number in `put`
So basically use put to do the values for the indexes, then drop the zero-values.
Or as #khan says, can do something that's out of range:
np.put(X, [2,3,7,8], [-1,np.max(X)+1])
print(X[X!=X.max()])
All Output:
[ 1 2 -1 5 6 7 -1 10]

Categories