specutils
specutils copied to clipboard
specutils.Spectrum1D refuses a Pandas Series as input
I tried adapting the specutils demo notebook for my own spectra. The input spectrum is in a pandas dataframe, which specutils.Spectrum1D() refuses as follows:
----> 1 s1723_spec = specutils.Spectrum1D(spectral_axis = df_s1723['wave'] * u.AA, flux=df_s1723['fnu'] * u.Unit('Jansky'))
~/anaconda3/envs/astroconda/lib/python3.6/site-packages/specutils/spectra/spectrum1d.py in init(self, flux, spectral_axis, wcs, velocity_convention, rest_value, redshift, radial_velocity, bin_specification, **kwargs)
97 if flux is not None:
98 if not isinstance(flux, u.Quantity):
---> 99 raise ValueError("Flux must be a Quantity
object.")
100 elif flux.isscalar:
101 flux = u.Quantity([flux])
ValueError: Flux must be a Quantity
object.
The kludgy workaround is to put .values after each Series: s1723_spec = specutils.Spectrum1D(spectral_axis = df_s1723['wave'].values * u.AA, flux=df_s1723['fnu'].values * u.Unit('Jansky'))
A better solution would be for astropy to gracefully accept a pandas Series. (And maybe even a pandas dataframe? Hey, I can dream.)
Thanks @janerigby! I think we can certainly do something at the specutils level to help compatibility, but this might also be a higher-level astropy question of getting Quantity
objects to accept pandas Series
.
Yes, I've worked with @eteq in the past to try to get Astropy to stop refusing pandas Series, in cases where a numpy array is accepted. This is a new case. I don't know where in Astropy to file the ticket. Help?
It is a good idea! You can file the feature request here.
Done, https://github.com/astropy/astropy/issues/11247
As pointed out in https://github.com/astropy/astropy/issues/11247#issuecomment-759742700 the problem is due to pandas' incorrect handling of series.__mul__(u.Unit())
and can only be fixed there.
Among the various slightly less kludgy workarounds it is noteworthy that u.Quantity(df['wave'] * u.AA)
works as well, i.e. this could in principle be implemented to intercept this input in the Spectrum1D
initialisation, i.e. in
https://github.com/astropy/specutils/blob/57dd2b28e5122e00e28333043192d30ec9f78a9d/specutils/spectra/spectrum1d.py#L114-L115
add an additional
try:
flux = u.Quantity(flux)
For plain ndarray or Series input this would create a dimensionless
quantity and of course raising a UnitError
further down, but the same applies to any input with incompatible units, so I don't think this would create a source of additional confusion. Anyway it would perhaps be preferable to check for valid units already right there.
The question is probably how far specutils wants to go to accommodate non-numpy compliant input.