How can I put 2d array to 2d array in numpy? - matrix

I have the following code
a_alpha_beta = zeros((2, len( atime ) ))
for i in range( len( atime ) ):
alpha_beta = transf.clarke(signal[0][i], signal[1][i], signal[2][i])
a_alpha_beta[0][i] = alpha_beta[0][0]
a_alpha_beta[1][i] = alpha_beta[1][0]
How can I optimize the code above, for example how can I copy alpha_beta to a_alpha_beta?

I don't exactly know what the function transf.clarke does, but copy operations that you desire can be done as follows:
import numpy as np
# generate a test input
x = np.arange(0, 10).reshape((2, 5))
print x
# simply copy 2d array
y = x.copy()
print y
# some new data (i.e., alpha_beta in the original code)
z = np.array([[10, 11, 12],
[13, 14, 15]])
print z
# replace the iteration by numpy slicing to obtain the same result
x[0, :] = z[0, 0]
x[1, :] = z[1, 0]
print x

Related

populate array with random numbers

I have the following array:
nums = [10, 20, 30, 40, 50]
and another array that must have 3 items:
arr = [1]
How can I get one or two items from nums array (random) to populate arr that must have 3 elements?
Use Array.sample
arr.concat num.sample(2)
nums = [10, 20, 30, 40, 50]
arr = [1]
2.times { arr << nums.sample }
Instead of sample(2) it's better to use sample without argument I think
Because sample with argument returns array with not repeated elements (with not repeated indices to be more precise)
That is, it is more random :)
Read more
You can shuffle the array and take the first three elements to ensure you don't have repeats.
arr = nums.shuffle.take(3)
If, for instance, you were dealing with a situation like a card game where you need to draw from a shuffled deck more than once, you might want to store the shuffled array, and then pop from it.
shuffled = arr.shuffle
arr = shuffled.pop(3)
# shuffled now only has the remaining two elements
Here are two ways to obtain a statistically random sample (subject to the impossibility of computing a truly random number).
The first is to select three elements at random and accept it if it contains at most two distinct elements. If it contains three distinct elements reject it and try again.
def doit(arr)
loop do
a = Array.new(3) { arr.sample }
return a if a.uniq.size <= 2
end
end
nums = [10, 20, 30, 40, 50]
doit nums #=> [40, 40, 10]
doit nums #=> [20, 50, 20]
doit nums #=> [50, 50, 20]
The second way is to make a probability calculation. Firstly, I assume that nums contains unique elements. (That assumption is not a deal-breaker but it avoids the messiness of dealing with the more complex case.)
n = nums.size
= 5
First compute the probability of drawing one distinct element (e.g., [30, 30, 30]).
P[N1] = (1/n)(1/n)
= (1/5)(1/5)
= 1/25
= 0.04
Note the first element drawn can be anything, then the second and third draws must match the first draw, the probability of each being 1/5.
Next compute the probability of drawing three distinct elements:
P[N3] = ((n-1)/n)*((n-2)/n)
= (n-1)*(n-2)/n**2
= 4*3/5**2
= 12/25
= 0.48
Again, the first element can be anything. The probability of the second element drawn being different is (n-1)/n and the probability of the third element drawn being different than the first two
is (n-1)/n.
Lastly, if N2 is the event in which exactly two of the three elements drawn are unique we have
P[N1] + P[N2] + P[N3] = 1
so
P[N2] = 1 - P[N1] - P[N3]
= 1 - 0.04 - 0.48
= 0.48
We therefore may compute
P[N1|N1 or N2] = P[N1 and (N1 or N2)]/P[N1 or N2]
P[N1|N1 or N2] = P[N1]/P[N1 or N2]
= 0.04/(0.04 + 0.48)
= 0.04/0.52
= 0.0769
Therefore,
P[N2|N1 or N2] = 1 - P[N1|N1 or N2]
= 1 - 0.0769
= 0.9231
We therefore may write the following to obtain a statistically random sample.
def doit(arr)
if rand < 0.0769
n = arr.sample
[n, n, n]
else
n1 = arr.sample
n2 = (arr - [n1]).sample
[n1, n2, n2]
end
end
doit nums #=> [40, 40, 40]
doit nums #=> [10, 20, 20]
doit nums #=> [10, 20, 20]

