Skip to content

Commit 21a1848

Browse files
committed
add compute_presence helper function
1 parent 2698f8f commit 21a1848

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

specparam/tests/utils/test_data.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,23 @@ def _dispersion_callable(data):
4848
assert isinstance(out4, np.ndarray)
4949
assert np.array_equal(out4, out2)
5050

51+
def test_compute_presence():
52+
53+
data1_full = np.array([0, 1, 2, 3, 4])
54+
data1_nan = np.array([0, np.nan, 2, 3, np.nan])
55+
assert compute_presence(data1_full) == 1.0
56+
assert compute_presence(data1_nan) == 0.6
57+
assert compute_presence(data1_nan, output='percent') == 60.0
58+
59+
data2_full = np.array([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]])
60+
data2_nan = np.array([[0, np.nan, 2, 3, np.nan], [np.nan, 6, 7, 8, np.nan]])
61+
assert np.array_equal(compute_presence(data2_full), np.array([1.0, 1.0, 1.0, 1.0, 1.0]))
62+
assert np.array_equal(compute_presence(data2_nan), np.array([0.5, 0.5, 1.0, 1.0, 0.0]))
63+
assert np.array_equal(compute_presence(data2_nan, output='percent'),
64+
np.array([50.0, 50.0, 100.0, 100.0, 0.0]))
65+
assert compute_presence(data2_full, average=True) == 1.0
66+
assert compute_presence(data2_nan, average=True) == 0.6
67+
5168
def test_trim_spectrum():
5269

5370
f_in = np.array([0., 1., 2., 3., 4., 5.])

specparam/utils/data.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,46 @@ def compute_dispersion(data, dispersion='std'):
8484
return dispersion_data
8585

8686

87+
def compute_presence(data, average=False, output='ratio'):
88+
"""Compute data presence (as number of non-NaN values) from an array of data.
89+
90+
Parameters
91+
----------
92+
data : 1d or 2d array
93+
Data array to check presence of.
94+
average : bool, optional, default: False
95+
Whether to average across . Only used for 2d array inputs.
96+
If False, for 2d array, the output is an array matching the length of the 0th dimension of the input.
97+
If True, for 2d arrays, the output is a single value averaged across the whole array.
98+
output : {'ratio', 'percent'}
99+
Representation for the output:
100+
'ratio' - ratio value, between 0.0, 1.0.
101+
'percent' - percent value, betweeon 0-100%.
102+
103+
Returns
104+
-------
105+
presence : float or array of float
106+
The computed presence in the given array.
107+
"""
108+
109+
assert output in ['ratio', 'percent'], 'Setting for output type not understood.'
110+
111+
if data.ndim == 1:
112+
presence = sum(~np.isnan(data)) / len(data)
113+
114+
elif data.ndim == 2:
115+
if average:
116+
presence = compute_presence(data.flatten())
117+
else:
118+
n_events, n_windows = data.shape
119+
presence = np.sum(~np.isnan(data), 0) / (np.ones(n_windows) * n_events)
120+
121+
if output == 'percent':
122+
presence *= 100
123+
124+
return presence
125+
126+
87127
def trim_spectrum(freqs, power_spectra, f_range):
88128
"""Extract a frequency range from power spectra.
89129

0 commit comments

Comments
 (0)