# How does SciPy's Welch function change the shape of the data?

I am working with some time series data with a shape of 8064. The data is actually the popular EEG data called DEAP. It basically is a 3D array of size (40, 40, 8064) and here is the link to the official dataset website: https://www.eecs.qmul.ac.uk/mmv/datasets/deap/

I applied Welch in order to get the PSD (Power Spectral Density) of the data but the PSD result has a different shape. I was trying to figure out how Welch changes the shape of the data. Any ideas?


srate = 128
winsize = int( 2*srate ) # 2-second window
hannw = .5 - np.cos(2*np.pi*np.linspace(0,1,winsize))/2
nfft = srate*100 # number of FFT points (frequency resolution)
f, welchpow = scipy.signal.welch(data1, fs=srate, window=hannw, nperseg=winsize, noverlap=winsize/2, nfft=nfft)



As you can see in the code above, data1 is the original data and has a shape of (40, 40, 8064). After Applying the code above, welchpow will have a shape of (40, 40, 6401). I can't figure out how it actually changes the shape of the time series data from 8064 to 6401.

• Are you sure it's 6041 and not 6401 ? Jul 22, 2022 at 20:04
• There's no link in your question (referring to the link that you talk about the DEAP dataset). Jul 23, 2022 at 13:48
• @Hilmar Yeah, you are right, my bad! It was actually 6401, not 6041. I also edited my post so it should be 6401 now. Thanks for letting me know! Jul 25, 2022 at 16:12
• @ZaellixA The link to the DEAP dataset is: eecs.qmul.ac.uk/mmv/datasets/deap Thanks for letting me know! Jul 25, 2022 at 16:13
• Yep, it was not visible in the question before... at least for me. Jul 25, 2022 at 19:28

Assuming that "6041" is a typo and it's actually "6401" that would be expected behavior.

The result of welch() is a frequency domain vector the length of which is given by the FFT size. That's in your case 12800. Since the spectrum is conjugate symmetric welch() only returns the positive half of the spectrum which is 6401 points.

This has nothing to do with the length of your time domain sequence. The more time samples you have the more frames are being averaged, but it doesn't change the frequency grid.

nfft = srate*100 # number of FFT points (frequency resolution)


That's a highly unusual choice. Typical the FFT length is determined by the window/frame length. In your example you just do an enormous amount of zero-padding.

• Thanks a lot for your response! I have got two questions: 1) According to your explanation, is it better to leave nfft blank for the Welch function to assign it automatically? 2) Also, is there anyway for me to make the result of the welch (i.e., the psd) to have a shape of 8064, just like the shape of the original time series? Or it doesn't make sense to do such thing? Jul 25, 2022 at 17:11
• @Saturn_4, without zero padding any FFT-based method of a real signal will return an output ~half the length of the input because negative frequencies are redundant. Any amount of zero padding will effectively interpolate the output with more samples, but this does not give you any new information. As long as you understand that, there is nothing inherently wrong with zero padding your data. All data has assumptions, it's your job to understand what those are and what importance it has to your conclusions. To make your output the same shape as your input, simply set nfft=2*8,064-1=16,127.
– Ash
Jul 25, 2022 at 23:48
• Question 1): That really depends on your requirements and what you want to do with the data. There is no "one size fits all". Question 2): You can, but it really makes no sense. Your frequency resolution should be determined by the physics of the underlying system and the needs of your application, not by the length of your input signal. Jul 26, 2022 at 13:31