How to subtract or find the differences from this output? - python

Beginner here, just a week into Python.
So what I'm trying to do is figure out how to find the differences from the output I get.
Let's say I got [ 5 8 10 8 11]
Now I want to 8-5, 10-8, 8-10, 11-8.
How do I achieve that? enlighten me.
import numpy as np
import random
ll = list(range(5))
a = np.array(range(5))
b = np.array(random.choices(ll, k=5))
c = np.array([5])
print(a+b+c)

You can try this way by using list comprehension:
>>> out = [7, 7, 10, 9, 12] # a normal python list
>>> out_diff = [ (i-j) for j, i in zip(out[:-1], out[1:]) ]
>>> out_diff
[0, 3, -1, 3]
And since you're using numpy, its more easy:
>>> out[:-1] - out[1:] # without using functions
array([ 0, -3, 1, -3])
Or use np.diff:
>>> np.diff(out) # assumed 'out' is a numpy array instance
array([ 0, 3, -1, 3])

I think you are looking for the function "ediff1d" inside the Numpy module. For more information visit this link:numpy.ediff1d documentation
See example code:
import numpy as np
array = [5, 8, 10, 8, 11]
print(array)
print(np.ediff1d(array))
Output:
[5, 8, 10, 8, 11]
[ 3 2 -2 3]

a simple way to implement it
lst=[5,8,10,8,11]
new_lst=[]
for i in range(1,len(lst)):
new_lst.append(lst[i]-lst[i-1])

Related

Python Numpy: How to reverse a slice operation?

I'd like to 'reverse' a slice operation. For example, the original array is:
import numpy as np
a=np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
>>> array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
Then, I slice this array, and do some operations on it (times 2):
b = 2 * a[::-1,::2]
>>> array([[18, 22],
[10, 14],
[ 2, 6]])
How can I put all elements in b back to their original position in a (Note axis 0 is flipped), i.e. the final result should be:
>>> array([[ 2, 0, 6, 0],
[10, 0, 14, 0],
[18, 0, 22, 0]])
I figured something like as_strided and flip should be used, but I can't seem to get it working. Thanks for any help!!
import numpy as np
a=np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
req_array = np.zeros(a.shape)
req_array[::-1,::2] = 2 * a[::-1,::2]
print(req_array) ## your required array
You could just np.zeros(shape=(3,4)), index them, but you would need to reverse[::-1] before doing so. Seems like a lot of pain for something that can be solved with just as simple as saving the array before under a different variable, as you always going to have to save the shape anyway. e.g.
var1 = beforeArray
var2 = 2 * var1 [::-1,::2]
to_reverse_var2 = np.zeros(var1.shape)
then index
But would be much easier to just save the var instead, because you will always need the array.shape anyway. Just use self. or global if it is functional problem.
Other ideas would be play about with matrix methods outside of numpy to speed up process such as.

Python - mutate row elements using array of indices

given the following array:
import numpy as np
a = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
I can create an array of indices:
b = np.array([0, 2, 0, 1])
and mutate one element from each row using the indices:
a[np.arange(4),b] += 10
which yields:
[[11 2 3]
[ 4 5 16]
[17 8 9]
[10 21 12]]
Is there a more readable way to achieve the same result instead of a[np.arange(4),b] += 10?
Maybe writing it out more explicitly would help for "readability":
x = np.array([0, 2, 0, 1])
y = numpy.arange(x.size)
a[y, x] += 10
Otherwise, you are doing it in a very clear and succinct way, in my opinion.
Another option is to use a ufunc:
numpy.add.at(a, [y,x], 10)
Or if you prefer not to use numpy.arange:
y = numpy.indices((x.size,))

Multiplication between 2 lists

