-
Notifications
You must be signed in to change notification settings - Fork 93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Updated zscore for in-place operations #440
Updated zscore for in-place operations #440
Conversation
…n-place operations, and also to return the original object instead of a new AnalogSignal object pointing to the original array
…ject created using Neo function.
…place operation in zscore. Changed test_zscore_single_inplace_int as the function now raises ValueError.
As discussed, the function was modified to raise an error when the in-place operation is not valid. Also, the duplicate is made using the Neo function. All unit tests were modified to check if the objects are the same/different according to the |
after modification to raise an error, check behavior with added exception handling: import numpy as np
import quantities as pq
import neo
from elephant.signal_processing import zscore
for inplace, dtype in ((True, np.int64), (False, np.int64),
(True, np.float64), (False, np.float64)):
print("=======================")
print(f"Inplace: {inplace}; dtype: {dtype}")
test = neo.AnalogSignal(np.random.normal(10, 2, (60000, 96)),
units='uV', dtype=dtype, sampling_rate=30000*pq.Hz)
try:
zscored = zscore(test, inplace=inplace)
print("IDs", id(test), id(zscored))
print("Same object?", test is zscored)
print(test[:1, :5])
print(zscored[:1, :5])
print("Equal data?", np.array_equal(test, zscored))
except:
print("error was raised") which produces the same output as in the first comment by @kohlerca, except now an error is raised with
|
The
zscore
function has a parameterinplace
, to allow storing the z-scored values in the originalAnalogSignal
object(s).The function always returns the
AnalogSignal
objects, whether or not an in-place operation is performed.However, the in-place operation only operated at the level of the data array, i.e., whenever the NumPy array from the original
AnalogSignal
was modified with the z-scored values, a newAnalogSignal
object was created pointing to that NumPy array. Therefore, this has never been a true in-place operation, as the returned objects differed from the inputs.This PR fixes that by returning the original
AnalogSignal
wheninplace
is True, and a new object (also using a different data array) wheninplace
is False.Moreover, the units in the original
AnalogSignal
object were not modified wheninplace
is True and only the returned object was dimensionless (see #384). Therefore, the originalAnalogSignal
ended up with z-scored values with a unit such asuV
, which is misleading. The code in the PR now sets the unit todimensionless
in the originalAnalogSignal
.Finally, the docstring mentioned that the in-place operation was not attempted if the
AnalogSignal
data type did not allow it (i.e., whenever the type was not float). The PR code now checks, for every object in the input list, whether the type allows the in-place operation. Ifinplace
is True and this is not allowed, the parameter is ignored for thatAnalogSignal
(i.e., a copy will be returned along with a newAnalogSignal
object), and a warning to the user is shown. Alternatively, this could be done before the main loop, checking if there is at least one object in the input list that does not allow the operation, and then settinginplace
to False in that case (i.e., preventing any in-place operation at all).To test the behavior of the updated function:
which produces