laszukdawid / PyEMD

Python implementation of Empirical Mode Decompoisition (EMD) method
https://pyemd.readthedocs.io/
Apache License 2.0
867 stars 224 forks source link

TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe'' #93

Closed linyu21 closed 3 years ago

linyu21 commented 3 years ago

I miss a problem in my project.

TypeError

Traceback (most recent call last) <ipython-input-20-324920922392> in <module>
      7 # IMF = EMD().emd(s)
      8 # IMF = EEMD().eemd(s)
----> 9 IMF=CEEMDAN().ceemdan(s)
     10 N = IMF.shape[0]+1
     11 print(IMF.shape)

~\.conda\envs\py36\lib\site-packages\emd_signal-0.2.14-py3.6.egg\PyEMD\CEEMDAN.py in ceemdan(self, S, T, max_imf)
    184 
    185         # Create first IMF
--> 186         last_imf = self._eemd(S, T, 1)[0]
    187         res = np.empty(S.size)
    188 

~\.conda\envs\py36\lib\site-packages\emd_signal-0.2.14-py3.6.egg\PyEMD\CEEMDAN.py in _eemd(self, S, T, max_imf)
    300         all_IMFs_1, all_IMFs_2 = itertools.tee(all_IMFs, 2)
    301 
--> 302         max_imfNo = max([IMFs.shape[0] for IMFs in all_IMFs_1])
    303 
    304         self.E_IMF = np.zeros((max_imfNo, N))

~\.conda\envs\py36\lib\site-packages\emd_signal-0.2.14-py3.6.egg\PyEMD\CEEMDAN.py in <listcomp>(.0)
    300         all_IMFs_1, all_IMFs_2 = itertools.tee(all_IMFs, 2)
    301 
--> 302         max_imfNo = max([IMFs.shape[0] for IMFs in all_IMFs_1])
    303 
    304         self.E_IMF = np.zeros((max_imfNo, N))

~\.conda\envs\py36\lib\site-packages\emd_signal-0.2.14-py3.6.egg\PyEMD\CEEMDAN.py in _trial_update(self, trial)
    312         # Generate noise
    313         noise = self.epsilon*self.all_noise_EMD[trial][0]
--> 314         return self.emd(self._S+noise, self._T, self.max_imf)
    315 
    316     def emd(self, S: np.ndarray, T: Optional[np.ndarray] = None, max_imf: int = -1) -> np.ndarray:

~\.conda\envs\py36\lib\site-packages\emd_signal-0.2.14-py3.6.egg\PyEMD\CEEMDAN.py in emd(self, S, T, max_imf)
    320         For reference please see :class:`PyEMD.EMD`.
    321         """
--> 322         return self.EMD.emd(S, T, max_imf)
    323 
    324     def get_imfs_and_residue(self) -> Tuple[np.ndarray, np.ndarray]:

~\.conda\envs\py36\lib\site-packages\emd_signal-0.2.14-py3.6.egg\PyEMD\EMD.py in emd(self, S, T, max_imf)
    823                 if extNo > 2:
    824 
--> 825                     max_env, min_env, eMax, eMin = self.extract_max_min_spline(T, imf)
    826                     mean[:] = 0.5*(max_env+min_env)
    827 

~\.conda\envs\py36\lib\site-packages\emd_signal-0.2.14-py3.6.egg\PyEMD\EMD.py in extract_max_min_spline(self, T, S)
    154         max_extrema, min_extrema = self.prepare_points(T, S, max_pos, max_val, min_pos, min_val)
    155 
--> 156         _, max_spline = self.spline_points(T, max_extrema)
    157         _, min_spline = self.spline_points(T, min_extrema)
    158 

~\.conda\envs\py36\lib\site-packages\emd_signal-0.2.14-py3.6.egg\PyEMD\EMD.py in spline_points(self, T, extrema)
    466         elif kind == 'cubic':
    467             if extrema.shape[1] > 3:
--> 468                 return t, interp1d(extrema[0], extrema[1], kind=kind)(t)
    469             else:
    470                 return cubic_spline_3pts(extrema[0], extrema[1], t)

~\.conda\envs\py36\lib\site-packages\scipy\interpolate\interpolate.py in __init__(***failed resolving arguments***)
    513                 # with nans.
    514                 # For slinear or zero order spline, we just pass nans through.
--> 515                 mask = np.isnan(self.x)
    516                 if mask.any():
    517                     sx = self.x[~mask]

TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
laszukdawid commented 3 years ago

Hi @linyu21,

To be honest I can't tell what's exactly the cause of the issue from your report. You'd need to share some data or reproduce the issue with a generic script.

From the traceback: You receive a TypeError when using CEEMDAN. That error actually comes from Scipy's cubic interpolation method and it is saying that it cannot interpolate as it cannot validate input signal. Specifically, it can't use numpy's isnan function on what is supposed to be x (or min extrema).

My guess is that for some reason there's been only one min extremum (i.e. len(extrema[0]) == 1) and more than 3 max extrema. That's super suspicious. CEEMDAN adds noise to each generation making decomposition different each time. Since you went ahead to report this I'm guessing that you were consistently getting this issue. This means that there's likely a bigger cause.

linyu21 commented 3 years ago

Thank you for your reply. This error has occurred since the update of tensorflow2. X. now I use another method to replace EMD.

laszukdawid commented 3 years ago

I thought that this issue didn't require follow up but looking at it from perspective it might benefit from conclusion.

PyEMD does not support formats other than Python lists, numpy ndarray or anything that's fully compatible with either. Especially it doesn't work with pandas dataframes and tensorflow records which have unusual APIs. For machine learning application please convert data to numpy ndarray first.