How can I plot different types of seaborn plots on different x ticks?

I want to have multiple types of seaborn plots using the same y axis but with different x coordinates (see image below).
I've tried doing this multiple different ways with specifying the X-axis coordinates differently but can't seem to get it to work.
Here is an example of almost working code
x=[1,2,3,3,3,4,4,5,5,6] # first violin
y=[4,4,5,5,5,5,6] # second violin
z=[5,5,6] # swarmplot over second violin
for data,label in [(x,'x'),(y,'y'),(z,'z')]:
for i in data:
c2v['value'].append(i)
c2v['key'].append(label)
data=pd.DataFrame(c2v)
data.head()
print(data.loc[data.key=='z'])
fig,ax=plt.subplots(1,figsize=(5,5),dpi=200)
ax = sns.violinplot(data=data.loc[data.key.isin(['x','y'])], x='key', y='value',palette=['honeydew','lightgreen'])
sns.swarmplot(x=['swarmplot']*len(data), y=data['value'], order=ax.get_xticklabels() + ['swarmplot'], ax=ax) #.loc[data.key=='z',:]
ax.set_xlabel('')
It produces the following image:
However, it is plotting all values associated with x/y/z instead of just z. When I slice the dataframe to only 'z' in the swarmplot as below, I get an error:
sns.swarmplot(x=['swarmplot']*len(data), y=data.loc[data.key=='z',:]['value'], order=ax.get_xticklabels() + ['swarmplot'], ax=ax)
KeyError: 'swarmplot'
Any suggestions?
To draw a second plot onto the same x-axis, you can use order= giving a list of existing tick labels, appending the new labels.
Here is an example:
import seaborn as sns
tips = sns.load_dataset('tips')
ax = sns.swarmplot(data=tips, x='day', y='total_bill')
sns.violinplot(x=['violin']*len(tips), y=tips['total_bill'], order=ax.get_xticklabels() + ['violin'], ax=ax)
ax.set_xlabel('')
The problem with the code in the new question, is that the x= and y= of the swarmplot need the same number of elements. It also seems the swarmplot resets the y limits, so I added some code to readjust those:
from matplotlib import pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
x = [1, 2, 3, 3, 3, 4, 4, 5, 5, 6] # first violin
y = [4, 4, 5, 5, 5, 5, 6] # second violin
z = [5, 5, 6] # swarmplot over second violin
data = pd.DataFrame({'value': np.concatenate([x, y, z]),
'key': ['x'] * len(x) + ['y'] * len(y) + ['z'] * len(z)})
fig, ax = plt.subplots(1, figsize=(5, 5))
ax = sns.violinplot(data=data.loc[data.key.isin(['x', 'y'])], x='key', y='value', palette=['honeydew', 'lightgreen'])
ymin1, ymax1 = ax.get_ylim()
swarm_data = data.loc[data.key == 'z', :]['value']
sns.swarmplot(x=['swarmplot'] * len(swarm_data), y=swarm_data, order=ax.get_xticklabels() + ['swarmplot'], ax=ax)
ymin2, ymax2 = ax.get_ylim()
ax.set_ylim(min(ymin1, ymin2), max(ymax1, ymax2))
ax.set_xlabel('')
ax.set_xticks(np.arange(3))
ax.set_xticklabels(['x', 'y', 'swarmplot'])
plt.show()
You can simplify things by directly using the data without creating a dataframe:
x = [1, 2, 3, 3, 3, 4, 4, 5, 5, 6] # first violin
y = [4, 4, 5, 5, 5, 5, 6] # second violin
z = [5, 5, 6] # swarmplot over second violin
fig, ax = plt.subplots(1, figsize=(5, 5))
ax = sns.violinplot(x=['x']*len(x) + ['y']*len(y), y=x + y, palette=['honeydew', 'lightgreen'])
ymin1, ymax1 = ax.get_ylim()
sns.swarmplot(x=['swarmplot'] * len(z), y=z, order=ax.get_xticklabels() + ['swarmplot'], ax=ax)
ymin2, ymax2 = ax.get_ylim()
ax.set_ylim(min(ymin1, ymin2), max(ymax1, ymax2))
ax.set_xticks(np.arange(3))
ax.set_xticklabels(['x', 'y', 'swarmplot'])
plt.show()

