Running through variables in for loop - python

I'm new to Python, but I use it to process data. I've got a large amount of data stored as float arrays:
data1
data2
data3
I want to run similar processing for each data file. I was thinking of using a for loop:
for i in range(1,4):
I would like to then multiply the three data files by two, but I'm not sure how to continue afterwards. I imagine it would look like his:
for i in range(1,4):
data_i=data_i*2
Thank you.

You could make a two-dimensional array, meaning you put your float arrays inside another array.
Your situation right now would look like this:
data1 = [12, 2, 5]
data2 = [2, 4, 8]
data3 = [3, 0, 1]
By putting your arrays inside another array by doing this:
datax = [data1, data2, data3]
Your new situation would look like this:
datax = [[12, 2, 5], [2, 4, 8], [3, 0, 1]]
Now we can loop over the new datax array and perform an action on it's elements, data1, data2 and data3.
Something along the lines of:
datax = [[12, 2, 5], [2, 4, 8], [3, 0, 1]]
for sub_array in datax:
perform_action(sub_array)

You can simply store the data in e.g. list
data_list = [data1, data2, data3]
for i, data in enumerate(data_list):
some_fancy_stuff
data_list[i] = data * 2
Some explanation - enumerate will literally enumerate the items of the list with index i and also assigns data_list[i] to variable data. Than you can do whatever you want with data and its index i.

You could also use Python comprehension instead of loops, here is an example to illustrate it:
>>> a1 = [1,2,3]
>>> a2 = [4,5,6]
>>> a3 = [7,8,9]
>>> A = [a1, a2, a3]
>>>
>>> print [[x*2 for x in a] for a in A]
[[2, 4, 6], [8, 10, 12], [14, 16, 18]]
>>>
Let me explain it also.
The following construction is called comprehension:
a = [x*2 for x in X]
It produces an array (as you could see the brackets [ ]) of processed values (in the example value multiplication by two) from array X. It's as if we wrote:
a = []
for x in X:
a.append(x*2)
but in more concise way.
In your situation we used two comprehension one in one:
[x*2 for x in a]
and:
[ [....] for a in A]
So it's the same as if we did:
result = []
for a in A:
for x in a:
result.append(x*2)
but in more concise way again.
If you asked about variable names modification, so it is not possible in the Python without altering the language processor. But I guess you don't need it in that task at all.

Related

Inserting elements at a specific index python

I'm trying to insert a list of number into a list of list. I've simplified the code just as an example because the actual thing is fairly long. Basically i have two list and the end result i want is as follows:
C = [
[1,1,x],
[2,1,x],
[3,1,x],
[1,2,x],
[2,2,x],
[3,2,x],
[1,3,x],
[2,3,x],
[3,3,x],
]
You can think of this as a matrix of nxn dimensions, but the list has to be like this. Basically my problem is that i can't figure out how to insert the first list into index 0 and 1 like in the matrix above. The second list is just the x's at index 3 which i can work my way around.
Here is what i have so far, any help would be appreciated. Thanks a lot!!
set_I = [1,2,3]
set_J = [x,x,x,x,x,x,x,x,x]
C = []
for i in range(len(set_I)*len(set_I)):
C.append([])
for liste in C:
liste.insert(0,0)
liste.insert(1,0)
liste.insert(2,0)
Super wild guess:
set_I = [1,2,3]
set_J = [20,21,22,23,24,25,26,27,28]
C = []
for i in range(len(set_I)):
for j in range(len(set_I)):
C.append([set_I[j], set_I[i], set_J[3*i+j]])
print(C)
Result:
[
[1, 1, 20],
[2, 1, 21],
[3, 1, 22],
[1, 2, 23],
[2, 2, 24],
[3, 2, 25],
[1, 3, 26],
[2, 3, 27],
[3, 3, 28]
]
I am confused. If you want the product, then use it.product(), like:
set_I = [1,2,3]
set_J = [0,0,0,0,0,0,0,0,0] #Just putting zeros instead of x's.
import itertools as it
[[a,b,c] for (a,b),c in zip(it.product(set_I,repeat=2),set_J)]
If you want to initialize an empty list of list, then simply multiply.
[[0]*3]*9
I guess if you are looking for that problem, then I guess you must use this code
set_I = [1,2,3]
set_J = ['x','x','x','x','x','x','x','x','x']
C = []
for i in range(len(set_I)*len(set_I)):
C.append([])
for i in range(len(set_I)):
for j in range(len(set_I)):
C[3*i+j].append(j+1)
C[3*i+j].append(i+1)
C[3*i+j].append(set_J[3*i+j])

