Python looping doesn't give expected output - python

I am trying to find the missing elements between arr1 and arr2 but not sure what's the issue with the code, why it's not working. Please suggest.
def miss2(arr1, arr2):
arr3=arr1
for i in arr1:
# print(i)
for j in arr2:
# print(i,j)
if i == j:
arr3.remove(j)
print(arr3)
arr1=[1,2,3,4]
arr2=[1,2]
miss2(arr1,arr2)
result:[2, 3, 4] instead of [3, 4]

Objects in Python are stored by reference,which means you didn't assign the value of arr1 to arr3, but a pointer to the object.You can use is operator to test if two objects have the same address in memory.
Sequences can be copied by slicing so you can use this to copy a list:
arr3 = arr1[:]
Also you can use
arr3 = list(arr1)
Or you can use copy() module:
from copy import copy
arr3 = copy(arr1)
By the way,you can try this:
print [i for i in arr1 if i not in arr2]

McGrady is right.
Here is an article tells you more stuff about the reference problem.
Is Python call-by-value or call-by-reference?
And you can use "set"(consider the math concept) data structure instead of "list", here:
x = set([1,2,3,4])
y = set([1,2])
x - y

Related

Get choose specific elements from an array based on list of index

A=np.array([ [7,8],[7,9],[3,4],[5,4],[3,4],[5,6] ])
indicesB=np.array([ [1] ,[1] ,[1] ,[2] ,[1] ,[2] ])
how can i get all the elements in A if the same position elements in indices B= 1?
for example,
if i want indicesB= 2,then i get[5,4],[5,6]
if i want indicesB= 1,then i get[7,8],[7,9],[3,4],[3,4]
What I want is something like this
Y=np.array([[7,8],[3,4],[3,4],[3,4],[3,4],[3,4]])
X=np.array([[1],[1],[1],[1],[1],[2]])
for x in range(1,3):
for i in range(6):
if X[i]==x:
print('the indice is ', x,Y[i])
how cccan i make it simple using numpy?
If I understand right this code might helps you:
new_list = []
for i,j in zip(A, indicesB):
el = i[:j[0]].tolist()
new_list.append(el)
If you need an array instead of list you should use i[:j[0]] without .tolist() and after loop change type new_list to array like that:
new_list = np.array(new_list)
Can you use dict ? that way you can call perticular key dict[1] and you will receive np.array.
import numpy as np
dic = {s:[] for s in set(np.concatenate([x.ravel() for x in X]))}
[dic[j.tolist()[0]].append(i.tolist()) for i,j in zip(A, B)]
np.array(dic[2]) #or np.array(dic[int(input())])
Output:
array([[5, 4],
[5, 6]])

Transform a single list into a nested list

I want to transform a single array [1,1,1,1,1,1....] into a nested list(?) or multiple arrays like [[1],[1],[1],[1],[1]...]
My code is returning this problem:
ValueError: all the input arrays must have same number of dimensionsand I believe it's because of that.
Use a list comprehension:
unnested_l = [1]*20
nest_l = [[x] for x in unnested_l]
nest_l == [[1], [1], ...] # 20 times
Since your question says "array", I am providing a solution using NumPy's newaxis
import numpy as np
arr = np.array([1,1,1,1,1,1])
arr = arr[:, None]
print (arr)
# [[1]
# [1]
# [1]
# [1]
# [1]
# [1]]
Check this
l=[1,1,1,1,1,1,1]
res=[]
for x in l:
res.append([x])
print(res)
Output:
[[1],[1],[1],[1],[1],[1],[1]]

What does [i,:] mean in Python?

