SciPy DCT for Discrete Cosine Transform
SciPy provides dct() to calculate the Discrete Cosine Transform of a real input sequence. A DCT represents data using cosine basis functions, so it is commonly used when the input is real-valued, such as a signal, measurement sequence, or image block.
The older scipy.fftpack.dct() function used in this tutorial still works, but scipy.fftpack is now treated as the legacy FFT interface. For new code, prefer scipy.fft.dct(). The examples below show both forms so that you can maintain old code and write current SciPy code correctly.
scipy.fftpack.dct() syntax used in existing SciPy code
y = scipy.fftpack.dct(x, type=2, n=None, axis=-1, norm=None, overwrite_x=False)
The default transform is DCT type 2 along the last axis of the input array. If you do not pass n, SciPy uses the length of the selected axis.
scipy.fft.dct() syntax recommended for new SciPy programs
y = scipy.fft.dct(x, type=2, n=None, axis=-1, norm=None, overwrite_x=False, workers=None, orthogonalize=None)
The modern scipy.fft.dct() API adds workers for parallel computation and orthogonalize for controlling the orthogonalized DCT variant. For simple one-dimensional examples, the result is the same as the older scipy.fftpack.dct() call when equivalent arguments are used.
SciPy DCT parameters: x, type, n, axis, norm and overwrite_x
| Parameter | Required/Optional | Description |
| x | Required | Input array or array-like object on which the Discrete Cosine Transform is computed. |
| type | Optional | DCT type. SciPy supports types 1, 2, 3, and 4. The default is 2, which is what most users mean by “the DCT”. |
| n | Optional | Length of the transform along the selected axis. If n is smaller than the current length, the input is truncated. If n is larger, the input is zero-padded. |
| axis | Optional | Axis along which the DCT is computed. The default is -1, meaning the last axis. |
| norm | Optional | Normalization mode. In scipy.fftpack.dct(), common values are None and 'ortho'. In scipy.fft.dct(), values include 'backward', 'ortho', and 'forward'. |
| overwrite_x | Optional | If True, SciPy may overwrite the input data while computing the transform. Keep it False when the original input must be preserved. |
| workers | Optional in scipy.fft.dct() | Maximum number of workers for parallel computation. This argument is not available in scipy.fftpack.dct(). |
| orthogonalize | Optional in scipy.fft.dct() | Controls whether SciPy uses the orthogonalized DCT variant. It is especially relevant when using norm='ortho'. |
| y | Returned value | Real ndarray containing the transformed input values. |
Values shown in the syntax are default values. In most programs, you will start with only the input array and add norm, axis, or n when the transform needs a specific scale, dimension, or length.
Example 1: calculate SciPy DCT of a NumPy array
scipy-example.py
# import numpy
import numpy as np
# import dct
from scipy.fftpack import dct
# numpy array
x = np.array([1.0, 2.0, 1.0, 2.0, -1.0])
print("x : ",x)
# apply dct function on array
y = dct(x)
print("dct(x) : ",y)
Output
x : [ 1. 2. 1. 2. -1.]
dct(x) : [ 10. 3.80422607 -4.47213595 2.35114101 -4.47213595]
The first value in the output is the low-frequency coefficient. The remaining values represent cosine components at increasing frequencies for this input sequence.
Example 2: use scipy.fft.dct() with norm=’ortho’
Use norm='ortho' when you want an orthonormal transform. This is useful when you want a clean inverse relationship with idct() using the same normalization.
import numpy as np
from scipy.fft import dct, idct
x = np.array([1.0, 2.0, 1.0, 2.0, -1.0])
coefficients = dct(x, norm='ortho')
reconstructed = idct(coefficients, norm='ortho')
print("DCT coefficients:", coefficients)
print("Reconstructed x :", reconstructed)
Output
DCT coefficients: [ 2.23606798 1.20300191 -1.41421356 0.74349607 -1.41421356]
Reconstructed x : [ 1. 2. 1. 2. -1.]
Here, idct() recovers the original array because both the forward and inverse transforms use norm='ortho'.
Example 3: apply SciPy DCT along rows or columns with axis
For a two-dimensional array, axis=-1 applies the DCT across each row because the last axis is the column direction. Use axis=0 to apply the DCT down each column.
import numpy as np
from scipy.fft import dct
x = np.array([
[1.0, 2.0, 3.0],
[4.0, 5.0, 6.0]
])
row_dct = dct(x, axis=1, norm='ortho')
column_dct = dct(x, axis=0, norm='ortho')
print("DCT across rows:")
print(row_dct)
print("DCT down columns:")
print(column_dct)
Output
DCT across rows:
[[ 3.46410162 -1.41421356 0. ]
[ 8.66025404 -1.41421356 0. ]]
DCT down columns:
[[ 3.53553391 4.94974747 6.36396103]
[-2.12132034 -2.12132034 -2.12132034]]
This example is useful when the rows and columns have different meanings. For example, rows may represent separate signals, while columns may represent samples within each signal.
Example 4: control SciPy DCT length with n
The n parameter changes the logical length of the transform. When n is smaller than the input length, SciPy truncates the data. When n is larger, SciPy pads the input with zeros before applying the DCT.
import numpy as np
from scipy.fft import dct
x = np.array([1.0, 2.0, 1.0, 2.0, -1.0])
print("n=3:", dct(x, n=3))
print("n=8:", dct(x, n=8))
Output
n=3: [ 8. 0. -2.]
n=8: [10. 7.56913141 0.76536686 -4.41241402 -1.41421356 2.56699766
-1.84775907 -6.05387275]
Example 5: compute a two-dimensional DCT with scipy.fft.dctn()
Calling dct() once transforms one axis. For a true two-dimensional or N-dimensional DCT, use scipy.fft.dctn(). This applies the DCT across multiple axes in one call.
import numpy as np
from scipy.fft import dctn, idctn
block = np.array([
[52, 55, 61, 66],
[70, 61, 64, 73],
[63, 59, 55, 90],
[67, 61, 68, 104]
], dtype=float)
coefficients = dctn(block, norm='ortho')
restored = idctn(coefficients, norm='ortho')
np.set_printoptions(precision=2, suppress=True)
print("2D DCT coefficients:")
print(coefficients)
print("Restored block:")
print(restored)
Output
2D DCT coefficients:
[[267.25 -28.08 25.25 -7.04]
[-21.42 13.72 -15.91 6.63]
[ -0.25 -8.75 -3.25 1.73]
[ -9.26 -4.87 1.45 -5.72]]
Restored block:
[[ 52. 55. 61. 66.]
[ 70. 61. 64. 73.]
[ 63. 59. 55. 90.]
[ 67. 61. 68. 104.]]
Use dctn() for image blocks, matrices, and multidimensional data. Use dct() with axis when you only want to transform one dimension of an array.
DCT type 2, DCT type 3 and inverse DCT in SciPy
In SciPy, DCT type 2 is the default and is the most common form in practical examples. DCT type 3 is closely related to the inverse of DCT type 2. When you use norm='ortho', a DCT-II followed by the matching inverse transform can reconstruct the original input without manually applying a scale factor.
Use type=1, type=3, or type=4 only when your formula, algorithm, or reference material specifically requires that DCT type. Otherwise, the default type=2 is usually the right starting point.
When to use norm=’ortho’ in scipy.fft.dct()
The norm argument controls scaling. Use norm='ortho' when you want orthonormal coefficients and straightforward reconstruction with idct() or idctn(). Leave normalization at the default when you are matching formulas or older code that expects SciPy’s unnormalized DCT output.
Common SciPy DCT mistakes and fixes
- Using FFT wording for DCT output:
dct()returns real DCT coefficients, not complex Fourier coefficients. - Forgetting the axis: On a 2D array,
axis=-1transforms rows. Useaxis=0for columns. - Mixing normalization modes: If you use
norm='ortho'fordct(), use the same normalization foridct(). - Expecting a full 2D transform from one dct() call: Use
dctn()or applydct()along both axes. - Using scipy.fftpack in new code: Existing code can keep it, but new code should generally import DCT functions from
scipy.fft.
SciPy DCT function reference links
For exact API details, refer to the official SciPy pages for scipy.fft.dct(), scipy.fftpack.dct(), and scipy.fft.dctn().
FAQs on SciPy DCT
What does scipy dct() return?
dct() returns a real ndarray containing the Discrete Cosine Transform coefficients of the input array. It does not return complex FFT coefficients.
Should I use scipy.fft.dct() or scipy.fftpack.dct()?
Use scipy.fft.dct() for new code. Use scipy.fftpack.dct() when you are maintaining older code that already depends on the legacy FFT interface.
How do I calculate a 2D DCT in SciPy?
Use scipy.fft.dctn() for a 2D or N-dimensional DCT. If you use dct(), it transforms only one axis per call unless you apply it again along another axis.
Why is norm=’ortho’ used with SciPy DCT?
norm='ortho' gives orthonormal scaling. It is helpful when you want to reconstruct the original values with idct() or idctn() without manually handling scale factors.
What is the default DCT type in SciPy?
The default DCT type is type=2. This is the form most examples use unless a specific algorithm requires another DCT type.
Editorial QA checklist for this SciPy DCT tutorial
- Confirm that new examples use
scipy.fftwhile the originalscipy.fftpackexample remains available for legacy users. - Check that every added code block uses a PrismJS-compatible class such as
language-python,language-python syntax, oroutput. - Verify that DCT output is described as a real ndarray, not as a complex FFT result.
- Ensure that
axis,n,norm,dctn(), and inverse reconstruction are covered with examples. - Review the official SciPy links when the API changes in a future SciPy release.
TutorialKart.com