Hamzah Ziadeh
Hamzah Ziadeh

Reputation: 68

Rolling window with apply function reutrns "dict object is not callable" in pandas data frame

For my project, I need to get very granular and continuous measure for heart rate variability through IBI (inter-beat interval) data that I have collected. To do this, I need to window my data applied with a pandas rolling window (size = 30s). I define my data frame as such:

py_physio_Data = pd.DataFrame(py_physio_DF)

Which yields (this only a snippet of the data):

Participant IBI Timestamp
1 526 2021-11-10 10:54:15
1 658 2021-11-10 10:54:15
1 700 2021-11-10 10:54:16
1 695 2021-11-10 10:54:17

Right now I have the data filtered to only include participant one. So here is the problematic code:

import hrvanalysis as hrv
py_physio_Data.index = pd.to_datetime(py_physio_Data["Timestamp"])
py_physio_Data.rolling("30s").apply(func = hrv.get_time_domain_features(py_physio_Data["IBI"]))

I set timestamp as the index column and then I try to apply the function get_time_domain_features().

TypeError: 'dict' object is not callable

I cant figure out what the problem is how to fix it. Ive consulted previous posts, tried various syntaxes (see below for examples), but I cant figure out the error. Any help would be appreciated :D

py_physio_Data.rolling("30s").apply(func = hrv.get_time_domain_features(py_physio_Data))
py_physio_Data.rolling("30s").apply(func = hrv.get_time_domain_features())
py_physio_Data["IBI"].rolling("30s").apply(func = hrv.get_time_domain_features(py_physio_Data["IBI"]))

EDIT WITH SOLUTION

Thanks to Koala, I managed to find a working solution. There were two resons why my code did not work:

  1. The .apply function often struggles when outputting multiple values/adict containing values. So passing a function like get_time_domain_features which returns a whole set of data conflicts with the function.
  2. The .rolling function did not apply windowing correctly to the beginning and end of the data frame. Likely because the first and last 15 rows of data have insufficient values for a 30 seconds window.

Anyways, here's the working code:

def calc_time(window):
  print(hrv.get_time_domain_features(window))
  print("========")
  return 0


py_physio_Data["IBI"].rolling("30s", min_periods = 30).apply(func = calc_time)

To fix the errors, I just needed to put the get_time_domain_features in a function that returns only one value to satisfy the .apply() constraints. Second, I specified that a window should not be less than 30 rows in legth.

Upvotes: 2

Views: 138

Answers (1)

koala
koala

Reputation: 108

Try this:

py_physio_Data["IBI"].rolling("30s").apply(hrv.get_time_domain_features);

What you are doing is applying the result of the get_time_domain() function, that you always call with the entire "IBI" column. If instead you specify only the function as a callable object, rolling will populate it with a Pandas Series containing the "IBI" data of that iteration, and it will return the resulting dictionary. Before you were calling the dictionary returned as if it was a function, that's why it wasn't returning anything.

Upvotes: 1

Related Questions