Is there a hold value until condition function in numpy?

For example something like:
pre_hold_list = [-2,0,0,-1,0,0,0,3,0,0]
hold_condition = lambda x:x != 0
output = np.hold(pre_hold_list, hold_condition)
[-2,-2,-2,-1,-1,-1,-1,3,3,3] #result of output
Here the condition is that the current value is not zero the function will hold the value that this condition is met until the next value that meets this condition (i.e. it will hold -2 then -1 then 3).
Searching for np.hold() or np.step() does not give me anything on google.
Nevermind I coded a function that does this using the cumulative nature of cumsum and diff. If there's a way to improve this please let me know.
def holdtil(x, condition):
condition_index = np.where(condition)[0]
condition_value = np.take(x, condition_index)
condition_value_diff = np.diff(condition_value)
holdtil_diff = np.zeros(len(x))
holdtil_diff[condition_index[0]] = condition_value[0]
holdtil_diff[condition_index[1:]] = condition_value_diff
return np.cumsum(holdtil_diff)
EDIT:
I did a performance check between my solution and #Willem Van Onsem and mine has a very slight edge in time.
def hold_func():
start = time.time()
for i in range(1000):
x = np.random.randint(-5, 5, 1000)
hold(x, x != 0)
print(time.time() - start)
def holdtil_func():
start = time.time()
for i in range(1000):
x = np.random.randint(-5, 5, 1000)
holdtil(x, x != 0)
print(time.time() - start)
hold_func()
holdtil_func()
#0.055173397064208984
#0.045740604400634766
You could use a trick here by using cumsum(..) [numpy-doc], and diff() [numpy-doc]:
import numpy as np
def hold(iterable, condition):
cond = np.array(condition)
vals = np.array(iterable)
a = vals * cond
a[cond] = np.diff(np.hstack(((0,), a[cond])))
return a.cumsum()
The first parameter is an iterable that contains the elements, the second parameter condition is an iterable of the same length with booleans.
For example:
>>> a
array([-2, 0, 0, -1, 0, 0, 0, 3, 0, 0])
>>> hold(a, a != 0)
array([-2, -2, -2, -1, -1, -1, -1, 3, 3, 3])
>>> hold(a, a != 0)
array([-2, -2, -2, -1, -1, -1, -1, 3, 3, 3])
The function works as follows. Furst we make a copy of the two iterables (and convert these to numpy arrays, if that is not yet the case). You can omit that if these are numpy arrays.
Next we perform an elementwise multiplication, to make the values where the condition does not hold zero.
Next we calculate the difference between each item where the condition holds and the next one, and we set that to a. Finally we can use the cummulative sum of a, since the .diff() ensured that this will result in the correct repetitions.

ruby enumerators: immediately skip multiple iterations (or start iterating from n)

