Appending to numpy array within a loop - python-3.x

I really hope to not have missed something, that had been clarified before, but I couldn't find something here.
The task seems easy, but I fail. I want to continuously append a numpy array to another one while in a for-loop:
step_n = 10
steps = np.empty([step_n,1])
for n in range(step_n):
step = np.random.choice([-1, 0, 1], size=(1,2))
#steps.append(step) -> if would be lists, I would do it like that
a = np.append(steps,step)
#something will be checked after each n
print(a)
The output should be ofc of type <class 'numpy.ndarray'> and look like:
[[-1. 0.]
[ 0. 0.]
[-1. -1.]
[ 1. -1.]
[ 1. 1.]
[ 0. -1.]
[-1. 1.]
[-1. 0.]
[ 0. -1.]
[ 1. 1.]]
However the code fails for some (most probably obvious) reasons.
Can someone give me a hint?

import numpy as np
step_n = 10
steps = np.random.choice([-1, 0, 1], size=(1,2))
for n in range(step_n-1):
step = np.random.choice([-1, 0, 1], size=(1,2))
print(steps)
steps = np.append(steps, step, axis=0)
#something will be checked after each n
print(steps)
One of the problems is that your steps variable that is initialized outside the for loop has a different size than each step inside. I changed how you initialized the variable steps, by creating your first step outside of the for loop. This way, your steps variable already has the matching size. But notice you need to reduce 1 iteration in the for loop because of this.
Also, you want to update the steps variable in each for loop, and not create a new variable "a" inside it. In your code, you would just end up with the steps array (that never changes) and only the last step.

Related

Complete values are not writing to the file using Python

My idea is to write some large number of bits to a file (almost 64*4800 bits). It is writing but not all the bits.
The console output looks like
[1. 1. 0. ... 1. 0. 1.]
If I decrement the number of bits to be saved then it will work.
I will paste my code here. This code is sampling the analog to digital
y= function(x) # Inside this function I am generating binary values and stored to y
################ y is in numpy.ndarray form
################ x is a sine wave
f=open('filename.txt',"w+")
f.write(str(y)) #we have to convert the numpy.ndarray to str.
f.close()
when I open my filename.txt file it is showing the binary values as
[1. 1. 0. ... 1. 0. 1.]
which is same as in the console.
Please help me to resolve this issue. I need all the bits (64*4800) to be saved inside the file
Try converting your numpy array to a list first:
y = function(x) # Inside this function I am generating binary values and stored to y
################ y is in numpy.ndarray form
################ x is a sine wave
y_list = y.tolist() # Convert to python list
# use the with context manager and you don't need to call .close() explicitly
with open('filename.txt',"w+") as f:
f.write(str(y_list)) #we have to convert the numpy.ndarray to a list and then to str(y_list) which will write the entire bits.

Finding more indices in a list close to zero

I have a list of values, which represents a damping function when this is plotted (so a form of a sinusoide). This function passes the y=0 thus several times until it levels out on y=0. I need to find the index at the moment when the function passes zero for the third time.
All values are floats, so I have a function that finds the index closest to zero:
def find_index(list_, value):
array = np.asarray(list_)
idx = (np.abs(array - value)).argmin()
return idx
Where 'list_' is the list and 'value' is zero.
This function does work, but it can only retrieve the index of the first moment the damping function (and thus the list) is closest to zero. Meaning that it will show an index of zero (because the damping function starts at zero). However, I need the index of the third time when it is closest to zero.
How can I obtain the index of the third time it will be closest to zero, instead of the first time?
You are looking for a change in the sign.
import numpy as np
x = np.array([10.0, 1.0, -1.0, -2.0, 1.0, 4.0])
y = np.sign(x) # -1 or 1
print(y)
>>> [ 1. 1. -1. -1. 1. 1.]
If you calculate the difference between consecutive elements using np.diff it will be either -2 or 2, both are boolean True.
>>> [ 0. -2. 0. 2. 0.]
Now get the indices of them using np.nonzero, which returns a tuple for each dimension. Pick the first one.
idx = np.nonzero(np.diff(y))[0]
print(idx)
>>> [1 3]

convert python map objects to array or dataframe

How can we convert map objects(derived from ndarray objects) to a dataframe or array object in python.
I have a normally distributed data with size 10*10 called a. There is one more data containing 0 and 1 of size 10*10 called b. I want to add a to b if b is not zero else return b.
I am doing it through map. I am able to create the map object called c but can't see the content of it. Can someone please help.
a=numpy.random.normal(loc=0.0,scale=0.001,size=(10,10))
b = np.random.randint(2, size=a.shape)
c=map(lambda x,y : y+x if y!=0 else x, a,b)
a=[[.24,.03,.87],
[.45,.67,.34],
[.54,.32,.12]]
b=[[0,1,0],
[1,0,0],
[1,0,1]]
then c should be as shown below.
c=[[0,1.03,.87],
[1.45,0,0],
[1.54,0,1.12]
]
np.multiply(a,b) + b
should do it
Here is the output
array([[0. , 1.03, 0. ],
[1.45, 0. , 0. ],
[1.54, 0. , 1.12]])
Since, a and b are numpy arrays, there is a numpy function especially for this use case as np.where (documentation).
If a and b are as follows,
a=np.array([[.24,.03,.87],
[.45,.67,.34],
[.54,.32,.12]])
b=np.array([[0,1,0],
[1,0,0],
[1,0,1]])
Then the output of the following line,
np.where(b!=0, a+b, b)
will be,
[[0. 1.03 0. ]
[1.45 0. 0. ]
[1.54 0. 1.12]]

