I have two arrays with the same dimension:
a = [
[1, 1, 1, 1],
[1, 0, 0, 1],
[1, 0, 0, 1],
[1, 1, 1, 1], ]
b = [
[0, 1, 1, 0],
[0, 0, 0, 0],
[2, 0, 0, 2],
[0, 0, 0, 0], ]
I would like to create a new one, only changing the values where B is not 0 and is different than A. The result would be:
c = [
[1, 1, 1, 1],
[1, 0, 0, 1],
[2, 0, 0, 2],
[1, 1, 1, 1], ]
How can I do this?
You can do assignment with boolean conditions:
a[b != 0] = b[b != 0]
a
array([[1, 1, 1, 1],
[1, 0, 0, 1],
[2, 0, 0, 2],
[1, 1, 1, 1]])
Here is one that I find easy to parse:
>>> np.where(b,b,a)
array([[1, 1, 1, 1],
[1, 0, 0, 1],
[2, 0, 0, 2],
[1, 1, 1, 1]])
This picks each value from either the third or second arguments based on whether the first argument is zero or not.
You don't need numpy. Here is a solution you can actually read line by line:
a = [
[1, 1, 1, 1],
[1, 0, 0, 1],
[1, 0, 0, 1],
[1, 1, 1, 1], ]
b = [
[0, 1, 1, 0],
[0, 0, 0, 0],
[2, 0, 0, 2],
[0, 0, 0, 0], ]
c = a[:]
#I would like to create a new one, only changing the values where B is not 0 and is different than A. The result would be:
for lineindex,line in enumerate(a):
for index,x in enumerate(line):
if x != b[lineindex][index] and b[lineindex][index] != 0:
c[lineindex][index] = b[lineindex][index]
print(c)
Related
Suppose I have the following numpy array:
a = np.array([[1, 1, 0, 0, 1],
[1, 1, 0, 0, 0],
[1, 0, 0, 1, 1],
[1, 1, 0, 0, 0],
[1, 1, 0, 0, 0],
[1, 1, 0, 0, 0],
[0, 0, 0, 1, 0],
[1, 1, 0, 0, 0],
[1, 1, 0, 0, 0],
[1, 1, 1, 0, 1],
[1, 1, 0, 0, 0],
[1, 1, 0, 0, 1],
[1, 1, 0, 0, 0],
[1, 0, 0, 1, 0],
[1, 0, 1, 1, 0]])
I want to select only the rows, where column with index 1 have value 1 and column with index 2 have value 0.
i tried the following:
evidence = {1:1,2:0}
mask = a[:,list(evidence.keys())] == list(evidence.values())
But after that i am stuck.
how can I do it in numpy 2-D array?
Try:
out = a[(a[:, 1] == 1) & (a[:, 2] == 0)]
Given a dictionary of column, value pairs, you could use:
evidence = {1:1,2:0}
out = a[ np.logical_and.reduce([a[:, c] == v for c, v in evidence.items()]) ]
which generalizes the above solution to a sequence of &.
For example, I have a list which only contains zeroes, ones and twos
ls = [
[1, 1, 0, 2, 2],
[1, 1, 1, 2, 2, 2],
[0, 1, 0, 0, 0, 2, 0]
]
I want to split this list it into two list,
ls1 contains the ones, and ls2 contains the twos. I would like to keep the shape and use 0 to replace 2's in ls1 and 1's in ls2. The expected result is:
ls1 = [
[1, 1, 0, 0, 0],
[1, 1, 1, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0]
]
ls2 = [
[0, 0, 0, 2, 2],
[0, 0, 0, 2, 2, 2],
[0, 0, 0, 0, 0, 2, 0]
]
I know I can use a for loop to handle it, but is there an elegant way?
ls1, ls2 = ([[b & x for b in a] for a in ls] for x in (1, 2))
Using nested list comprehension:
ls1 = [[1 if e == 1 else 0 for e in l] for l in ls]
ls2 = [[2 if e == 2 else 0 for e in l] for l in ls]
# ls1
[[1, 1, 0, 0, 0],
[1, 1, 1, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0]]
# ls2
[[0, 0, 0, 2, 2],
[0, 0, 0, 2, 2, 2],
[0, 0, 0, 0, 0, 2, 0]]
Nothing especially "elegant" about it, but you could simply use a list comprehension:
ls = [
[1, 1, 0, 2, 2],
[1, 1, 1, 2, 2, 2],
[0, 1, 0, 0, 0, 2, 0]
]
def keep_only(val, lst):
return [[v if v==val else 0 for v in sublist] for sublist in lst]
ls1 = keep_only(1, ls)
ls2 = keep_only(2, ls)
Output:
print(ls1)
print(ls2)
# [[1, 1, 0, 0, 0], [1, 1, 1, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0]]
# [[0, 0, 0, 2, 2], [0, 0, 0, 2, 2, 2], [0, 0, 0, 0, 0, 2, 0]]
I've got success/failure data on several simulations. Each simulation consists of several trials and I want a cumulative sum of the successes per simulation. Here's an example of my data:
data = pd.DataFrame([[0, 0, 0],
[0, 1, 0],
[0, 2, 1],
[0, 3, 0],
[1, 0, 1],
[1, 1, 0],
[1, 2, 0],
[1, 3, 1],
[2, 0, 0],
[2, 1, 1],
[2, 2, 1],
[2, 3, 1],
[0, 0, 0],
[0, 1, 1],
[0, 2, 1],
[0, 3, 0]],
columns=['simulation', 'trial', 'success'])
Using this answer, I came up with the following code but it isn't quite working and I can't figure out why.
cumsum = data['success'].cumsum()
reset = -cumsum[data['trial'] == 0].diff().fillna(cumsum)
data['cumsum'] = data['success'].where(data['trial'] != 0, reset).cumsum()
The resulting column is [0, 0, 1, 1, -1, -1, -1, 0, -1, 0, 1, 2, -1, 0, 1, 1] but I expect [0, 0, 1, 1, 1, 1, 1, 2, 0, 1, 2, 3, 0, 1, 2, 2]
You can do groupby 'simulation' & then cumsum the 'success'.
data.groupby(data.simulation.ne(data.simulation.shift()).cumsum())['success'].cumsum()
or
data.groupby((data.simulation!=data.simulation.shift()).cumsum())['success'].cumsum()
Matrix A:
A = np.array([[3, 0, 0, 8, 3],
[9, 3, 2, 2, 6],
[5, 5, 4, 2, 8],
[3, 8, 7, 1, 2],
[3, 9, 1, 5, 5]])
Matrix B: values in each row means the index of each row in matrix A.
B = np.array([[1, 2],
[3, 4],
[1, 3],
[0, 1],
[2, 3]])
We will set values in A whose index are in B to 1, others to 0.
Then the result will be:
A = np.array([[0, 1, 1, 0, 0],
[0, 0, 0, 1, 1],
[0, 1, 0, 1, 0],
[1, 1, 0, 0, 0],
[0, 0, 1, 1, 0]])
I don't want to use for loop, how can I do it with numpy?
We can index using arrays. For axis0, we just make a range for 0-len(B) to cover each row. Then for axis1, we transpose B to represent all the column indices we want to access.
>>> C = np.zeros_like(A)
>>> C[np.arange(len(B)), B.T] = 1
>>> C
array([[0, 1, 1, 0, 0],
[0, 0, 0, 1, 1],
[0, 1, 0, 1, 0],
[1, 1, 0, 0, 0],
[0, 0, 1, 1, 0]])
>>> B = np.array([[1, 2],
... [3, 4],
... [1, 3],
... [0, 1],
... [2, 3]])
Convenient but a bit wasteful
>>> np.identity(5,int)[B].sum(1)
array([[0, 1, 1, 0, 0],
[0, 0, 0, 1, 1],
[0, 1, 0, 1, 0],
[1, 1, 0, 0, 0],
[0, 0, 1, 1, 0]])
More economical but also more typing
>>> out = np.zeros((5,5),int)
>>> out[np.c_[:5],B] = 1
>>> out
array([[0, 1, 1, 0, 0],
[0, 0, 0, 1, 1],
[0, 1, 0, 1, 0],
[1, 1, 0, 0, 0],
[0, 0, 1, 1, 0]])
What am I doing wrong?
N=[1, 2, 3, 4, 5, 6]
A=[[1, 2], [1, 3], [1, 5], [2, 3], [2, 4], [3, 4], [3, 5], [4, 6], [5, 6]]
for i in range (len(N)):
for j in range (len(N)):
my_list1 = [i[0] for i in A]
my_list2 = [i[1] for i in A]
print my_list1
print my_list2
I am not getting this output instead im getting [1, 1, 1, 2, 2, 3, 3, 4, 5]
repeated multiply times
ADJ=[[0, 1, 1, 0, 1, 0], [0, 0, 1, 1, 0, 0], [0, 0, 0, 1, 1, 0], \
[0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0]]
The simplest way to approach this requires building an empty adjacency matrix first, then populating it with a single pass through A. Here's a simple example that ignores the contents of N.
#!/usr/bin/env python
def show(matrix):
for row in matrix:
print row
print
N = [1, 2, 3, 4, 5, 6]
A = [[1, 2], [1, 3], [1, 5], [2, 3], [2, 4], [3, 4], [3, 5], [4, 6], [5, 6]]
adj_target = [
[0, 1, 1, 0, 1, 0],
[0, 0, 1, 1, 0, 0],
[0, 0, 0, 1, 1, 0],
[0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0]
]
show(adj_target)
size = len(N)
adj = [[0]*size for _ in range(size)]
#show(adj)
for u,v in A:
adj[u-1][v-1] += 1
show(adj)
print adj == adj_target
output
[0, 1, 1, 0, 1, 0]
[0, 0, 1, 1, 0, 0]
[0, 0, 0, 1, 1, 0]
[0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 0, 0]
[0, 1, 1, 0, 1, 0]
[0, 0, 1, 1, 0, 0]
[0, 0, 0, 1, 1, 0]
[0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 0, 0]
True