I'm iterating over permutations of a list (18 items) like this:
List = [item0..item18] # (unpredictable)
Permutation_size = 7
Start_at = 200_000_000
for item, i in List.repeated_permutation(Permutation_size).each_with_index
next if i < Start_at
# do stuff
end
Start_at is used to resume from a previously saved state so it's always different but it takes almost 200s to reach 200 million so I'm wondering if there is a faster way to skip multiple iterations or start at iteration n (converting the enumerator to an array takes even longer). If not, a way to create a custom repeated_permutation(n).each_with_index (that yields results in the same order) would also be appreciated.
Feel free to redirect me to an existing answer (I haven't found any)
PS. (what I had come up with)
class Array
def rep_per_with_index len, start_at = 0
b = size
raise 'btl' if b > 36
counter = [0]*len
# counter = (start_at.to_s b).split('').map {|i| '0123456789'.include?(i) ? i.to_i : (i.ord - 87)} #this is weird, your way is way faster
start_at.to_s(b).chars.map {|i| i.to_i b}
counter.unshift *[0]*(len - counter.length)
counter.reverse!
i = start_at
Enumerator.new do |y|
loop do
y << [counter.reverse.map {|i| self[i]}, i]
i += 1
counter[0] += 1
counter.each_with_index do |v, i|
if v >= b
if i == len - 1
raise StopIteration
else
counter[i] = 0
counter[i + 1] += 1
end
else
break
end
end
end
end
end
end
I first construct a helper method, change_base, with three arguments:
off, the base-10 offset into the sequence of repeated permutations of the given array arr,
m, a number system base; and
p, the permutation size.
The method performs three steps to construct an array off_m:
converts off to base m (radix m);
separates the digits of the base m value into an array; and
if necessary, pads the array with leading 0s to make it of size p.
By setting m = arr.size, each digit of off_m is an offset into arr, so off_m maps the base-10 offset to a unique permutation of size p.
def change_base(m, p, off)
arr = off.to_s(m).chars.map { |c| c.to_i(m) }
arr.unshift(*[0]*(p-arr.size))
end
Some examples:
change_base(16, 2, 32)
#=> [2, 0]
change_base(16, 3, 255)
#=> [0, 15, 15]
change_base(36, 4, 859243)
#=> [18, 14, 35, 31]
18*36**3 + 14*36**2 + 35*36**1 + 31
#=> 859243
This implementation of change_base requires that m <= 36. I assume that will be sufficient, but algorithms are available to convert base-10 numbers to numbers with arbitrarily-large bases.
We now construct a method which accepts the given array, arr, the size of each permutation, p and a given base-10 offset into the sequence of permutations. The method returns a permutation, namely, an array of size p whose elements are elements of arr.
def offset_to_perm(arr, p, off)
arr.values_at(*change_base(arr.size, p, off))
end
We can now try this with an example.
arr = (0..3).to_a
p = 2
(arr.size**p).times do |off|
print "perm for off = "
print " " if off < 10
print "#{off}: "
p offset_to_perm(arr, p, off)
end
perm for off = 0: [0, 0]
perm for off = 1: [0, 1]
perm for off = 2: [0, 2]
perm for off = 3: [0, 3]
perm for off = 4: [0, 1]
perm for off = 5: [1, 1]
perm for off = 6: [2, 1]
perm for off = 7: [3, 1]
perm for off = 8: [0, 2]
perm for off = 9: [1, 2]
perm for off = 10: [2, 2]
perm for off = 11: [3, 2]
perm for off = 12: [0, 3]
perm for off = 13: [1, 3]
perm for off = 14: [2, 3]
perm for off = 15: [3, 3]
If we wish to begin at, say, offset 5, we can write:
i = 5
p offset_to_perm(arr, p, i)
[1, 1]
i = i.next #=> 6
p offset_to_perm(arr, p, i)
[2, 1]
...

Manipulating matrix elements in tensorflow

How can I do the following in tensorflow?
mat = [4,2,6,2,3] #
mat[2] = 0 # simple zero the 3rd element
I can't use the [] brackets because it only works on constants and not on
variables. I cant use the slice function either because that returns a tensor and you can't assign to a tensor.
import tensorflow as tf
sess = tf.Session()
var1 = tf.Variable(initial_value=[2, 5, -4, 0])
assignZerosOP = (var1[2] = 0) # < ------ This is what I want to do
sess.run(tf.initialize_all_variables())
print sess.run(var1)
sess.run(assignZerosOP)
print sess.run(var1)
Will print
[2, 5, -4, 0]
[2, 5, 0, 0])
You can't change a tensor - but, as you noted, you can change a variable.
There are three patterns you could use to accomplish what you want:
(a) Use tf.scatter_update to directly poke to the part of the variable you want to change.
import tensorflow as tf
a = tf.Variable(initial_value=[2, 5, -4, 0])
b = tf.scatter_update(a, [1], [9])
init = tf.initialize_all_variables()
with tf.Session() as s:
s.run(init)
print s.run(a)
print s.run(b)
print s.run(a)
[ 2 5 -4 0]
[ 2 9 -4 0]
[ 2 9 -4 0]
(b) Create two tf.slice()s of the tensor, excluding the item you want to change, and then tf.concat(0, [a, 0, b]) them back together.
(c) Create b = tf.zeros_like(a), and then use tf.select() to choose which items from a you want, and which zeros from b that you want.
I've included (b) and (c) because they work with normal tensors, not just variables.

Resources