How can i do this simple thing in Python from Matlab? - python

Simple Matlab code: e.g A(5+(1:3)) -> gives [A(6), A(7), A(8)]
In the above, A is a vector or a matrix. For instance:
A = [1 2 3 4 5 6 7 8 9 10];
A(5+(1:3))
ans =
6 7 8
Note that MATLAB indexing starts at 1, not 0.
How can i do the same in Python?

You are looking for slicing behavior
A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> A[5:8]
[6, 7, 8]
If A is some function that you want to call with parameters 6, 7, and 8, you could use a list comprehension.
answers = [A(6+i) for i in range(3)]

You want to do two things.
First, create a range (5 + (1:3)) which could be done in Python like range(number).
Second, apply a function to each range index. This could be done with map or a for loop.
The for loop solutions have been addressed, so here's a map based one:
result = map(A,your_range)

Use a list comprehension:
x = 5
f = 1 # from
t = 3 # till
print [x+i for i in range(f,t+1)]

If you are trying to use subscripts to create an array which is a subset of the whole array:
subset_list = A[6:8]

in python u can do it easily by A[5:5+3] . u can reference the values 5 and 3 by variables also like
b=5
c=3
a[b:b+c]

Related

Apply condition in for loop to each element in a list of lists

I am trying to see if each value in array is less then 0 then output 0, else output the number itself. The output must have the same dimensions as the input. Currently the input is a 3 by 4 but output is a list. How do I get the output size the same (3 by 4 array)?
input = [[1,2,3,4],[4,5,-6,-7],[8,9,10,11]]
output= []
for i in input:
if i < 0:
value = 0
output.append(value)
else:
value= i
output.append(value)
Python's NumPy arrays are a much more efficient way of dealing with matrices, which are what you have if all of your nested lists are the same size. If I understood your question, your example can be simplified down to a single line:
import numpy as np
inp = np.array([[-1,2,3,4],[4,5,-6,7],[8,9,-10,11]])
print (inp)
#[[ -1 2 3 4]
# [ 4 5 -6 7]
# [ 8 9 -10 11]]
inp[inp < 0] = 0
print (inp)
# [[ 0 2 3 4]
# [ 4 5 0 7]
# [ 8 9 0 11]]
You need a nested loop.
lists = [[1, 2, 3, 4], [4, 5, 6, 7], [8, 9, 10, 11]]
output = []
for l in lists:
nested_list = []
for i in l:
if i < 0:
nested_list.append(0)
else:
nested_list.append(i)
output.append(nested_list)
Also, you shouldn't name your variable input as it will override the input() function.
You don't necessarily need to import any additional libraries for this, that would be an overkill. Base python provides all the necessary operations for handling nested data structures and conditional operations.
You can do this with a combination of list comprehension and ternary operators in python -
inp = [[1,2,3,4],[4,5,-6,-7],[8,9,10,11]]
[[0 if item<0 else item for item in sublist] for sublist in inp]
#|____________________|
# |
# ternary operator
[[1,2,3,4],[4,5,0,0],[8,9,10,11]]
A list comprehension would allow you to avoid the list.append() and directly result in a list as output. Note, that you need a listed list comprehension since you want to iterate over elements of a list of lists.
A ternary operator is a conditional expression of the form [on_true] if [expression] else [on_false]. This lets you add conditions (if-else) to the list comprehension on each element you are iterating.
Here is my attempt:
l = [[1,2,3,4],[4,5,-6,-7],[8,9,10,11]]
res = [[x if x >= 0 else 0 for x in in_l] for in_l in l]

Use a custom order in range function Python

I have been struggling with this quite a bit, and was wondering if there is a solution for this.
I would like to use the range(start,stop,step) function in Python, but I would like to use a different order than what the normal functionalities allow. From what I understand the range function can do 3 things:
0, 1, 2, 3 etc
10, 9, 8, 7 etc
2, 4, 6, 8 etc
Now I am looking for the following order:
0, 10, 1, 9, 2, 8, 3, 7 etc
In this case 10 in the len(df), so the last row of the df.
You can create a generator to do that:
def my_range(n):
"""Yields numbers from 0 to n, in order 0, n, 1, n-1..."""
low = 0
high = n
while low <= high:
yield low
if high != low:
yield high
low += 1
high -= 1
Some examples:
print(list(my_range(10)))
# [0, 10, 1, 9, 2, 8, 3, 7, 4, 6, 5]
for i in my_range(5):
print(i)
0
5
1
4
2
3
This will provide every number in the interval exactly once, and lazily, just as range.
To answer the question in your comment:
if you want to mix the numbers in your_list = [1,3,4,5,7,9,10,12,13,14], you can just use this function to generate the indices:
your_list = [1,3,4,5,7,9,10,12,13,14]
for index in my_range(len(your_list)-1):
print(your_list[index], end=' ')
# 1 14 3 13 4 12 5 10 7 9
or you could build a new list in the mixed order:
new = [your_list[index] for index in my_range(len(your_list)-1)]
print(new)
# [1, 14, 3, 13, 4, 12, 5, 10, 7, 9]
range just has start, stop, step params. But you can achieve what you want by zipping two ranges together along with the chain.from_iterable function:
from itertools import chain
for val in chain.from_iterable(zip(range(11), range(10, -1, -1))):
print(val)
# 0 10 1 9 2 8 3 7 4 6 5 5 6 4 7 3 8 2 9 1 10 0
Note this solution repeats values, if you want no repeated values, then a generator is the way to go.
To keep things simple and clear the range function cannot do this.
Since it only allows to either increment or decrement at once.
but this can be achieved with loops and variables.
this is how to do it
for i in range(0,11):
print(i,10-i,end=" ")
this code will do it.

