Iterating over numpy array and access the values - python

I want to iterate over a numpy array and do some calculations on the values. However, things are not as expected. To show what I mean, I simply wrote this code to read values from a numpy array and move them to another list.
a = array([1,2,1]).reshape(-1, 1)
u = []
for i in np.nditer(a):
print(i)
u.append(i)
print(u)
According to tutorial, nditer points to elements and as print(i) shows, i is the value. However, when I append that i to an array, the array doesn't store the value. The expected output is u = [1, 2, 1] but the output of the code is
1
2
1
[array(1), array(2), array(1)]
What does array(1) mean exactly and how can I fix that?
P.S: I know that with .tolist() I can convert a numpy array to a standard array. However, in that code, I want to iterate over numpy elements.

As already explained in your previous question, numpy.nditer yields numpy arrays. What is shown by print is only the representation of the object, not the content or type of the object (e.g., 1 and '1' have the same representation, not the same type).
import numpy as np
a = np.array([1,2,1]).reshape(-1, 1)
type(next(np.nditer(a)))
# numpy.ndarray
You just have a zero-dimensional array:
np.array(1).shape
# ()
There is no need to use numpy.nditer here. If you really want to iterate over the rows of your array with single column (and not use tolist), use:
u = []
for i in a[:,0]:
u.append(i)
u
# [1, 2, 1]

numpy.nditer actually returns a numpy array. If you want the actual value of this item, you can use the built in item() function:
a = array([1,2,1]).reshape(-1, 1)
u = []
for i in np.nditer(a):
u.append(i.item())
print(u)

A pure python equivalent of what's happening with your append is:
In [75]: alist = []
...: x = [0]
...: for i in range(3):
...: x[0] = i
...: print(x)
...: alist.append(x)
[0]
[1]
[2]
In [76]: alist
Out[76]: [[2], [2], [2]]
In [77]: x
Out[77]: [2]
x is modified in each loop, but only a reference is saved. The result is that all elements of the list are the same object, and display its last value.

Related

Extract indices of specified elements in a list

I have a list. Each element is a real-value integer, and I want to extract the indices of specified element. For example:
import numpy as np
idx = np.where(A==1) #A is a list of [1,1,2,3,4,5....]
But np.where seems not to work for a list.
My next task is to obtain a new list from another list, B, based on the obtained indices:
C = B[idx]
Convert the list A to an ndarray and it should work
idx = np.where(np.array(A)==1)
C = [B[i] for i in idx[0]]
There is no need of numpy IMO. You can create B simply by using something like:
B = [ele for ele in A if ele == 1]
If A is a vanilla list (a default list in Python), then Python will interpret:
A == 1
as checking whether the list is equal to 1. Which is of course not true.
You should turn A into an array:
Aa = np.array(A) # construct a numpy array
idx = np.where(Aa == 1) # obtain the indices
B = Aa[idx] # make a copy (again on the numpy array)

How to subtract every n-1 item from every nth item in an array (Python)?

I've looked into the many posts about getting every nth item of an array, and I used the method for slicing even and odd indices. However, I end up with an empty array for the final object. Any suggestions?
floc1 is an array, and I want to subtract every odd element from every even element:
period = abs(floc1[0::2] - floc1[1::2])
This currently gives me an empty array.
EDIT:
I've tried everything suggested in the comments below. The only thing that generated a different error was:
period = [i-j for i, j in zip(floc1[0::2], floc1[1::2])]
This gives:
Phi12 = ((tau)/(period))
ValueError: operands could not be broadcast together with shapes (1,8208) (0,)
In reference to:
Phi12 = ((tau)/(period))
Again, floc1 is definitely not an empty array. I saved it to a text file to confirm.
Your example gives an error if floc1 is a list (which people often call an "array"). For a list you can do it this way.
>>> floc1 = [11, 5, 6, 2]
>>> it = iter(floc1)
>>> [x - next(it) for x in it]
[6, 4]
You can also use zip if you prefer see #wenzul's answer
If floc1 is a numpy.array - what you have already works
>>> import numpy as np
>>> floc1 = np.array([11, 5, 6, 2])
>>> abs(floc1[0::2] - floc1[1::2])
array([6, 4])
Perhaps your floc1 is actually an empty array
It's not working because you try to substract a list from a list.
You need to do that element-wise.
>>> for i, k in zip(floc1[0::2], floc1[1::2]):
... print abs(i-k)
Also look into this.

Array inside an array in Python [duplicate]

