Related
I have some data array
a = [6,4,3,1,5]
and a "to location array", that gives indices for how these elements should be reshuffled,
b = [4,2,0,1,3]
What this means: the 1st element of a should go to index 4, the 2nd element of a should go to index 2, and so on. So when applying b to a, I should get:
c = [3,1,4,5,6]
However, I am struggling to implement this operation. Is it a common operation? If so, could someone give me an example? I want to generate some array d from b so that
c = a[d]
In the above example,
d = [2,3,1,4,0]
What I tried: d = b[b], but this is not always correct.
If you don't need d, you can directly get c with np.put_along_axis:
>>> a = np.array([6,4,3,1,5])
>>> b = np.array([4,2,0,1,3])
>>> c = np.zeros_like(b)
>>> np.put_along_axis(c, b, a, 0)
>>> c
array([3, 1, 4, 5, 6])
Note the operation is inplace.
One method I just found is calculating d is as follows:
d = np.zeros(5);
d[b] = np.arange(5)
But it seems very non-intuitive to me.
This question already has answers here:
Numpy sum elements in array based on its value
(2 answers)
Closed 4 years ago.
Maybe has been asked before, but I can't find it.
Sometimes I have an index I, and I want to add successively accordingly to this index to an numpy array, from another array. For example:
A = np.array([1,2,3])
B = np.array([10,20,30])
I = np.array([0,1,1])
for i in range(len(I)):
A[I[i]] += B[i]
print(A)
prints the expected (correct) value:
[11 52 3]
while
A[I] += B
print(A)
results in the expected (wrong) answer
[11 32 3].
Is there any way to do what I want in a vectorized way, without the loop?
If not, which is the fastest way to do this?
Use numpy.add.at:
>>> import numpy as np
>>> A = np.array([1,2,3])
>>> B = np.array([10,20,30])
>>> I = np.array([0,1,1])
>>>
>>> np.add.at(A, I, B)
>>> A
array([11, 52, 3])
Alternatively, np.bincount:
>>> A = np.array([1,2,3])
>>> B = np.array([10,20,30])
>>> I = np.array([0,1,1])
>>>
>>> A += np.bincount(I, B, minlength=A.size).astype(int)
>>> A
array([11, 52, 3])
Which is faster?
Depends. In this concrete example add.at seems marginally faster, presumably because we need to convert types in the bincount solution.
If OTOH A and B were float dtype then bincount would be faster.
You need to use np.add.at:
A = np.array([1,2,3])
B = np.array([10,20,30])
I = np.array([0,1,1])
np.add.at(A, I, B)
print(A)
prints
array([11, 52, 3])
This is noted in the doc:
ufunc.at(a, indices, b=None)
Performs unbuffered in place operation on operand ‘a’ for elements specified by ‘indices’. For addition ufunc, this method is equivalent to a[indices] += b, except that results are accumulated for elements that are indexed more than once. For example, a[[0,0]] += 1 will only increment the first element once because of buffering, whereas add.at(a, [0,0], 1) will increment the first element twice.
Is there anyway to sum two points not using "class point"
Input
a= (2,5)
b= (3,4)
c= a +b
Output
(5 , 9)
You can use a comprehension plus zip:
c = tuple(a_n + b_n for a_n, b_n in zip(a, b))
This is obviously cumbersome if you need to do it a lot (not to mention slightly inefficient). If you are going to be doing this sort of computation a lot, then you're better off using a library like numpy which allows arrays to be added as first-class objects.
import numpy as np
a = np.array([2, 5])
b = np.array([3, 4])
c = a + b
If you go the numpy route, converting to and from numpy arrays is a bit expensive so I'd recommend that you store your points as arrays rather than tuple.
If you'd like a functional approach:
t = tuple(map(sum, zip(a, b)))
import numpy
a = (2,5)
b = (3,4)
c = tuple(numpy.asarray(a) + numpy.asarray(b)) #Tuple convert is just because this is how your output defined. you can skip it...
Complex numbers are (2-)tuples in disguise:
>>> a = 2+5j
>>> b = 3+4j
>>> c = a + b
>>> c
(5+9j)
My solution:
reduce(lambda x, y: (x[0] + y[0], x[1] + y[1]), zip(a, b))
I have some data looks like in this format
2,3,4
3,4,5
5,6,7
I pack the array as:
with open('house_price_data.txt') as data:
substrings = data.read().split()
array = [map(int, substring.split(',')) for substring in substrings]
My task is to do some calculation like this for each data in the set:
(2-3)**2 + (3-3)**2 + (5-3)**2
(3-4)**2 + (4-4)**2 + (5-4)**2
My expected answer is C1 = 5 and C2 = 2
I wrote a code like this
for [a for a, b, c in array] in range (0,2):
C1 = (([a for a, b, c in array]) - 3)**2
C2 = (([b for a, b, c in array]) - 4)**2
But it is not working. For the purpose of for loop, I think it will read the data 2,3,5 one by one minus 3 and square the result one by one and sum the total results. So how can I improve it?
A part from that, I also have problems with this code
[a for a, b, c in array]
[b for a, b, c in array]
[c for a, b, c in array]
I need to call array many times with this code with item a, b and c of the array in the program, when I have such codes in the program error massage come
not enough values to unpack (expected 3, got 0)
How can I do to make changes?
This question is unclear and probably destined for oblivion, but if I understand correctly, which is far from certain, you are trying to do something like this.
array = [[2, 3, 5], [3, 4, 5], [5, 6, 7]]
#initialize the variables C1 and C2
C1 = 0
C2 = 0
#iterate the elements of the FIRST list in your list
#so 2,3,5 (I assume you have indicated 2,3,4 by mistake)
for element in array[0]:
C1+=(element-3)**2
#iterate the elements of the SECOND list in your list
#so 3,4,5
for element in array[1]:
C2+=(element-4)**2
print("C1 =", C1)
print("C2 =", C2)
Output:
C1 = 5
C2 = 2
But your example is ambiguous. Maybe 2,3,5 are the first elements in each sublist ? In this case, the logic is the same.
#iterate the FIRST element in each sublist in your list
for element in array:
C1+=(element[0]-3)**2
If that's what you want to do, then it's best for you to do it like that, with classic loops. List comprehensions (things like [x for x in array if ...]) are shortcuts for advanced Python programmers. They do exactly the same thing, but are less clear and more error prone.
If you have array = [[2,3,4],[3,4,5],[5,6,7]], then you want a = [2,3,5], then that would be
a = [x[0] for x in array]
Otherwise, array[0] is [2,3,4] and you can instead do
a, b, c = array
To unpack the 2D array.
Sidenote: you seem to have a CSV file, so I would strongly suggest using Pandas and Numpy for your numerical calculations
I have a question based an how to "call" a specific cell in an array, while looping over another array.
Assume, there is an array a:
a = [[a1 a2 a3],[b1 b2 b3]]
and an array b:
b = [[c1 c2] , [d1 d2]]
Now, I want to recalculate the values in array b, by using the information from array a. In detail, each value of array b has to be recalculated by multiplication with the integral of the gauss-function between the borders given in array a. but for the sake of simplicity, lets forget about the integral, and assume a simple calculation is necessary in the form of:
c1 = c1 * (a2-a1) ; c2 = c2 * (a3 - a2) and so on,
with indices it might look like:
b[i,j] = b[i,j] * (a[i, j+1] - a[i,j])
Can anybody tell me how to solve this problem?
Thank you very much and best regards,
Marc
You can use zip function within a nested list comprehension :
>>> [[k*(v[1]-v[0]) for k,v in zip(v,zip(s,s[1:]))] for s,v in zip(a,b)]
zip(s,s[1:]) will gave you the desire pairs of elements that you want, for example :
>>> s =[4, 5, 6]
>>> zip(s,s[1:])
[(4, 5), (5, 6)]
Demo :
>>> b =[[7, 8], [6, 0]]
>>> a = [[1,5,3],[4 ,0 ,6]]
>>> [[k*(v[1]-v[0]) for k,v in zip(v,zip(s,s[1:]))] for s,v in zip(a,b)]
[[28, -16], [-24, 0]]
you can also do this really cleanly with numpy:
import numpy as np
a, b = np.array(a), np.array(b)
np.diff(a) * b
First I would split your a table in a table of lower bound and one of upper bound to work with aligned tables and improve readability :
lowerBounds = a[...,:-1]
upperBounds = a[...,1:]
Define the Gauss function you provided :
def f(x, gs_wdth = 1., mean=0.):
return 1./numpy.sqrt(2*numpy.pi)*gs_wdth * numpy.exp(-(x-mean)**2/(2*gs_wdth**2))
Then, use a nditer (see Iterating Over Arrays) to efficientely iterate over the arrays :
it = numpy.nditer([b, lowerBounds, upperBounds],
op_flags=[['readwrite'], ['readonly'], ['readonly']])
for _b, _lb, _ub in it:
multiplier = scipy.integrate.quad(f, _lb, _ub)[0]
_b[...] *= multiplier
print b
This does the job required in your post, and should be computationnaly efficient. Note that b in modified "in-place" : original values are lost but there is no memory overshoot during calculation.