How can I sum every n array values and place the result into a new array? [duplicate]

This question already has answers here:
Sum slices of consecutive values in a NumPy array
(5 answers)
Closed 3 years ago.
I have a very long list of array numbers I would like to sum and place into a new array. For example the array:
[1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8]
would become:
[6,15,16,6,15,x]
if I was to sum every 3.
I cannot figure out how to go about it. I think possibly one problem is I do not know the length of my array - I do not mind losing the bottom bit of data if necessary.
I have tried the numpy.reshape function with no success:
x_ave = numpy.mean(x.reshape(-1,5), axis=1)
ret = umr_sum(arr, axis, dtype, out, keepdims)
I get an error:
TypeError: cannot perform reduce with flexible type
Cut the array to the correct length first then do a reshape.
import numpy as np
N = 3
a = np.array([1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8])
# first cut it so that lenght of a % N is zero
rest = a.shape[0]%N
a = a[:-rest]
assert a.shape[0]%N == 0
# do the reshape
a_RS = a.reshape(-1,N)
print(a_RS)
>> [[1 2 3]
[4 5 6]
[7 8 1]
[2 3 4]
[5 6 7]]
then you can simply add it up:
print(np.sum(a_RS,axis=1))
>> [ 6 15 16 9 18]
You can use a list comprehension do this:
ls = [1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8]
res = [sum(ls[i:i+3]) for i in range(0, len(ls), 3)]
[6, 15, 16, 9, 18, 8]
This will result in all the numbers being included in the resulting sum. If you don't want this to happen, then you can just check for it and replace the last sum with whatever value you want:
if (len(ls)%3) != 0:
res[-1] = 'x'
[6, 15, 16, 9, 18, 'x']
Or remove it entirely:
if (len(ls)%3) != 0:
res[:] = res[:-1]
[6, 15, 16, 9, 18]
Why don't you just simply use a list comprehension? E.g.
my_list = [1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8]
len_list = len(my_list) - len(my_list) % 3 # ignore end of list, s.t., only tuples of three are considered
[my_list[i] + my_list[i+1] + my_list[i+2] for i in range(0, len_list, 3)]

python: Create new lists by summing values of multiple lists

I want to create a new list that is the sum of the columns of the previous lists.
I have a lot of different lists and I would like to sum up all of the different lists in the most efficient way possible. Below is an example of the issue I am trying to solve:
list[0] = [2,4,1,6,7]
list[1] = [3,1,2,11,0]
list[2] = [2,4,2,2,1]
...
list[999] = [4,2,5,6,7]
The newlist would then look something like this:
Newlist = [1340,1525,675,1825,895]
What would be the best way to create the new list.
What do you think of this solution:
import numpy as np
a = list()
a.append([2, 4, 1, 6, 7]) # a[0]
a.append([3, 1, 2, 11, 0]) # a[1]
a.append([2, 4, 2, 2, 1]) # a[2]
# 1st solution
rslt_1 = a[0]
for _ in range(1, len(a)):
rslt_1 = np.add(rslt_1, a[_])
# 2nd solution
rslt_2 = np.sum(a, axis=0)
print("Rslt_1:", rslt_1)
print("Rslt_2:", rslt_2)
Returns:
Rslt_1: [ 7 9 5 19 8]
Rslt_2: [ 7 9 5 19 8]

parellelizing for loop in python

I am pretty new to python and i am yet to get a good handle on it.
I am dealing with huge datas in arrays and matrices, so i need some help in parellelizing the loops.
Heres my exact problem :
#Program Block starts
A= [1, 2, 3, 4, 5]
B= [2, 5, 7, 9, 15]
# I have a 3*3 matrix
C = [[0 for x in range(3)] for x in range(3)]
C[0][:]=[2,5,7]
C[1][:]=[7,9,15]
C[2][:]=[2,9,15]
#C is composed of elements of the array B and i want to change each element which would correspond to A i.e. change 2 to 1 , 5 to 2, and so on.
C_new = []
for el in range(0, 3):
n = C[el][:]
n_new=[]
for i in range(0, 3):
for j in range(0,5):
if n[i]== B[j]:
n_new.append(j+1)
C_new.append(n_new)
#Program Block Ends
I will obtain an output of
C_new =[ 1 2 3; 3 4 5; 1 4 5]
My original sizes are as follows:
A & B have 600000
C has 4000000*4
so i would like to parallelize wrt the rows of C ..break down 4000000 into parts..
For something like this, I recommend you taking a look at Numpy. It's been built to work with large arrays such as this.

Categories

Resources