This question already has an answer here:
Strange behavior of lists in python [duplicate]
(1 answer)
Closed 8 years ago.
This is not really a question about an error. Rather, a clarification on how things work.
I am putting an element(0 for example) inside an array which is also inside an array. Doing it iteratively, the code looks like this:
arr = [[0 for x in range(2)] for x in range(2)]
Recursively,
def zero(array,n,i):
if i >= n:
return array
else:
array[i].append(0)
return zero(array,n,i+1)
arr = [[]] * 2
print zero(arr,2,0)
They would both have an output like this:
[[0,0],[0,0]]
I did not get the process that the recursion underwent(I just accidentally made that code through trial and error.).
What I did not get was since I am appending zero in the first array(with index zero) inside the bigger array, shouldn't '0' be appended only in the first array and not on the second array? But that is not the case, '0' was appended to both array. And when it returns the function, instead of appending '0' to the second array, it was appended to both array again.
I tried to trace it but I really don't understand how it happened. Thank you for the response.
This would be because
arr = [[]] * 2
is creating another reference to the same list construct. So you have an array with two elements both of which are a reference to the same list. Thus an application on one of them, such as appending an element, will cause that same operation to be reciprocated to the other.
Breaking down the constituent parts of the list comprehension using the interactive interpreter:
>>> arr = [[0 for x in range(2)] for x in range(2)]
>>> print arr
[[0, 0], [0, 0]]
>>> inner_array = [0 for x in range(2)]
>>> print inner_array
[0, 0]
>>> total_arr = [inner_array for x in range(2)]
>>> print total_arr
[[0, 0], [0, 0]]
So you have an array of [0,0], and then place that in the outer list comprehension which creates that same array twice, due to the range(2) component.
One can verify that they are the exact same array as follows:
>>> id(inner_array)
139834121190864
>>> id(total_arr[0])
139834121190864
>>> id(total_arr[1])
139834121190864
id returns the address of the object, and here, they are all the same.

Shapes of the np.arrays, unexpected additional dimension

I'm dealing with arrays in python, and this generated a lot of doubts...
1) I produce a list of list reading 4 columns from N files and I store 4 elements for N times in a list. I then convert this list in a numpy array:
s = np.array(s)
and I ask for the shape of this array. The answer is correct:
print s.shape
#(N,4)
I then produce the mean of this Nx4 array:
s_m = sum(s)/len(s)
print s_m.shape
#(4,)
that I guess it means that this array is a 1D array. Is this correct?
2) If I subtract the mean vector s_m from the rows of the array s, I can proceed in two ways:
residuals_s = s - s_m
or:
residuals_s = []
for i in range(len(s)):
residuals_s.append([])
tmp = s[i] - s_m
residuals_s.append(tmp)
if I now ask for the shape of residuals_s in the two cases I obtain two different answers. In the first case I obtain:
(N,4)
in the second:
(N,1,4)
can someone explain why there is an additional dimension?
You can get the mean using the numpy method (producing the same (4,) shape):
s_m = s.mean(axis=0)
s - s_m works because s_m is 'broadcasted' to the dimensions of s.
If I run your second residuals_s I get a list containing empty lists and arrays:
[[],
array([ 1.02649662, 0.43613824, 0.66276758, 2.0082684 ]),
[],
array([ 1.13000227, -0.94129685, 0.63411801, -0.383982 ]),
...
]
That does not convert to a (N,1,4) array, but rather a (M,) array with dtype=object. Did you copy and paste correctly?
A corrected iteration is:
for i in range(len(s)):
residuals_s.append(s[i]-s_m)
produces a simpler list of arrays:
[array([ 1.02649662, 0.43613824, 0.66276758, 2.0082684 ]),
array([ 1.13000227, -0.94129685, 0.63411801, -0.383982 ]),
...]
which converts to a (N,4) array.
Iteration like this usually is not needed. But if it is, appending to lists like this is one way to go. Another is to pre allocate an array, and assign rows
residuals_s = np.zeros_like(s)
for i in range(s.shape[0]):
residuals_s[i,:] = s[i]-s_m
I get your (N,1,4) with:
In [39]: residuals_s=[]
In [40]: for i in range(len(s)):
....: residuals_s.append([])
....: tmp = s[i] - s_m
....: residuals_s[-1].append(tmp)
In [41]: residuals_s
Out[41]:
[[array([ 1.02649662, 0.43613824, 0.66276758, 2.0082684 ])],
[array([ 1.13000227, -0.94129685, 0.63411801, -0.383982 ])],
...]
In [43]: np.array(residuals_s).shape
Out[43]: (10, 1, 4)
Here the s[i]-s_m array is appended to an empty list, which has been appended to the main list. So it's an array within a list within a list. It's this intermediate list that produces the middle 1 dimension.
You are using NumPy ndarray without using the functions in NumPy, sum() is a python builtin function, you should use numpy.sum() instead.
I suggest you change your code as:
import numpy as np
np.random.seed(0)
s = np.random.randn(10, 4)
s_m = np.mean(a, axis=0, keepdims=True)
residuals_s = s - s_m
print s.shape, s_m.shape, residuals_s.shape
use mean() function with axis and keepdims arguments will give you the correct result.

Two dimensional array in python

I want to know how to declare a two dimensional array in Python.
arr = [[]]
arr[0].append("aa1")
arr[0].append("aa2")
arr[1].append("bb1")
arr[1].append("bb2")
arr[1].append("bb3")
The first two assignments work fine. But when I try to do, arr[1].append("bb1"), I get the following error:
IndexError: list index out of range.
Am I doing anything silly in trying to declare the 2-D array?
Edit:
but I do not know the number of elements in the array (both rows and columns).
You do not "declare" arrays or anything else in python. You simply assign to a (new) variable. If you want a multidimensional array, simply add a new array as an array element.
arr = []
arr.append([])
arr[0].append('aa1')
arr[0].append('aa2')
or
arr = []
arr.append(['aa1', 'aa2'])
There aren't multidimensional arrays as such in Python, what you have is a list containing other lists.
>>> arr = [[]]
>>> len(arr)
1
What you have done is declare a list containing a single list. So arr[0] contains a list but arr[1] is not defined.
You can define a list containing two lists as follows:
arr = [[],[]]
Or to define a longer list you could use:
>>> arr = [[] for _ in range(5)]
>>> arr
[[], [], [], [], []]
What you shouldn't do is this:
arr = [[]] * 3
As this puts the same list in all three places in the container list:
>>> arr[0].append('test')
>>> arr
[['test'], ['test'], ['test']]
What you're using here are not arrays, but lists (of lists).
If you want multidimensional arrays in Python, you can use Numpy arrays. You'd need to know the shape in advance.
For example:
import numpy as np
arr = np.empty((3, 2), dtype=object)
arr[0, 1] = 'abc'
You try to append to second element in array, but it does not exist.
Create it.
arr = [[]]
arr[0].append("aa1")
arr[0].append("aa2")
arr.append([])
arr[1].append("bb1")
arr[1].append("bb2")
arr[1].append("bb3")
We can create multidimensional array dynamically as follows,
Create 2 variables to read x and y from standard input:
print("Enter the value of x: ")
x=int(input())
print("Enter the value of y: ")
y=int(input())
Create an array of list with initial values filled with 0 or anything using the following code
z=[[0 for row in range(0,x)] for col in range(0,y)]
creates number of rows and columns for your array data.
Read data from standard input:
for i in range(x):
for j in range(y):
z[i][j]=input()
Display the Result:
for i in range(x):
for j in range(y):
print(z[i][j],end=' ')
print("\n")
or use another way to display above dynamically created array is,
for row in z:
print(row)
When constructing multi-dimensional lists in Python I usually use something similar to ThiefMaster's solution, but rather than appending items to index 0, then appending items to index 1, etc., I always use index -1 which is automatically the index of the last item in the array.
i.e.
arr = []
arr.append([])
arr[-1].append("aa1")
arr[-1].append("aa2")
arr.append([])
arr[-1].append("bb1")
arr[-1].append("bb2")
arr[-1].append("bb3")
will produce the 2D-array (actually a list of lists) you're after.
You can first append elements to the initialized array and then for convenience, you can convert it into a numpy array.
import numpy as np
a = [] # declare null array
a.append(['aa1']) # append elements
a.append(['aa2'])
a.append(['aa3'])
print(a)
a_np = np.asarray(a) # convert to numpy array
print(a_np)
a = [[] for index in range(1, n)]
For compititve programming
1) For input the value in an 2D-Array
row=input()
main_list=[]
for i in range(0,row):
temp_list=map(int,raw_input().split(" "))
main_list.append(temp_list)
2) For displaying 2D Array
for i in range(0,row):
for j in range(0,len(main_list[0]):
print main_list[i][j],
print
the above method did not work for me for a for loop, where I wanted to transfer data from a 2D array to a new array under an if the condition. This method would work
a_2d_list = [[1, 2], [3, 4]]
a_2d_list.append([5, 6])
print(a_2d_list)
OUTPUT - [[1, 2], [3, 4], [5, 6]]
x=3#rows
y=3#columns
a=[]#create an empty list first
for i in range(x):
a.append([0]*y)#And again append empty lists to original list
for j in range(y):
a[i][j]=input("Enter the value")
In my case I had to do this:
for index, user in enumerate(users):
table_body.append([])
table_body[index].append(user.user.id)
table_body[index].append(user.user.username)
Output:
[[1, 'john'], [2, 'bill']]

Categories

Resources