77
88
99def hyper_index (
10- data : Union [pd .DataFrame , pd .Series ], ULTR : int = 140 , a : float = 1.1 , c : int = 30
11- ) -> pd .DataFrame :
10+ data : Union [pd .DataFrame , pd .Series , np . ndarray , list ], ULTR : int = 140 , a : float = 1.1 , c : int = 30
11+ ) -> pd .DataFrame | float :
1212 """
1313 Calculate Hyperglycemia Index.
1414
@@ -19,8 +19,8 @@ def hyper_index(
1919
2020 Parameters
2121 ----------
22- data : Union[pd.DataFrame, pd.Series]
23- DataFrame with columns 'id', 'time', and 'gl', or a Series of glucose values
22+ data : Union[pd.DataFrame, pd.Series, np.ndarray, list ]
23+ DataFrame with columns 'id', 'time', and 'gl', or a Series of glucose values, or a numpy array or list of glucose values
2424 ULTR : int, default=140
2525 Upper Limit of Target Range, in mg/dL
2626 a : float, default=1.1
@@ -31,10 +31,10 @@ def hyper_index(
3131
3232 Returns
3333 -------
34- pd.DataFrame
34+ pd.DataFrame|float
3535 DataFrame with 1 row for each subject, a column for subject id and a column
3636 for the Hyperglycemia Index value. If a Series of glucose values is passed,
37- then a DataFrame without the subject id is returned.
37+ then a float is returned.
3838
3939 References
4040 ----------
@@ -62,50 +62,32 @@ def hyper_index(
6262 0 0.106
6363 """
6464 # Handle Series input
65- is_vector = False
66- if isinstance (data , (list , np .ndarray )):
67- data = pd .Series (data )
68- if isinstance (data , pd .Series ):
69- is_vector = True
70- data = data .dropna ()
71- if len (data ) == 0 :
72- return pd .DataFrame ({"GVP" : [np .nan ]})
73-
74- # Convert to DataFrame format for processing
75- data = pd .DataFrame (
76- {
77- "id" : ["subject1" ] * len (data ),
78- "time" : pd .date_range (
79- start = "2020-01-01" , periods = len (data ), freq = "5min"
80- ),
81- "gl" : data .values ,
82- }
83- )
65+ if isinstance (data , (pd .Series ,list , np .ndarray )):
66+ if isinstance (data , (np .ndarray , list )):
67+ data = pd .Series (data )
68+ return hyper_index_single (data , ULTR , a , c )
8469
8570 # Check and prepare data
8671 data = check_data_columns (data )
8772
8873 # Calculate hyper_index for each subject
89- result = []
90- for subject in data ["id" ].unique ():
91- subject_data = data [data ["id" ] == subject ]
92- # Remove NA values
93- subject_data = subject_data .dropna (subset = ["gl" ])
94-
95- if len (subject_data ) == 0 :
96- continue
97-
98- # Calculate hyper_index
99- hyper_values = subject_data [subject_data ["gl" ] > ULTR ]["gl" ] - ULTR
100- hyper_index = np .sum (hyper_values ** a ) / (len (subject_data ) * c )
101-
102- result .append ({"id" : subject , "hyper_index" : hyper_index })
103-
104- # Convert to DataFrame
105- out = pd .DataFrame (result )
106-
107- # Remove id column if input was a Series
108- if is_vector and not out .empty :
109- out = out .drop ("id" , axis = 1 )
74+ out = data .groupby ('id' ).agg (
75+ hyper_index = ("gl" , lambda x : hyper_index_single (x , ULTR , a , c ))
76+ ).reset_index ()
11077
11178 return out
79+
80+ def hyper_index_single (
81+ gl : pd .Series , ULTR : int = 140 , a : float = 1.1 , c : int = 30
82+ ) -> float :
83+ """
84+ Calculate Hyperglycemia Index for a single subject.
85+ """
86+ gl = gl .dropna ()
87+ if len (gl ) == 0 :
88+ return np .nan
89+ # Calculate hyper_index
90+ hyper_values = gl [gl > ULTR ] - ULTR
91+ hyper_index = np .sum (hyper_values ** a ) / (len (gl ) * c )
92+
93+ return hyper_index
0 commit comments