Condition on numpy arrays - python

I have two arrays with the same number of elements
X = [1,2,3,4,5,6,7,8,9]
Y = [10,4,3,7,7,3,1,8,98]
I would like to keep the elements of X and Y such as 2<X<7. How can I do?
Ok it works well with
Y = Y[np.logical_and(X>2, X<5)]
X = X[np.logical_and(X>2, X<5)]
Thanks a lot!

You can use numpy.logical_and:
>>> X = np.array([1,2,3,4,5,6,7,8,9])
>>> X[np.logical_and(X>2, X<7)]
array([3, 4, 5, 6])

you can use a loop and if ,and also you can use set() for keep the deferent indexes :
>>> X = [1,2,3,4,5,6,7,8,9]
>>> Y = [10,4,3,7,7,3,1,8,98]
>>> X=[i for i in X if 2<i<7]
>>> Y=[i for i in Y if 2<i<7]
>>> X
[3, 4, 5, 6]
>>> Y
[4, 3, 3]
>>> set(Y)
set([3, 4])

Related

Inconsistent Numpy array aliasing behavior

The following behavior is expected and is what I get. This is consistent with how aliasing works for native Python objects like lists.
>>> x = np.array([1, 2, 3])
>>> y = x
>>> x
array([1, 2, 3])
>>> y
array([1, 2, 3])
>>> x = x + np.array([2, 3, 4])
>>> x
array([3, 5, 7])
>>> y
array([1, 2, 3])
But the following behavior is unexpected by changing x = x + np.array([2, 3, 4]) to x += np.array([2, 3, 4])
>>> x += np.array([2, 3, 4])
>>> x
array([3, 5, 7])
>>> y
array([3, 5, 7])
The Numpy version is 1.16.4 on my machine. Is this a bug or feature? If it is a feature how x = x + np.array([2, 3, 4]) differs from x += np.array([2, 3, 4])
Your line y = x doesn't create a copy of the array; it simply tells y to point to the same data as x, which you can see if you look at their ids:
x = np.array([1,2,3])
y = x
print(id(x), id(y))
(140644627505280, 140644627505280)
x = x + np.array([2, 3, 4]) will do a reassignment of x to a new id, while x += np.array([2, 3, 4]) will modify it in place. Thus, the += will also modify y, while x = x + ... won't.
x += np.array([2, 3, 4])
print(id(x))
print(x, y)
x = x + np.array([2, 3, 4])
print(id(x))
print(x, y)
140644627505280
[3 5 7] [3 5 7]
140644627175744
[ 5 8 11] [3 5 7]

Splitting columns of a numpy array easily

How can I split an array's columns into three arrays x, y, z without manually writing each of the [:,0],[:,1],[:,2] separately?
Example
# Create example np array
import numpy as np
data = np.array([[1,2,3],[4,5,6],[7,8,9]])
Now data is
[[1 2 3]
[4 5 6]
[7 8 9]]
What I want to do:
x, y, z = data[:,0], data[:,1], data[:,2] ## Help me here!
print(x)
Wanted output:
array([1, 4, 7])
Transpose, then unpack:
>>> x, y, z = data.T
>>> x
array([1, 4, 7])
You don't need to slice it.
>>> import numpy as np
>>> data = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> x, y, z = data.T
>>> x
array([1, 4, 7])
>>> y
array([2, 5, 8])
>>> z
array([3, 6, 9])

How can I have references of lists in Python

Say I have two following lists.
x = [1, 2, 3]
y = [4, 5, 6]
Now I want a list that contains references to these lists,
So instead of wanting
z = [x, y] -> [[1, 2, 3], [4, 5, 6]]
I want the following
z = [ref of x, ref of y]
How can I achieve that in Python?
z = [x, y] is the way to use references:
>>> x = [1, 2, 3]
>>> y = [4, 5, 6]
>>> z = [x, y]
>>> x[0] = 0
>>> z
[[0, 2, 3], [4, 5, 6]]
If you want to copy, use the slice notation or the copy module:
>>> z=[x[:],y[:]]
>>> x[0] = 11
>>> x
[11, 2, 3]
>>> z
[[0, 2, 3], [4, 5, 6]]
z=[x,y] keeps the references, not the copies. This can be proved as:
>>> x = [1, 2, 3]
>>> y = [4, 5, 6]
>>> id(x),id(y)
(139643028466504, 139643028484320)
>>> z=[x,y]
>>> id(z[0]),id(z[1])
(139643028466504, 139643028484320)
As you can see addresses of x and y are similar to addresses z[0] and z[1], which clearly is the definition of reference.

Python lists Ids

Why is the id is of x changes in the following code while it still has the same value. I expect the id for x and z should be same in this case as the value remains the same at the end.
>>> x = [1, 2, 3]
>>> z = x
>>> id(z) == id(x)
True
>>> x = [1, 2, 3]
>>> id(z) == id(x)
False
>>> x
[1, 2, 3]
>>> z
[1, 2, 3]
>>>
What an object holds has nothing to do with its identity. id(x) == id(y) if and only if x and y both refer to the same object.
Maybe this example helps:
x = [1, 2, 3]
y = [1, 2, 3]
z = y
print x, y, z
y[0] = 1000
print x, y, z
which prints this:
[1, 2, 3] [1, 2, 3] [1, 2, 3]
[1, 2, 3] [1000, 2, 3] [1000, 2, 3]
y and z both refer to the same object, so modifying one variable modifies the value retrieved by the other, too. x remains the same because it's a separate object.
What you shouldn't forget is that initializing a variable with a literal list (like [1, 2, 3]) creates a new list object.
Whether or not the two lists contain the same elements does not imply that they should have the same id.
Two variables only have the same id if they refer to the same object, which the second z and x do not:
>>> x = [1, 2, 3]
>>> z = [1, 2, 3]
>>> x[0] = 999
>>> x
[999, 2, 3]
>>> z
[1, 2, 3]
This demonstrates that x and z are two distinct, unrelated lists.

Python not all in operation

How do I check if a list is a subset of a bigger list.
i.e.
a = [1,2,3] is a subset of b = [1,2,3,4,5,6]
Can I do something like
if a all in b
http://docs.python.org/library/stdtypes.html#set.issubset
set(a).issubset(set(b))
>>> a = set([1, 2, 3])
>>> b = set([1, 2, 3, 4, 5, 6])
>>> a.issubset(b)
True
or
>>> a = [1, 2, 3]
>>> b = [1, 2, 3, 4, 5, 6]
>>> all(map(lambda x: x in b, a))
True
>>> a = [1, 2, 3, 9]
>>> all(map(lambda x: x in b, a))
False
or (if the number of elements is important)
>>> a = [1, 1, 2, 3]
>>> all(map(lambda x: a.count(x) <= b.count(x), a))
False
mostly like the other answers, but I do prefer the generator syntax here, seems more natural and it's lazily evaluated:
if all(x in b for x in a):
pass
if you care about the number of repeated elements, this option seems nice, and you could optimize it sorting c and using bisect:
def all_in(a, b)
try:
c = b[:]
for x in a: c.remove[x]
return True
except:
return False

Categories