Skip to content
This repository was archived by the owner on Feb 7, 2024. It is now read-only.
This repository was archived by the owner on Feb 7, 2024. It is now read-only.

Bug: indexing a signal returns instance of signal with wrong sample frequency #196

Description

@FRidh
>>> s = Signal([0,1,2,3,4,5,6,7,8,9],10)
>>> s2 = s[[0,2,4,6,8]] 
>>> s.fs == s2.fs
True

whereas it should be False. Possible solutions:

  • return array instead of Signal. Can be changed easily in a single method
  • try to determine the real sample frequency. This can be impossible if index is not equally spaced. We could inspect the slice object? Numpy indexing is complicated though.

Activity

  1. felipeacsi commented on Oct 21, 2015

    @felipeacsi
    Member

    I don't see the problem with this. In the example you are trying to extract some data from the signal, but you are not downsampling it, so why it would be necessary to change the sample frequency? If you require to low the sample frequency there are other methods for that, not through numpy.

  2. e-sr commented on Oct 22, 2015

    @e-sr

    I see this as inconsistent because by "trying to extract some data from the signal" you should get data (np.array) and not a Signal object. As you said if the extracted data should correspond to a downsampled Signal then a method returning the Signal will be te correct way.

  3. felipeacsi commented on Oct 22, 2015

    @felipeacsi
    Member

    I see this as inconsistent because by "trying to extract some data from the signal" you should get data (np.array) and not a Signal object.

    I disagree. In all cases where I worked in python, this behaviour is desirable. Take a look at this example with a list, a numpy array and a panda series:

    In [1]: a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    
    In [2]: a_ext = a[0:9:2]
    
    In [3]: a_ext
    Out[3]: [0, 2, 4, 6, 8]
    
    In [4]: type(a_ext)
    Out[4]: list
    
    In [5]: import numpy as np
    
    In [6]: b = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    
    In [7]: b_ext = b[0:9:2]
    
    In [8]: b_ext
    Out[8]: array([0, 2, 4, 6, 8])
    
    In [9]: type(b_ext)
    Out[9]: numpy.ndarray
    
    In [10]: import pandas as pd
    
    In [11]: c = pd.Series([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    
    In [12]: c_ext = c[0:9:2]
    
    In [13]: c_ext
    Out[13]: 
    0    0
    2    2
    4    4
    6    6
    8    8
    dtype: int64
    
    In [14]: type(c_ext)
    Out[14]: pandas.core.series.Series
  4. FRidh commented on Oct 22, 2015

    @FRidh
    MemberAuthor

    Interesting, I agree with both of you. Yes, in Python you generally get an object of the same type back. So returning a Signal would make sense then. But then again, the sample frequency of the extracted data is different. At least, it depends on how you interpret the data.

    Each sample itself still has sample time corresponding to the original fs. So keeping fs as it was makes sense then. However, for computations with the new sequence of values you might not be interested in using the original sample frequency fs.

    But because it is impossible to know what the user will do with the new sequence, there is no sane way of determining a new sample frequency for the user. So we end up with the following choice:

    • Keep the sample frequency as it was, because it corresponds to the sample time of the samples, and that hasn't changed. The user just has to be careful how to use the Signal.
    • Because the sample frequency of the selection cannot be used for certain operations, we might better just throw it away. Better be safe than sorry.

    Because I think keeping meta-data (which a sample frequency is) along with your actual data is important, I lean towards the first option.

  5. e-sr commented on Oct 22, 2015

    @e-sr

    I understand but it depends on the definition we want for a signal.

    How will you implement time information on a signal? Should signals have a sampling rate or better a time tags for every sample (like it where implemented by a panda Series)? Sampling rate assumes periodic sampling, so is not possible to have booth without requiring periodic sampling.

    list, np.array, pdSeries are less specific objects than Signal

    My opinion is to reduce the signals to time series with periodic sampling

    Imagine we have signal basing on pandas Series. Then the Issue we discuss will be clear because

    s = Signal([1,2,3,4,5,6,7])[[0,2,5]]

    Cannot be Anymore a Signal, because in this case a sampling rate does'not exist anymore. Or we have to recalculate all time tags.

    In python-acoustics time informations on Signals are contained in sampling rate (in future maybe maybe t0) and the method time() which generate the time indexing of the frames.

    What is the meaning of s.time() for the sliced Signal in my example?

    Another questions is how useful is to have a Signal where is possible to do the slicing like in my example. All'the methods in Signal class have no mathematical sense anymore. Otherwiese i can imagine there are situations where it can be useful.

    I'm not against keeping Signal returning Signal by slicing, Important is that the user is aware of it.
    What we are discussing is more a theoretical question...

  6. FRidh commented on Oct 22, 2015

    @FRidh
    MemberAuthor

    What we are discussing is more a theoretical question...

    Not really. It's quite difficult as well to implement properly.

    If any form of indexing would return an array, then picking a part of the signal (e.g. the first couple of seconds) would not be possible anymore unless we would explicitly test the slice object for the step. I've once spend a lot of time on implementing numpy compatible indexing for a sparse array class I was working on, and believe me, that was hell.

  7. FRidh commented on Oct 22, 2015

    @FRidh
    MemberAuthor

    I'm closing this issue, since even if we want to 'fix' this issue, it would require a significant amount of effort. I rather spend the time on more pressing issues, I don't know about you. Anyway, thanks a lot for the discussion, since I think it was very useful.

  8. felipeacsi commented on Oct 22, 2015

    @felipeacsi
    Member

    At least, it depends on how you interpret the data.

    Yes. I think this is the core of this discussion.

    But because it is impossible to know what the user will do with the new sequence, there is no sane way of determining a new sample frequency for the user.

    Exactly. Even if this is implemented, this generates certain type of "magic". I agree to change the sample frequency "automatically" but only if it's done in a context of resample the signal, not in an implicit way as is proposed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions