How to selectively substract a pair indexs from an array using python - python

I have an array of 10 elements, and I would like to compute the following
a = [1,2,3,4,5,6,7,8,9,10]
and wish to do the following operation:
k = [a[1]-a[0], a[3]-a[2], a[5]-a[4], a[7]-a[6], a[9]-a[8]]
I wish to extend this operation any array size.

For a list with even elements you could build upon the following:
a = [1,3,5,7,9,11,13,15,17,19]
m = []
for i in range(1,len(a)-1):
m.append([a[i] - a[i-1]])
print(m)

Related

How can I use a for-loop to examine a two-dimensional array from a two-dimensional array?

What I want is to repeat the 10x10 array by 3x3 array. For example, an array of 3x3 contains nine values of indexes [0][0:3], [1][0:3], [2][0:3], and I want to find the max value of these nine values and apply them to a new array. I will add a picture and what I tried.
enter image description here
[1
array_33 = []
new_list = []
for i in range(10):
for j in range(10):
array_33.append([i:i+3])
max_value = max(map(max, array_33) # to find a max_vlaue in 3x3 array
new_list.append(max_value)
One row succeeded in finding a value up to index [0:3], but the next row failed to find a way to get a value up to [0:3]. The value [8:10] is not divided by 3, so the value is added to the new array as it is. Then I want to do a repetitive task of finding a value of [0:3] from lines 4 to 6. I dont know how can i do this
you can use 2D slicing from numpy:
import numpy as np
a = np.array([[(i+1)%10 for i in range(10)]]*10)
print(a)
sz = 3
b = [[np.max(a[i:i+3, j:j+3])
for j in range(0,a.shape[1],sz)]
for i in range(0,a.shape[0],sz)]
print(b)
generally, a[row1:row2, col1:col2] will give you the submatrix in those indexes (not including the last index)

How to count an element that exceed our criteria in a list that is in a list that is also in a list (a list with a depth of 4 lists (?))?

I'm trying to count how many element that is exceed some criteria (for exemple: 0.7) and then convert them into percent, the element is in a multiple list that look like this:
[[[[0.00173012]
[0.0009075 ]
[0.00080378]
...
[0.00069336]
[0.00074539]
[0.00186453]]
[[0.00081442]
[0.00022855]
[0.00019197]
...
[0.00018318]
[0.00017222]
[0.00075811]]
[[0.00084458]
[0.00020444]
[0.0001783 ]
...
[0.00020849]
[0.00017066]
[0.00070635]]
...
[[0.00073932]
[0.00022051]
[0.00024553]
...
[0.00028661]
[0.00019603]
[0.0007242 ]]
[[0.00085666]
[0.0002345 ]
[0.00021651]
...
[0.0002319 ]
[0.00017067]
[0.00066847]]
[[0.00188439]
[0.00092146]
[0.00082662]
...
[0.00077084]
[0.00066442]
[0.00178707]]]]
info: there is ... because it is a long list and cant fit all the list in the output cell (it is originally an image)
I've tried using:
len(pex > 0.7)/100
#pex is variable contain the multiple list above
but it's not really working because the ouput from the len is just 1, and if i divide it by 100 the output will be just 0.01
Is there any way for me to easily count all the element and the element that exceed some criteria so i can convert them into percent?? TIA
If you are allowed to use numpy this can be easily done, consider following example
import numpy as np
data = [[[1,2],[3,4]],[[5,6],[7,8]]]
arr = np.array(data) # create numpy.array
print(np.sum(arr>5)) # count elements > 5
print(arr.size) # number of all elements
output
3
8
Explanation: convert nested lists into numpy.array use comparison to get same-shaped array with Trues where value greater than 5 and Falses elsewhere, then use numpy.sum (not built-in sum function) to get count, as True and False are treated as 1 and 0 when subjected to arithmetic operations (this also apply outside numpy, e.g. sum([True,True,True]) gives 3)
I'm not sure of why this data structure was choosen but it look simpler to me to just flatten the list and sub list in a single list with all elements then perform operations on it :
def flatten(l):
res = []
for el in l:
if type(el) == list:
#If it's a list then we extract all the elements in it
res.extend(flatten(el))
else:
#Only add in the result the non-list elements
res.append(el)
return res
dex = [[[[0.00173012],
[0.0009075 ],
[0.00080378],
[0.00069336],
....
[0.00074539],
[0.00186453]]]]
flatten_dex = flatten(dex)
#Here flatten_dex is [0.00173012, 0.0009075, 0.00080378, 0.00069336, ..., 0.00074539, 0.00186453]
Once you have this list it's much simple to count the number of elements matching the condition :
nb_elements_greater_than_0_8 = len([e for e in flatten_dex if e > 0.8])
number_of_total_elements = len(flatten_dex)

Creating data in loop subject to moving condition

I am trying to create a list of data in a for loop then store this list in a list if it satisfies some condition. My code is
R = 10
lam = 1
proc_length = 100
L = 1
#Empty list to store lists
exponential_procs_lists = []
for procs in range(0,R):
#Draw exponential random variables
z_exponential = np.random.exponential(lam,proc_length)
#Sort values to increase
z_exponential.sort()
#Insert 0 at start of list
z_dat_r = np.insert(z_exponential,0,0)
sum = np.sum(np.diff(z_dat_r))
if sum < 5*L:
exponential_procs_lists.append(z_dat_r)
which will store some of the R lists that satisfies the sum < 5L condition. My question is, what is the best way to store R lists where the sum of each list is less than 5L? The lists can be different length but they must satisfy the condition that the sum of the increments is less than 5*L. Any help much appreciated.
Okay so based on your comment, I take that you want to generate an exponential_procs_list, inside which every sublist has a sum < 5*L.
Well, I modified your code to chop the sublists as soon as the sum exceeds 5*L.
Edit : See answer history to see my last answer for the approach above.
Well looking closer, notice you don't actually need the discrete difference array. You're finding the difference array, summing it up and checking whether the sum's < 5L and if it is, you append the original array.
But notice this:
if your array is like so: [0, 0.00760541, 0.22281415, 0.60476231], it's difference array would be [0.00760541 0.21520874 0.38194816].
If you add the first x terms of the difference array, you get the x+1th element of the original array. So you really just need to keep elements which are lesser than 5L:
import numpy as np
R = 10
lam = 1
proc_length = 5
L = 1
exponential_procs_lists = []
def chop(nums, target):
good_list = []
for num in nums:
if num >= target:
break
good_list.append(num)
return good_list
for procs in range(0,R):
z_exponential = np.random.exponential(lam,proc_length)
z_exponential.sort()
z_dat_r = np.insert(z_exponential,0,0)
good_list = chop(z_dat_r, 5*L)
exponential_procs_lists.append(good_list)
You could probably also just do a binary search(for better time complexity) or use a filter lambda, that's up to you.

Does Python syntax prevent me from creating this list comprehension?

I am trying to recreate a for loop (A) into a list comprehension. I think the problem here is that there are too many functions that need to be done to ni, namely squaring it and then making sure it is an integer before appending onto nn .
The list comprehension (B) is an attempt at getting the list comprehension to take a string (m) and square each individual number as an integer. The problem is that it needs to iterate over each number as a string THEN square itself as individual integers.
A
n = str(2002)
nn = []
for x in range(len(n)):
ni = n[x]
ns = int(ni)**2
nn.append(ns)
print(nn)
[4, 0, 0, 4]
B
m = str(9119)
mm = [(int(m[x]))**2 for x in m]
TypeError: string indices must be integers
This makes me feel like A cannot be done as a list comprehension? Love to see what your thoughts for alternatives and/or straight up solutions are.
You are passing a string as the index!
Additionally, you were trying to index the string m with the number at each index instead of its index (e.g, you tried to index m[0] with m[9] instead)
Try using the following instead:
m = str(9119)
mm = [int(x)**2 for x in m] #Thanks #Gelineau
Hope this helps!
x represents each digit in m. So you just have to square it
mm = [int(x)**2 for x in m]

Iterating efficiently through indices of arbitrary order array

Say I have an arbitrary array of variable order N. For example:
A is a 2x3x3 array is an order 3 array with 2,3, and 3 dimiensions along it's three indices.
I would like to efficiently loop through each element. If I knew a priori the order then I could do something like (in python),
#for order 3
import numpy as np
shape = np.shape(A)
i = 0
while i < shape[0]:
j = 0
while j < shape[1]:
k = 0
while k < shape[2]:
#code using i,j,k
k += 1
j += 1
i += 1
Now suppose I don't know the order of A, i.e. I don't know a priori the length of shape. How can I permute the quickest through all elements of the array?
There are many ways to do this, e.g. iterating over a.ravel() or a.flat. However, looping over every single element of an array in a Python loop will never be particularly efficient.
I don't think it matters which index you choose to permute over first, which index you choose to permute over second, etc. because your inner-most while statement will always be executed once per combination of i, j, and k.
If you need to keep the results of your operation (and assuming its a function of A and i,j,k) You'd want to use something like this:
import itertools
import numpy as np
results = ( (position, code(A,position))
for indices in itertools.product(*(range(i) for i in np.shape(A))))
Then you can iterate the results getting out the position and return value of code for each position. Or convert the generator expression to a list if you need to access the results multiple times.
If the array of of the format array = [[[1,2,3,4],[1,2]],[[1],[1,2,3]]]
You could use the following structure:
array = [[[1,2,3,4],[1,2]],[[1],[1,2,3]]]
indices = []
def iter_array(array,indices):
indices.append(0)
for a in array:
if isinstance(a[0],list):
iter_array(a,indices)
else:
indices.append(0)
for nonlist in a:
#do something using each element in indices
#print(indices)
indices.append(indices.pop()+1)
indices.pop()
indices.append(indices.pop()+1)
indices.pop()
iter_array(array,indices)
This should work for the usual nested list "arrays" I don't know if it would be possible to mimic this using numpy's array structure.

Categories