I have arrays like this:
x = np.array([-1,-1,-1,1,-1,-1])
weight = np.array([[0.5,-0.5,0.5,-0.5,0.5,-0.5],
[-0.5,0.5,-0.5,0.5,-0.5,0.5],
[0.5,0.5,0.5,0.5,0.5,0.5]])
print(weight.shape)
bias=np.array([2, 2, 2])
print(bias)
weight = np.transpose(weight)
weight
You can run the above code which results to arrays bias and weight_ham and x:
bias = [2 2 2]
weight = array([[ 0.5, -0.5, 0.5],
[-0.5, 0.5, 0.5],
[ 0.5, -0.5, 0.5],
[-0.5, 0.5, 0.5],
[ 0.5, -0.5, 0.5],
[-0.5, 0.5, 0.5]])
x = array([-1, -1, -1, 1, -1, -1])
Now i want to calculate this equation:
the y_in array should be like this:
y_in = np.zeros((1, len(bias)))
What i don't understand is how can i compute that equation with for loop since i'm not really familiar with how should i write for loops.
if you didn't understand the equation you can see this example below:
I don't understand why you are required to use loops when you are already working with numpy, however the correct way would be:
>>> np.add(bias, np.dot(x[None, :], weight)).flatten()
array([1., 3., 0.])
But if you want loops:
y = []
for index_1, b in enumerate(bias):
sum_ = b
for index_2, val in enumerate(x):
sum_ += x[index_2] * weight[index_2, index_1]
y.append(sum_)
>>> y
[1.0, 3.0, 0.0]
# OR
>>> [b + sum(x_val * w for x_val, w in zip(x, weight[:,i])) for i, b in enumerate(bias)]
[1.0, 3.0, 0.0]
Posting answer for your screenshot problem. You can use the same code for your original problem:
x = np.array([1,1,-1,-1])
weight = np.array([[0.5,-0.5,-0.5,-0.5],
[-0.5,-0.5,-0.5,0.5],
])
bias=np.array([2, 2])
weight = np.transpose(weight)
One Liner:
np.add(bias, np.dot(weight.T, x))
Using Loop:
y_arr = []
for j in range(weight.shape[1]):
y = (bias[j] + np.dot(weight[:,j].T, x))
y_arr.append(y)
y_arr = np.array(y_arr)
y_arr:
array([3., 1.])
Related
Let's say I have a numpy array
my_array = [0.2, 0.3, nan, nan, nan, 0.1, nan, 0.5, nan]
For each nan value, I want to extract the two non-nan values to the left and right of that point (or single value if appropriate). So I would like my output to be something like
output = [[0.3,0.1], [0.3,0.1], [0.3,0.1], [0.1,0.5], [0.5]]
I was thinking of looping through all the values in my_array, then finding those that are nan, but I'm not sure how to do the next part of finding the nearest non-nan values.
Using pandas and numpy:
s = pd.Series([0.2, 0.3, nan, nan, nan, 0.1, nan, 0.5, nan])
m = s.isna()
a = np.vstack((s.ffill()[m], s.bfill()[m]))
out = a[:,~np.isnan(a).any(0)].T.tolist()
Output:
[[0.3, 0.1], [0.3, 0.1], [0.3, 0.1], [0.1, 0.5]]
NB. You can choose to keep or drop the lists containing NaNs.
With NaNs:
out = a.T.tolist()
[[0.3, 0.1], [0.3, 0.1], [0.3, 0.1], [0.1, 0.5], [0.5, nan]]
alternative to handle the single elements:
s = pd.Series([0.2, 0.3, nan, nan, nan, 0.1, nan, 0.5, nan])
m = s.isna()
(pd
.concat((s.ffill()[m], s.bfill()[m]), axis=1)
.stack()
.groupby(level=0).agg(list)
.to_list()
)
Output:
[[0.3, 0.1], [0.3, 0.1], [0.3, 0.1], [0.1, 0.5], [0.5]]
Less elegant than #mozway's answer, but the last list only has one element:
pd.DataFrame({
'left':arr.ffill(),
'right': arr.bfill()
}).loc[arr.isna()].apply(lambda row: row.dropna().to_list(), axis=1).to_list()
For the sake of education, I'll post a pretty straight-forward algorithm for achieving this result, which works by finding the closest index of a value to the left and to the right of each index of a NaN, and filters out any infs at the end:
def get_neighbors(x: np.ndarray) -> list:
mask = np.isnan(x)
nan_idxs, *_ = np.where(mask)
val_idxs, *_ = np.where(~mask)
neighbors = []
for nan_idx in nan_idxs:
L, R = -float("inf"), float("inf")
for val_idx in val_idxs:
if val_idx < nan_idx:
L = max(L, val_idx)
else:
R = min(R, val_idx)
# casting to list isn't strictly necessary, you'll just end up with a list of arrays
neighbors.append(list(x[[i for i in (L, R) if i > 0 and i < float("inf")]]))
return neighbors
Output:
>>> get_neighbors(my_array)
[[0.3, 0.1], [0.3, 0.1], [0.3, 0.1], [0.1, 0.5], [0.5]]
The nested for loop has a worst-case runtime of O((n / 2)^2) where n is the number of elements of x (worst case occurs when exactly half the elements are NaN).
I was eager to check how could use just NumPy to solve this problem as an exercise. After some hours I could reach a solution :), but as I think it will be inefficient comparing to pandas as mentioned by Mozway, I didn't optimized the code further (it can be optimized; if conditions may could be cured and merged in other sections):
my_array = np.array([np.nan, np.nan, 0.2, 0.3, np.nan, np.nan, np.nan, 0.1, 0.7, np.nan, 0.5])
nans = np.isnan(my_array).astype(np.int8) # [1 1 0 0 1 1 1 0 0 1 0]
zeros = np.where(nans == 0)[0] # [ 2 3 7 8 10]
diff_nan = np.diff(nans) # [ 0 -1 0 1 0 0 -1 0 1 -1]
start = np.where(diff_nan == 1)[0] # [3 8]
end = np.where(diff_nan == -1)[0] + 1 # [ 2 7 10]
mask_start_nan = np.isnan(my_array[0]) # True
mask_end_nan = np.isnan(my_array[-1]) # False
if mask_end_nan: start = start[:-1] # [3 8]
if mask_start_nan: end = end[1:] # [ 7 10]
inds = np.dstack([start, end]).squeeze() # [[ 3 7] [ 8 10]]
initial = my_array[inds] # [[0.3 0.1] [0.7 0.5]]
repeats = np.diff(np.where(np.concatenate(([nans[0]], nans[:-1] != nans[1:], [True])))[0])[::2] # [2 3 1]
if mask_end_nan: repeats = repeats[:-1] # [2 3 1]
if mask_start_nan: repeats = repeats[1:] # [3 1]
result = np.repeat(initial, repeats, axis=0) # [[0.3 0.1] [0.3 0.1] [0.3 0.1] [0.7 0.5]]
if mask_end_nan: result = np.array([*result, np.array(my_array[zeros[-1]])], dtype=object)
if mask_start_nan: result = np.array([np.array(my_array[zeros[0]]), *result], dtype=object)
# [array(0.2) array([0.3, 0.1]) array([0.3, 0.1]) array([0.3, 0.1]) array([0.7, 0.5])]
I don't know if there be a much easier solution by NumPy; I implemented what came to my mind. I believe that this code can be greatly improved (I will do it if I find a free time).
I'm having the following relatively simple problem. I have two arrays storing x and y coordinates per timestep, e.g.
x = [[0, 1, 2, 3], [0.1, 1.1, 2.1, 3.1]]
y = [[0.5, 0.5, 0.5, 0.5], [0.51, 0.52, 0.49, 0.53]]
in which 2 timesteps are represented (2 rows). What I would like is to find the maximum y coordinate per row when the condition x >= 1 and x <= 2.5 is met.
How can I define a function which returns an array of 2 columns with just the max(y) per row when the spatial x condition is met?
I've tried np.where without luck. The result the function should return is:
[0.5, 0.52]
You can use numpy's mask function. The mask function 'masks' the true values, so the conditions are flipped.
import numpy as np
x = [[0, 1, 2, 3], [0.1, 1.1, 2.1, 3.1]]
y = [[0.5, 0.5, 0.5, 0.5], [0.51, 0.52, 0.49, 0.53]]
x = np.array(x)
y = np.array(y)
y_masked = np.ma.masked_where((x>2.5) | (x<1), y)
result = np.max(y_masked, axis = 1)
print(result)
Not very pretty, but using pure Python (no numpy) you could combine zip, filter, and max:
>>> x = [[0,1,2,3],[0.1,1.1,2.1,3.1]]
>>> y = [[0.5,0.5,0.5,0.5],[0.51,0.52,0.49,0.53]]
>>> [max(filter(lambda t: 1.0 <= t[0] <= 2.5, zip(rx, ry)), key=lambda t: t[1])[1]
... for rx, ry in zip(x, y)]
...
[0.5, 0.52]
Or a bit shorter, using a list comprehension to filter and reverse order of the tuple so max can use natural ordering:
>>> [max((y, x) for (x, y) in zip(rx, ry) if 1.0 <= x <= 2.5)[0]
... for rx, ry in zip(x, y)]
...
[0.5, 0.52]
As you were suggesting a Numpy solution:
import numpy as np
x = np.array([[0, 1, 2, 3], [0.1, 1.1, 2.1, 3.1]])
y = np.array([[0.5, 0.5, 0.5, 0.5], [0.51, 0.52, 0.49, 0.53]])
print([np.max(y[i][(x[i] >= 1) & (x[i] <= 2.5)]) for i in range(len(x))])
gives
[0.5, 0.52]
I have a torch tensor a of shape (x, n) and another tensor b of shape (y, n) where y <= x. every column of b contains a sequence of row indices for a and what I would like to be able to do is to somehow index a with b such that I obtain a tensor of shape (y, n) in which the ith column contains a[:, i][b[:, i]] (not quite sure if that's the correct way to express it).
Here's an example (where x = 5, y = 3 and n = 4):
import torch
a = torch.Tensor(
[[0.1, 0.2, 0.3, 0.4],
[0.6, 0.7, 0.8, 0.9],
[1.1, 1.2, 1.3, 1.4],
[1.6, 1.7, 1.8, 1.9],
[2.1, 2.2, 2.3, 2.4]]
)
b = torch.LongTensor(
[[0, 3, 1, 2],
[2, 2, 2, 0],
[1, 1, 0, 4]]
)
# How do I get from a and b to c
# (so that I can also assign to those elements in a)?
c = torch.Tensor(
[[0.1, 1.7, 0.8, 1.4],
[1.1, 1.2, 1.3, 0.4],
[0.6, 0.7, 0.3, 2.4]]
)
I can't get my head around this. What I'm looking for is a method that will not yield the tensor c but also let me assign a tensor of the same shape as c to the elements of a which c is made up of.
I try to use index_select but it supports only 1-dim array for index.
bt = b.transpose(0, 1)
at = a.transpose(0, 1)
ct = [torch.index_select(at[i], dim=0, index=bt[i]) for i in range(len(at))]
c = torch.stack(ct).transpose(0, 1)
print(c)
"""
tensor([[0.1000, 1.7000, 0.8000, 1.4000],
[1.1000, 1.2000, 1.3000, 0.4000],
[0.6000, 0.7000, 0.3000, 2.4000]])
"""
It might be not the best solution, but hope this helps you at least.
I tried to define a function (tent map) as following:
def f(r, x):
return np.piecewise([r, x], [x < 0.5, x >= 0.5], [lambda r, x: 2*r*x, lambda r, x: 2*r*(1-x)])
And r, x will be numpy arrays:
no_r = 10001
r = np.linspace(0, 4, no_r)
x = np.random.rand(no_r)
I would like the result to be a numpy array matching the shapes of r and x, calculated using each pairs of elements of arrays r and x with the same indicies. For example if r = [0, 1, 2, 3] and x = [0.1, 0.7, 0.3, 1], the result should be [0, 0.6, 1.2, 0].
An error occured: "boolean index did not match indexed array along dimension 0; dimension is 2 but corresponding boolean dimension is 10001"
So what should I do to achieve the intended purpose?
what you want to get as result can be done with np.select such as:
def f(r, x):
return np.select([x < 0.5,x >= 0.5], [2*r*x, 2*r*(1-x)])
Then with
r = np.array([0, 1, 2, 3])
x = np.array([0.1, 0.7, 0.3, 1])
print (f(r,x))
[0. 0.6 1.2 0. ]
EDIT: in this case, with only 2 conditions that are exclusive, you can also use np.where:
def f(r,x):
return np.where(x<0.5,2*r*x, 2*r*(1-x))
will give the same result.
I'm trying to solve the following linear programming problem in Python 2.7 and for some reason, linprog is not returning the correct results.
Minimize: -x2 -x3
such that:
x0 + 0.33*x2 + 0.67*x3 = 0.5
x1 + 0.67*x2 + 0.33*x3 = 0.5
x0 + x1 + x2 + x3 = 1.0
Here's my code:
from scipy.optimize import linprog
a_eq = [[1.0, 0.0, 0.33, 0.67],
[0.0, 1.0, 0.67, 0.33],
[1, 1, 1, 1]]
b_eq = [0.5, 0.5, 1.0]
c = [0, 0, -1.0, -1.0]
x = linprog(c=c, A_eq=a_eq, b_eq=b_eq)
print x
Here's the output of the above:
fun: -0.0
message: 'Optimization terminated successfully.'
nit: 4
slack: array([], dtype=float64)
status: 0
success: True
x: array([ 0.5, 0.5, 0. , 0. ])
Clearly, the following solution is more optimal:
x: array([0.0, 0.0, 0.5, 0.5])
which makes the objective function value:
fun: -1.0
I did find some issues reported in github. Could this be what I'm facing or am I doing something wrong? Any help will be greatly appreciated! Thanks.
I did find some issues reported in github. Could this be what I'm facing...?
Exactly:
It turns out that A_eq in the problem is rank-deficient. After finding and removing rows that are a linear combination of others, linprog's solution agrees with the other.
The matrix a_eq is rank deficient. The last row is a linear combination of the first two rows. This makes the row redundant for the constraint so we can simply remove it and the corresponding entry in b_eq:
a_eq = [[1.0, 0.0, 0.33, 0.67],
[0.0, 1.0, 0.67, 0.33]]
b_eq = [0.5, 0.5]
This results in the optimal solution x: array([ 0. , 0. , 0.5, 0.5]).