So I'm finished one part of this assignment I have to do. There's only one part of the assignment that doesn't make any sense to me.
I'm doing a LinearRegression model and according to others I need to apply ans[i,:] = y_poly at the very end, but I never got an answer as to why.
Can someone please explain to me what [i,:] means? I haven't found any explanations online.
It's specific to the numpy module, used in most data science modules.
ans[i,:] = y_poly
this is assigning a vector to a slice of numpy 2D array (slice assignment). Self-contained example:
>>> import numpy
>>> a = numpy.array([[0,0,0],[1,1,1]])
>>> a[0,:] = [3,4,5]
>>> a
array([[3, 4, 5],
[1, 1, 1]])
There is also slice assignment in base python, using only one dimension (a[:] = [1,2,3])
I guess you are also using numpy to manipulate data (as a matrix)?
If based on numpy, ans[i,:] means to pick the ith 'row' of ans with all of its 'columns'.
Note: when dealing with numpy arrays, we should (almost) always use [i, j] instead of [i][j]. This might be counter-intuitive if you've used Python or Java to manipulate matrixes before.
I think in this case [] means the indexing operator for a class object which can be used by defining the getitem method
class A:
def __getitem__(self, key):
pass
key can be literally anything. In your case "[1,:]" key is a tuple containing of "1" and a slice(None, None, None). Such a key can be useful if your class represents multi-dimensional data which you want to access via [] operator. A suggested by others answers this could be a numpy array:
Here is a quick example of how such a multi-dimensional indexing could work:
class A:
values = [[1,2,3,4], [4,5,6,7]]
def __getitem__(self, key):
i, j = key
if isinstance(i, int):
i = slice(i, i + 1)
if isinstance(j, int):
j = slice(j, j + 1)
for row in self.values[i]:
print(row[j])
>>>a = A()
>>>a[:,2:4]
[3, 4]
[6, 7]
>>>a[1,1]
[5]
>>>a[:, 2]
[3]
[6]

Python2: access nested list using a list of indices

how do I access an element of a nested list with another list which contains the indices?
e.g:
# this is the variable containing the indices
a = [0, 1]
b = [[1,2],[3,4]]
in reality, these lists are filled with elements of self defined classes and the list containing the "coordinates" (a) has more than 2 elements.
Is there any possibility to access b[0][1] automatically? Previously, I used this code:
c = deepcopy(b)
for el in a:
c = c[el]
but since b is pretty big, I'd love to get rid of that deepcopy without manipulating b in reality.
I am happy about any suggestions :)
Thanks!
Just toss it in a function. That will keep it scoped so you don't overwrite the original value
def nested_getitem(container, idxs):
haystack = container
for idx in idxs:
haystack = haystack[idx]
return haystack
DEMO:
>>> a = [0, 1]
>>> b = [[1, 2], [3, 4]]
>>> nested_getitem(b, a)
2
You could probably do this with a functools.reduce as well, if you were insane.
import functools
import operator
def nested_getitem(container, idxs):
return functools.reduce(operator.getitem, idxs, container)

NumPy List Comprehension Syntax