i have 2 lists
a=[[2,3,5],[3,6,2],[1,3,2]]
b=[4,2,1]
i want the output to be:
c=[[8,12,20],[6,12,4],[1,3,2]]
At present i am using the following code but its problem is that the computation time is very high as the number of values in my list are very large.The first list of list has 1000 list in which each list has 10000 values and the second list has 1000 values.Therefore the computation time is a problem.I want a new idea in which computation time is less.The present code is:
a=[[2,3,5],[3,6,2],[1,3,2]]
b=[4,2,1]
c=[]
s=0
for i in b:
c1=[]
t=0
s=s+1
for j in a:
t=t+1
for k in j:
if t==s:
m=i*k
c1.append(m)
c.append(c1)
print(c)
Use zip() to combine each list:
a=[[2,3,5],[3,6,2],[1,3,2]]
b=[4,2,1]
[[m*n for n in second] for m, second in zip(b,a)]
You can use numpy :
>>> import numpy as np
>>> a=np.array([[2,3,5],[3,6,2],[1,3,2]])
>>> b=np.array([4,2,1])
>>> a*np.vstack(b)
array([[ 8, 12, 20],
[ 6, 12, 4],
[ 1, 3, 2]])
Or as #csunday95 suggested as a more optimized way you can use transpose instead of vstack :
>>> (a.T*b).T
array([[ 8, 12, 20],
[ 6, 12, 4],
[ 1, 3, 2]])
This may not be faster, but it's a neater way of doing it :)
c = []
b_len = len(b)
for i in range(len(a)):
b_multiplier = b[i%b_len]
c.append([x*b_multiplier for x in a[i]])
Alternate short way now I've actually read the question properly and realised a and b are the same length:
c = [[x*b[i] for x in a[i]] for i in range(len(a))]

I have need the N minimum (index) values in a numpy array

Hi I have an array with X amount of values in it I would like to locate the indexs of the ten smallest values. In this link they calculated the maximum effectively, How to get indices of N maximum values in a numpy array?
however I cant comment on links yet so I'm having to repost the question.
I'm not sure which indices i need to change to achieve the minimum and not the maximum values.
This is their code
In [1]: import numpy as np
In [2]: arr = np.array([1, 3, 2, 4, 5])
In [3]: arr.argsort()[-3:][::-1]
Out[3]: array([4, 3, 1])
If you call
arr.argsort()[:3]
It will give you the indices of the 3 smallest elements.
array([0, 2, 1], dtype=int64)
So, for n, you should call
arr.argsort()[:n]
Since this question was posted, numpy has updated to include a faster way of selecting the smallest elements from an array using argpartition. It was first included in Numpy 1.8.
Using snarly's answer as inspiration, we can quickly find the k=3 smallest elements:
In [1]: import numpy as np
In [2]: arr = np.array([1, 3, 2, 4, 5])
In [3]: k = 3
In [4]: ind = np.argpartition(arr, k)[:k]
In [5]: ind
Out[5]: array([0, 2, 1])
In [6]: arr[ind]
Out[6]: array([1, 2, 3])
This will run in O(n) time because it does not need to do a full sort. If you need your answers sorted (Note: in this case the output array was in sorted order but that is not guaranteed) you can sort the output:
In [7]: sorted(arr[ind])
Out[7]: array([1, 2, 3])
This runs on O(n + k log k) because the sorting takes place on the smaller
output list.
I don't guarantee that this will be faster, but a better algorithm would rely on heapq.
import heapq
indices = heapq.nsmallest(10,np.nditer(arr),key=arr.__getitem__)
This should work in approximately O(N) operations whereas using argsort would take O(NlogN) operations. However, the other is pushed into highly optimized C, so it might still perform better. To know for sure, you'd need to run some tests on your actual data.
Just don't reverse the sort results.
In [164]: a = numpy.random.random(20)
In [165]: a
Out[165]:
array([ 0.63261763, 0.01718228, 0.42679479, 0.04449562, 0.19160089,
0.29653725, 0.93946388, 0.39915215, 0.56751034, 0.33210873,
0.17521395, 0.49573607, 0.84587652, 0.73638224, 0.36303797,
0.2150837 , 0.51665416, 0.47111993, 0.79984964, 0.89231776])
Sorted:
In [166]: a.argsort()
Out[166]:
array([ 1, 3, 10, 4, 15, 5, 9, 14, 7, 2, 17, 11, 16, 8, 0, 13, 18,
12, 19, 6])
First ten:
In [168]: a.argsort()[:10]
Out[168]: array([ 1, 3, 10, 4, 15, 5, 9, 14, 7, 2])
This code save 20 index of maximum element of split_list in Twenty_Maximum:
Twenty_Maximum = split_list.argsort()[-20:]
against this code save 20 index of minimum element of split_list in Twenty_Minimum:
Twenty_Minimum = split_list.argsort()[:20]

NumPy first and last element from array

