getting difference between list values with variable window - python

>>> jj = [1,3,9,4,5,6,1,2,4,1,7,9,0,4,1,9]
>>> np.diff(jj)
[ 2 6 -5 1 1 -5 1 2 -3 6 2 -9 4 -3 8]
np.diff gives difference between the consecutive numbers. I am looking for difference between every element with a gap of 3 values
input: [1,3,9,4,5,6,1,2,4,1,7,9,0,4,1,9]
difference between the bold values
output : [3,-3,0,-1,-9]

Well, the most straightforward way is to slice for every third number:
>>> import numpy as np
>>> arr = np.array([1,3,9,4,5,6,1,2,4,1,7,9,0,4,1,9])
>>> np.diff(arr[::3])
array([ 3, -3, 0, -1, 9])
Note, if you use a numpy.ndarray then this is fairly space-efficient since arr[::3] creates a view

You still can use np.diff just pass not the whole array but a specific array like this:
np.diff(jj[::3])

First, you can use slicing with step : 3. then use numpy.diff. You can read understanding-slicing
import numpy as np
a = np.array([1,3,9,4,5,6,1,2,4,1,7,9,0,4,1,9])
b = np.diff(a[::3])
print(b)
Output: array([ 3, -3, 0, -1, 9])

Related

change odd elements in list to negative

I am trying to change odd elements in a list of int to negative using slicing
l[1::2] = -1 * l[1::2]
However, I encounter the following error:
ValueError: attempt to assign sequence of size 0 to extended slice of size 2
If you wish to uses slices:
>>> a = [1,4,7,8,2]
>>> a[1::2] = [-x for x in a[1::2]]
>>> a
[1, -4, 7, -8, 2]
When assigning to an extended slice like a[1::2], the list/slice on the right hand side must be the same length as the left hand side. In the above, we've mapped to a[1::2] with a list comprehension, so the length is unchanged. If we consider -1 * a[1::2] this yields [] which is of a different length.
Best way would be to do it vectorized with numpy. Without numpy, I don't see a way to do it without creating a new loop. Here you have two examples of how to do it. With and without numpy:
import numpy as np
# vectorized
a = np.arange(10)
a[1::2] *= -1
print(a)
# >>> [ 0 -1 2 -3 4 -5 6 -7 8 -9]
a = [i for i in range(10)]
a = [i if i%2==0 else i*-1 for i in a] # need to loop through list again..
print(a)
# >>> [0, -1, 2, -3, 4, -5, 6, -7, 8, -9]
Edited to fix odd elements to negative, not pos.

How to print even index values of any array | NumPy |

I am a learner , bit stuck not getting how do i print the even indexed value of an array
My code :
import numpy as np
arr_1 = np.array([2,4,6,11])
arr_1 [ (arr_1[ i for i in range(arr_1.size) ] ) % 2 == 0 ]
Expected Output :
2,6
2 -> comes under index 0
6 -> comes under index 2
Both are even index
IIUC, You can use [start:end:step] from list and get what you want like below:
>>> arr_1 = np.array([2,4,6,11])
>>> arr_1[::2]
array([2, 6])
>>> list(arr_1[::2])
[2, 6]
>>> print(*arr_1[::2], sep=',')
2,6
Your problem was that you were iterating through what range() function returned.
which obviously wasn't your original arr_1
in my code we just iterate through the arr_1 without using any range or length
Code that will work:
import numpy as np
arr_1 = np.array([2,4,6,11])
arr_1 = [i for index, i in enumerate(arr_1) if ((index % 2) == 0)]
print(arr_1)
Output:
[2, 6]

Delete subarray in numpy array if threshold is not met

I have the following np array structure:
[[1, 2, 3 ,4]
[5, 7, 8 ,6]
.
.
[7, 5, 1 ,0]]
What is want to do is to remove a subarray if thresholds are not met.
for example in [5, 7, 8 ,6], i want to delete this array if position 0 is not between 2 and 4. I want to do this action for the whole numpy array and intend on having a threshold on all positions in the sub array.
My thought process is something that is shown below:
for arr in data:
if arr[0] < 2 or arr[0] > 4:
np.delete(data, arr)
However, printing data.shape before and after show no difference. Can someone help me?
Thanks!
Creating example data for testing:
>>> import numpy as np
>>> data = np.array([
... [1,2,3,4],
... [5,7,8,9],
... [7,5,1,0]
... ])
You can slice the array to get the first column:
>>> data[:, 0]
array([1, 5, 7])
Figure out which of these first-column values is in range by broadcasting the comparison operators across them (being careful that we can't chain these operators, and must combine them using a bitwise rather than logical AND, because of syntax limitations):
>>> first = data[:, 0]
>>> (4 <= first) & (first <= 6)
array([False, True, False])
Finally, we can use that to mask the original array:
>>> data[(4 <= first) & (first <= 6)]
array([[5, 7, 8, 9]])

What's the most efficient way to split up a Numpy ndarray using percentage?

Hi I'm new to Python & Numpy and I'd like to ask what is the most efficient way to split a ndarray into 3 parts: 20%, 60% and 20%
import numpy as np
row_indices = np.random.permutation(10)
Let's assume the ndarray has 10 items: [7 9 3 1 2 4 5 6 0 8]
The expected results are the ndarray separated into 3 parts like part1, part2 and part3.
part1: [7 9]
part2: [3 1 2 4 5]
part3: [0 8]
Here's one way -
# data array
In [85]: a = np.array([7, 9, 3, 1, 2, 4, 5, 6, 0, 8])
# percentages (ratios) array
In [86]: p = np.array([0.2,0.6,0.2]) # must sum upto 1
In [87]: np.split(a,(len(a)*p[:-1].cumsum()).astype(int))
Out[87]: [array([7, 9]), array([3, 1, 2, 4, 5, 6]), array([0, 8])]
Alternative to np.split :
np.split could be slower when working with large data, so, we could alternatively use a loop there -
split_idx = np.r_[0,(len(a)*p.cumsum()).astype(int)]
out = [a[i:j] for (i,j) in zip(split_idx[:-1],split_idx[1:])]
I normally just go for the most obvious solution, although there are much fancier ways to do the same. It takes a second to implement and doesn't even require debugging (since it's extremely simple)
part1 = [a[i, ...] for i in range(int(a.shape[0] * 0.2))]
part2 = [a[i, ...] for i in range(int(a.shape[0] * 0.2), int(len(a) * 0.6))]
part3 = [a[i, ...] for i in range(int(a.shape[0] * 0.6), len(a))]
A few things to notice though
This is rounded and therefore you could get something which is only roughly a 20-60-20 split
You get back a list of element so you might have to re-numpyfy them with np.asarray()
You can use this method for indexing multiple objects (e.g. labels and inputs) for the same elements
If you get the indices once before the splits (indices = list(range(a.shape[0]))) you could also shuffle them thus taking care of data shuffling at the same time

Edit an array value using another array with the positions that should change

It's the end of my first month coding with python and I'm struggling with a piece of code that seemed simpler in my mind.
I'm trying to edit array values based on the positions given by another array generated by np.argwhere. For example:
a = np.arange(6).reshape(2,3)
b = np.argwhere(a>3)
c = ([7,8,9],[10,11,12])
Now I want to change the values in c that are in the same position as the values that are greater than 3 in the array a.
I'm trying to avoid a for loop because of the size of the real data I am working on.
Thanks in advance!
You can use numpy indexing:
In [6]: c[np.where(a>3)] = a[a>3]
In [7]: c
Out[7]:
array([[ 7, 8, 9],
[10, 4, 5]])
cant you just do
c[a>3] = a[a>3]
example:
import numpy as np
c = np.arange(7,13).reshape(2,3)
a = np.arange(6).reshape(2,3)
c[a>3] = a[a>3]
outputs
>>> c
[[ 7 8 9]
[10 4 5]]

Categories