I'd like to be able to use list comprehension syntax to work with NumPy arrays easily.
For instance, I would like something like the below obviously wrong code to just reproduce the same array.
>>> X = np.random.randn(8,4)
>>> [[X[i,j] for i in X] for j in X[i]]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: arrays used as indices must be of integer (or boolean) type
What is the easy way to do this, to avoid using range(len(X)?
First, you should not be using NumPy arrays as lists of lists.
Second, let's forget about NumPy; your listcomp doesn't make any sense in the first place, even for lists of lists.
In the inner comprehension, for i in X is going to iterate over the rows in X. Those rows aren't numbers, they're lists (or, in NumPy, 1D arrays), so X[i] makes no sense whatsoever. You may have wanted i[j] instead.
In the outer comprehension, for j in X[i] has the same problem, but is has an even bigger problem: there is no i value. You have a comprehension looping over each i inside this comprehension.
If you're confused by a comprehension, write it out as an explicit for statement, as explained in the tutorial section on List Comprehensions:
tmp = []
for j in X[i]:
tmp.append([X[i,j] for i in X])
… which expands to:
tmp = []
for j in X[i]:
tmp2 = []
for i in X:
tmp2.append(X[i,j])
tmp.append(tmp2)
… which should make it obvious what's wrong here.
I think what you wanted was:
[[cell for cell in row] for row in X]
Again, turn it back into explicit for statements:
tmp = []
for row in X;
tmp2 = []
for cell in row:
tmp2.append(cell)
tmp.append(tmp2)
That's obviously right.
Or, if you really want to use indexing (but you don't):
[[X[i][j] for j in range(len(X[i]))] for i in range(len(X))]
So, back to NumPy. In NumPy terms, that last version is:
[[X[i,j] for j in range(X.shape[1])] for i in range(X.shape[0])]
… and if you want to go in column-major order instead of row-major, you can (unlike with a list of lists):
[[X[i,j] for i in range(X.shape[0])] for j in range(X.shape[1])]
… but that will of course transpose the array, which isn't what you wanted to do.
The one thing you can't do is mix up column-major and row-major order in the same expression, because you end up with nonsense.
Of course the right way to make a copy of an array is to use the copy method:
X.copy()
Just as the right way to transpose an array is:
X.T
The easy way is to not do this. Use numpy's implicit vectorization instead. For example, if you have arrays A and B as follows:
A = numpy.array([[1, 3, 5],
[2, 4, 6],
[9, 8, 7]])
B = numpy.array([[5, 3, 5],
[3, 5, 3],
[5, 3, 5]])
then the following code using list comprehensions:
C = numpy.array([[A[i, j] * B[i, j] for j in xrange(A.shape[1])]
for i in xrange(A.shape[0])])
can be much more easily written as
C = A * B
It'll also run much faster. Generally, you will produce faster, clearer code if you don't use list comprehensions with numpy than if you do.
If you really want to use list comprehensions, standard Python list-comprehension-writing techniques apply. Iterate over the elements, not the indices:
C = numpy.array([[a*b for a, b in zip(a_row, b_row)]
for a_row, b_row in zip(A, B)]
Thus, your example code would become
numpy.array([[elem for elem in x_row] for x_row in X])
Another option (though not necessarily performant) is to rethink your problem as a map instead of a comprehension and write a ufunc:
http://docs.scipy.org/doc/numpy/reference/ufuncs.html
You can call functional-lite routines like:
http://docs.scipy.org/doc/numpy/reference/generated/numpy.apply_over_axes.html
http://docs.scipy.org/doc/numpy/reference/generated/numpy.vectorize.html
Etc.
Do you mean following?
>>> [[X[i,j] for j in range(X.shape[1])] for i in range(X.shape[0])]
[[0.62757350000000001, -0.64486080999999995, -0.18372566000000001, 0.78470704000000002],
[1.78209799, -1.336448459999999 9, -1.3851422200000001, -0.49668994],
[-0.84148266000000005, 0.18864597999999999, -1.1135151299999999, -0.40225053999999 999],
[0.93852824999999995, 0.24652238000000001, 1.1481637499999999, -0.70346624999999996],
[0.83842508000000004, 1.0058 697599999999, -0.91267403000000002, 0.97991269000000003],
[-1.4265273000000001, -0.73465904999999998, 0.6684284999999999 8, -0.21551155],
[-1.1115614599999999, -1.0035033200000001, -0.11558254, -0.4339924],
[1.8771354, -1.0189299199999999, - 0.84754008000000003, -0.35387946999999997]]
Using numpy.ndarray.copy:
>>> X.copy()
array([[ 0.6275735 , -0.64486081, -0.18372566, 0.78470704],
[ 1.78209799, -1.33644846, -1.38514222, -0.49668994],
[-0.84148266, 0.18864598, -1.11351513, -0.40225054],
[ 0.93852825, 0.24652238, 1.14816375, -0.70346625],
[ 0.83842508, 1.00586976, -0.91267403, 0.97991269],
[-1.4265273 , -0.73465905, 0.6684285 , -0.21551155],
[-1.11156146, -1.00350332, -0.11558254, -0.4339924 ],
[ 1.8771354 , -1.01892992, -0.84754008, -0.35387947]])

Categories