I am trying to dynamically get the first and last element from an array.
So, let us suppose the array has 6 elements.
test = [1,23,4,6,7,8]
If I am trying to get the first and last = 1,8, 23,7 and 4,6. Is there a way to get elements in this order?
I looked at a couple of questions Link Link2. I took help of these links and I came up with this prototype..
#!/usr/bin/env python
import numpy
test = [1,23,4,6,7,8]
test1 = numpy.array([1,23,4,6,7,8])
len_test = len(test)
first_list = [0,1,2]
len_first = len(first_list)
second_list = [-1,-2,-3]
len_second = len(second_list)
for a in range(len_first):
print numpy.array(test)[[first_list[a] , second_list[a]]]
print test1[[first_list[a], second_list[a]]]
But this prototype won't scale for if you have more than 6 elements. So, I was wondering if there is way to dynamically get the pair of elements.
Thanks!
I ended here, because I googled for "python first and last element of array", and found everything else but this. So here's the answer to the title question:
a = [1,2,3]
a[0] # first element (returns 1)
a[-1] # last element (returns 3)
How about:
In [10]: arr = numpy.array([1,23,4,6,7,8])
In [11]: [(arr[i], arr[-i-1]) for i in range(len(arr) // 2)]
Out[11]: [(1, 8), (23, 7), (4, 6)]
Depending on the size of arr, writing the entire thing in NumPy may be more performant:
In [41]: arr = numpy.array([1,23,4,6,7,8]*100)
In [42]: %timeit [(arr[i], arr[-i-1]) for i in range(len(arr) // 2)]
10000 loops, best of 3: 167 us per loop
In [43]: %timeit numpy.vstack((arr, arr[::-1]))[:,:len(arr)//2]
100000 loops, best of 3: 16.4 us per loop
arr = np.array([1,2,3,4])
arr[-1] # last element
Using Numpy's fancy indexing:
>>> test
array([ 1, 23, 4, 6, 7, 8])
>>> test[::-1] # test, reversed
array([ 8, 7, 6, 4, 23, 1])
>>> numpy.vstack([test, test[::-1]]) # stack test and its reverse
array([[ 1, 23, 4, 6, 7, 8],
[ 8, 7, 6, 4, 23, 1]])
>>> # transpose, then take the first half;
>>> # +1 to cater to odd-length arrays
>>> numpy.vstack([test, test[::-1]]).T[:(len(test) + 1) // 2]
array([[ 1, 8],
[23, 7],
[ 4, 6]])
vstack copies the array, but all the other operations are constant-time pointer tricks (including reversal) and hence are very fast.
>>> test = [1,23,4,6,7,8]
>>> from itertools import izip_longest
>>> for e in izip_longest(test, reversed(test)):
print e
(1, 8)
(23, 7)
(4, 6)
(6, 4)
(7, 23)
(8, 1)
Another option
>>> test = [1,23,4,6,7,8]
>>> start, end = iter(test), reversed(test)
>>> try:
while True:
print map(next, [start, end])
except StopIteration:
pass
[1, 8]
[23, 7]
[4, 6]
[6, 4]
[7, 23]
[8, 1]
You can simply use take method and index of element (Last index can be -1).
arr = np.array([1,2,3])
last = arr.take(-1)
# 3
How about this?
>>> import numpy
>>> test1 = numpy.array([1,23,4,6,7,8])
>>> forward = iter(test1)
>>> backward = reversed(test1)
>>> for a in range((len(test1)+1)//2):
... print forward.next(), backward.next()
...
1 8
23 7
4 6
The (len(test1)+1)//2 ensures that the middle element of odd length arrays is also returned:
>>> test1 = numpy.array([1,23,4,9,6,7,8]) # additional element '9' in the middle
>>> forward = iter(test1)
>>> backward = reversed(test1)
>>> for a in range((len(test1)+1)//2):
... print forward.next(), backward.next()
1 8
23 7
4 6
9 9
Using just len(test1)//2 will drop the middle elemen of odd length arrays.
This does it. Note that with an odd number of elements the one in the middle won't be included.
test = [1, 23, 4, 6, 7, 8, 5]
for i in range(len(test)/2):
print (test[i], test[-1-i])
Output:
(1, 5)
(23, 8)
(4, 7)
How about this:
xs = [1,23,4,6,7,8]
np.array(list(zip(xs[:len(xs)//2], xs[::-1])))
array([[ 1, 8],
[23, 7],
[ 4, 6]])
Assuming the list has a even number of elements, you could do:
test = [1,23,4,6,7,8]
test_rest = reversed(test[:len(test)/2])
for n in len(test_rest):
print [test[n], test_test[n]]

Categories