99
1010
1111def igc (
12- data : Union [pd .DataFrame , pd .Series ],
12+ data : Union [pd .DataFrame , pd .Series , np . ndarray , list ],
1313 LLTR : int = 80 ,
1414 ULTR : int = 140 ,
1515 a : float = 1.1 ,
1616 b : float = 2 ,
1717 c : int = 30 ,
1818 d : int = 30 ,
19- ) -> pd .DataFrame :
19+ ) -> pd .DataFrame | float :
2020 """
2121 Calculate Index of Glycemic Control (IGC).
2222
@@ -25,8 +25,8 @@ def igc(
2525
2626 Parameters
2727 ----------
28- data : Union[pd.DataFrame, pd.Series]
29- DataFrame with columns 'id', 'time', and 'gl', or a Series of glucose values
28+ data : Union[pd.DataFrame, pd.Series, np.ndarray, list ]
29+ DataFrame with columns 'id', 'time', and 'gl', or a Series of glucose values, or a numpy array or list of glucose values
3030 LLTR : int, default=80
3131 Lower Limit of Target Range, in mg/dL
3232 ULTR : int, default=140
@@ -42,10 +42,9 @@ def igc(
4242
4343 Returns
4444 -------
45- pd.DataFrame
45+ pd.DataFrame|float
4646 DataFrame with 1 row for each subject, a column for subject id and a column
47- for the IGC value. If a Series of glucose values is passed, then a DataFrame
48- without the subject id is returned.
47+ for the IGC value. If a Series of glucose values is passed, then a float is returned.
4948
5049 References
5150 ----------
@@ -73,40 +72,34 @@ def igc(
7372 0 0.106
7473 """
7574 # Handle Series input
76- is_vector = False
77- if isinstance (data , (list , np .ndarray )):
78- data = pd .Series (data )
79- if isinstance (data , pd .Series ):
80- is_vector = True
81- data = data .dropna ()
82- if len (data ) == 0 :
83- return pd .DataFrame ({"GVP" : [np .nan ]})
84-
85- # Convert to DataFrame format for processing
86- data = pd .DataFrame (
87- {
88- "id" : ["subject1" ] * len (data ),
89- "time" : pd .date_range (
90- start = "2020-01-01" , periods = len (data ), freq = "5min"
91- ),
92- "gl" : data .values ,
93- }
94- )
75+ if isinstance (data , (pd .Series ,list , np .ndarray )):
76+ if isinstance (data , (np .ndarray , list )):
77+ data = pd .Series (data )
78+ return igc_single (data , LLTR , ULTR , a , b , c , d )
9579
9680 # Check and prepare data
9781 data = check_data_columns (data )
9882
99- # Calculate hyper_index and hypo_index
100- out_hyper = hyper_index (data , ULTR = ULTR , a = a , c = c )
101- out_hypo = hypo_index (data , LLTR = LLTR , b = b , d = d )
102-
103- # Combine the indices
104- out = pd .merge (out_hyper , out_hypo , on = "id" )
105- out ["IGC" ] = out ["hyper_index" ] + out ["hypo_index" ]
106- out = out [["id" , "IGC" ]]
83+ out = data .groupby ('id' ).agg (
84+ IGC = ("gl" , lambda x : igc_single (x , LLTR , ULTR , a , b , c , d ))
85+ ).reset_index ()
86+ return out
10787
108- # Remove id column if input was a Series
109- if is_vector :
110- out = out .drop ("id" , axis = 1 )
88+ def igc_single (
89+ gl : pd .Series ,
90+ LLTR : int = 80 ,
91+ ULTR : int = 140 ,
92+ a : float = 1.1 ,
93+ b : float = 2 ,
94+ c : int = 30 ,
95+ d : int = 30
96+ ) -> float :
97+ """
98+ Calculate Index of Glycemic Control for a single subject.
99+ """
100+ # Calculate hyper_index and hypo_index
101+ out_hyper = hyper_index (gl , ULTR = ULTR , a = a , c = c )
102+ out_hypo = hypo_index (gl , LLTR = LLTR , b = b , d = d )
111103
112- return out
104+ out = out_hyper + out_hypo
105+ return out
0 commit comments