Python: Increasing one number in a list by one

I am trying to write a program that returns the frequency of a certain pattern. My frequency list is initially a list of zeros, and I want to increase a certain zero by one depending on the pattern. I have tried the code below, but it does not work.
FrequencyArray[j] = FrequencyArray[j]+1
Is there another way to increase one element of the list by 1 without affecting the other elements?
While your approach should work, this would be the alternative:
FrequencyArray[j] += 1
Example:
>>> zeros = [0, 0, 0]
>>> zeros[1] += 1
>>> zeros
[0, 1, 0]

FMU FMI simulation, no evaluation of some equations after initialization

I believe my problem is somehow related to this previous question but I was not able to fix my problem with their advices.
Here is a minimal non working example. I have a simple electrical circuit with a commutating switch in it (developed in openModelica). I want to modify the value of switch.control depending on the value of an input Parameter. To do that I have the following:
model MinimalNonWorkingExemple
parameter Modelica.Blocks.Interfaces.RealInput openclose;
Modelica.Electrical.Analog.Ideal.IdealCommutingSwitch switch;
Modelica.Electrical.Analog.Basic.Ground G;
equation
connect(switch.p, G.p);
connect(switch.n2, G.p);
connect(switch.n1, G.p);
switch.control = if openclose > 0.5 then true else false;
end MinimalNonWorkingExemple;
Note: I tried many combination between parameter, input, etc...
I want to make an iterative simulation (for instance simulate 60 seconds of the system but with 60 consecutive simulations of 1 second). This is to be able to change the input value (openclose) according to another FMU simulation.
As a result I can modify the value of the input from pyFMI. (when I read it, the changed is taken into account). However, the "new value" is not taken into account neither in my equations.
Here is my pyfmi script:
# Import the load function (load_fmu)
from pyfmi import load_fmu
import numpy as np
from pylab import *
def simulate(model, res, startTime,finalTime, initialState):
if res == None:
opts=model.simulate_options()
opts['initialize']=True
else:
opts=model.simulate_options()
opts['initialize']=False
for s in initialState:
model.set(s[0],s[1])
res = model.simulate(start_time = startTime, final_time=finalTime, options=opts)
return res
#main part
model = load_fmu('MinimalNonWorkingExemple.fmu')
switchClose = ['openclose', [0.0]]
switchOpen = ['openclose', [1.0]]
#Simulate an FMU
res = simulate(model, None, 0, 50, [switchOpen])
v = res["openclose"]
v2 = res["switch.control"]
res = simulate(model, res, 50, 100, [switchClose])
v = np.concatenate((v,res["openclose"]))
v2 = np.concatenate((v2,res["switch.control"]))
res = simulate(model, res, 100, 200, [switchOpen])
v = np.concatenate((v,res["openclose"]))
v2 = np.concatenate((v2,res["switch.control"]))
print v
print v2
Basically I simulate during 50 units of time then I change the value of the openclose variable, then simulating again, switching again and re-simulating. As a result I obtained:
openclose: [ 1. 1. 1. 1. 0. 0. 0. 0. 1. 1. 1. 1.]
switch.control: [ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
Actually, only the set made before the first call to model.simulate(...) propagates its value in the system.
I tried to understand the annotation(Evaluate = false) proposed here but it did not work. I'm not sure if it is related since I can actually change my value. The problem is that the equations based on this parameter seems only evaluated during initialisation :-/
Any idea/help would be very welcome...
As far as I can understand, the FMI standard says that after you initialize the model your changes to the parameters will not affect the model anymore. So, one has to use reset and re-initialize the model so the changes are picked up again.
It seems to work fine with this code:
# Import the load function (load_fmu)
from pyfmi import load_fmu
import numpy as np
from pylab import *
def simulate(model, res, startTime,finalTime, initialState):
if res == None:
opts=model.simulate_options()
opts['initialize']=True
else:
model.reset()
opts=model.simulate_options()
opts['initialize']=True
for s in initialState:
model.set(s[0],s[1])
res = model.simulate(start_time = startTime, final_time=finalTime, options=opts)
return res
#main part
model = load_fmu('MinimalNonWorkingExemple.fmu')
print model.get_description()
model.set_log_level(7)
switchClose = ['openclose', [0.0]]
switchOpen = ['openclose', [1.0]]
#Simulate an FMU
res = simulate(model, None, 0, 50, [switchOpen])
v = res["openclose"]
v2 = res["switch.control"]
res = simulate(model, res, 50, 100, [switchClose])
v = np.concatenate((v,res["openclose"]))
v2 = np.concatenate((v2,res["switch.control"]))
res = simulate(model, res, 100, 200, [switchOpen])
v = np.concatenate((v,res["openclose"]))
v2 = np.concatenate((v2,res["switch.control"]))
print v
print v2
The result is:
[ 1. 1. 1. 1. 0. 0. 0. 0. 1. 1. 1. 1.]
[ 1. 1. 1. 1. 0. 0. 0. 0. 1. 1. 1. 1.]
You can see also the discussion here:
http://ext5.modelon.ideon.se/5858
It might work also if you make openclose an input (no parameter) and then give an input object to the simulation (openclose, time, value) as in the example here:
http://www.jmodelica.org/assimulo_home/pyfmi_1.0/pyfmi.examples.html#module-pyfmi.examples.fmu_with_input
However, I haven't tried it so it might not work.

Resources