Python Numpy append array without flattening

In Python 3 I am importing several data files in a loop, and I would like to be able to store all the data in a single 2-dimensional array. I start with something like data = np.array([]) and on each iteration i want to add a new array datai = np.array([1,2,3]), how can I get my final array to look like this? [[1,2,3],[1,2,3],...,[1,2,3]]
I have tried np.append, np.concatenate, and np.stack, but none seem to work. An example code that I'm trying:
data = np.array([])
for i in range(datalen):
datai = *func to load data as array*
data = np.append(data, datai)
but of course this returns a flattened array. Is there any way I can get back a 2-dimensional array of length datalen with each element being the array datai?
Thanks!
The fastest way would be vstack
data = np.vstack((get_data() for i in range(datalen)))
vstack requires a tuple/iterable
data = np.vstack((data1, data2, data3))
or you can do this by appending with axis=0
data = np.empty(shape=(0, 3))
data = np.append(data, datai.reshape((-1, 3)), axis=0) # -1 will make the rows automatic
You can reshape your array using np.reshape like this
flattened_array = np.array([1,2,3,1,2,3,1,2,3])
wanted_array = np.reshape(flattened_array, (-1, 3))
This would result in
[[1, 2, 3],[1, 2, 3],[1, 2, 3]]
Solution 1 using list comprehensions:
data = []
datalen = 4
datai = range(1,4)
data = [list(datai) for _ in range(datalen)]
print (data)
Output
[[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]
Solution 2 (just a bit lengthy)
data = []
datalen = 4
for i in range(datalen):
datai = range(1,4)
data.append(list(datai))
print (data)
with the same output as above. In the second method you can also just simply use data.append(list(range(1,4))). You can choose if you want to convert datai to list or not. If you want the final output as an array, you can just use np.array()
You can try this-
data = np.zeros(shape=(datalen,len(datai))
for i in range(datalen):
data[i] = datai
It's called numpy.tile.
From the official docs:
>>> c = np.array([1,2,3,4])
>>> np.tile(c,(3,1))
array([[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4]])
so, for your datai do np.tile(datai,(N_repeats,1))

How does list.append() work in Python - I'm getting an unexpected result

I've written the following code below but the output of it is not as I expected. Does anyone know why it is behaving like this?
N.B.: I know the code doesn't transpose the list correctly - I stumbled across this strange behavior whilst writing the function.
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]
transposed = []
for i in range(4):
print("i", i)
t_list = []
for row in matrix:
print("row", row)
t_list.append(row[i])
print("t_list**********", t_list)
transposed.append(t_list)
print("transposed//////////////", transposed)
The output I would expect from this function at the end of the first row is:
[[1], [1, 5], [1, 5, 9]]
Instead, it seems to output:
[[1, 5, 9], [1, 5, 9], [1, 5, 9]]
Does anyone know why?
Thanks!
Key point is to make a copy of inner list and then append in the outer list.
copy = t_list[::]
It is because list is an object and it is a refresnce. so when you append another item in a list, it will be updated over all places where that objects exists. In your case, you are appending list into a list and then updating the inner list which causes the previous list items to update as well. You need to append a copy of a list in transposed list. Here is a solution.
transposed = []
for i in range(4):
print("i", i)
t_list = []
for row in matrix:
print("row", row)
t_list.append(row[i])
print("t_list**********", t_list)
transposed.append(t_list[::])
print("transposed//////////////", transposed)
It seems like an indentation issue in the line transposed.append(t_list):
transposed = []
for i in range(4):
t_list = []
for row in matrix:
t_list.append(row[i])
transposed.append(t_list)
This code prints:
[[1, 5, 9],
[2, 6, 10],
[3, 7, 11],
[4, 8, 12]]
Transpose has been implemented in numpy and it works with python arrays:
import numpy as np
np.transpose(matrix)
The problem is here:
t_list = []
for row in matrix:
t_list.append(row[i])
transposed.append(t_list)
Inside the loop the contents of the list object t_list changes, but the
list object itself remains the same. Thus, transposed gets the same object
for each row.
This is fixed by appending a copy of the current list instead of the original
list object.
transposed.append(list(t_list))

accessing position from numpy matrices in the list

I have numpy matrices collected in the list. I need to built an array which contains particular entry from each matrix, for example second entry from each matrix. I would like to avoid loop.
The data is already in this shape, I don't want to change the structure or change matrices into something else.
Example code - data structure:
L = []
m1 = np.mat([ 1, 2, 3]).T
m2 = np.mat([ 4, 5, 6]).T
m3 = np.mat([ 7, 8, 9]).T
m4 = np.mat([10,11,12]).T
m5 = np.mat([13,14,15]).T
L.append(m1)
L.append(m2)
L.append(m3)
L.append(m4)
L.append(m5)
The only way I managed to do it is through the loop:
S = []
for k in range(len(L)):
S.append(L[k][1,0])
print 'S = %s' % S
the output I need: S = [2, 5, 8, 11, 14] I thought something like: S1 = np.array(L[:][1,0]) should work but whatever I try I have the error like: TypeError: list indices must be integers, not tuple. What is the efficient way (numpy style) of accessing it?
Using list comprehension:
>>> x = [i[1] for i in L]
>>> x
[2, 5, 8, 11, 14]
>>>
You could also do
>>> M = np.column_stack([m1,m2,m3,m4,m5])
and then access the rows via
>>> M[1]
matrix([[ 2, 5, 8, 11, 14]])
If you've got larger vectors, and want to access multiple rows, this might be faster in the long run.
As DSM says, either you should have a 2D matrix and use numpy slicing, otherwise some form of list-comp as shown by Pawelmhm... A faster form will be:
from operator import itemgetter
els = map (itemgetter(1), (m1, m2, m3, m4, m5))

Rearrange a python list into n lists, by column

I want to rearrange a list l into a list of n lists, where n is the number of columns.
e.g.,
l = [1,2,3,4,5,6,7,8,9,10]
n = 4
==> [[1,5,9],[2,6,10],[3,7][4,8]]
Can someone please help me out with an algorithm? Feel free to use any python awesomeness that's available; I'm sure theres some cool mechanism that's a good fit for this, i just can't think of it.
PS The example list just happened to be ordered numbers starting at 1. That's not my actual scenario.
There is indeed a cool mechanism for this in Python: the three-argument form of slicing, where the last argument is step size.
>>> l = [1,2,3,4,5,6,7,8,9,10]
>>> n = 4
>>> [l[i::n] for i in range(n)]
[[1, 5, 9], [2, 6, 10], [3, 7], [4, 8]]
l = [1,2,3,4,5,6,7,8,9,10]
n = 4
def f(l,n):
A = []
[A.append([]) for i in xrange(n)]
[ A [(i - 1) % n].append(i) for i in l]
return A
print f(l,n)
[[1, 5, 9], [2, 6, 10], [3, 7], [4, 8]]
The following function does what you want to achieve:
def rearrange(seq,n):
return [[v for i,v in enumerate(seq[x:]) if i%n==0] for x in xrange(len(seq))][:n]
Writing Python isn't a game of code golf, don't be afraid to use more than one line for the sake of readability.
l = [1,2,3,4,5,6,7,8]
def split_into_columns(input_list, num_of_cols=3):
retval = [ [] for _ in xrange(num_of_cols)] # build 3 columns
for i in xrange(len(input_list)): # iterate through original list
retval[i%num_of_cols].append(input_list[i]) # place in the "modulo 3" column
return retval
# here's a compressed, less readable version of that for-loop
#[retval[i%3].append(input_list[i]) for i in xrange(len(input_list))]
#return retval
print split_into_columns(l, 3)

Categories