@@ -110,27 +110,12 @@ def filter_column(self,
110
110
column : Optional [str ],
111
111
value_filter : Union [str , int , float , None ]) -> pd .DataFrame :
112
112
"""
113
- Filter sensors by column and value_filter. If only column is passed, we
114
- return rows that are not None. If the value_filter is passed, we only
115
- return rows where the column matches that value.
113
+ Returns the output of filter_column_to_array as a pandas dataframe.
116
114
"""
117
115
# Check if there is no column passed
118
116
if column is None :
119
117
raise ValueError ('No column name provided to filter on!' )
120
- out_l : List [dict ] = []
121
- for sensor in self .all_sensors :
122
- sensor_data = sensor .as_flat_dict (channel )
123
- if column not in sensor_data :
124
- raise ValueError (
125
- f'Requested column { column } does not exist in sensor data!' )
126
- result = sensor_data .get (column )
127
- if value_filter and result != value_filter :
128
- continue
129
- if value_filter and result == value_filter :
130
- out_l .append (sensor_data )
131
- elif result is not None :
132
- # If we do not want to filter the values, we filter out `None`s
133
- out_l .append (sensor_data )
118
+ out_l = filter_column_to_array (self .all_sensors , channel , column , value_filter )
134
119
135
120
if len (out_l ) == 0 :
136
121
# pylint: disable=line-too-long
@@ -181,3 +166,63 @@ def to_dataframe(self,
181
166
182
167
sensor_data .index = sensor_data .pop ('id' )
183
168
return sensor_data
169
+
170
+ def to_dataframe_multi_filter (self ,
171
+ channel : str ,
172
+ sensor_filters : Optional [str ] = None ,
173
+ column : Optional [str ] = None ,
174
+ value_filter : Union [str , int , float , None ] = None ) -> pd .DataFrame :
175
+ """
176
+ Returns a Pandas dataframe with filtered sensors, based on multiple filters
177
+ provided by the user. If no filters are provided, we return all sensors in
178
+ self.all_sensors.
179
+ """
180
+
181
+ if not sensor_filters or len (sensor_filters ) == 0 or 'all' in sensor_filters :
182
+ sensor_data = pd .DataFrame ([s .as_flat_dict (channel ) for s in self .all_sensors ])
183
+ else :
184
+ relevant_sensors = self .all_sensors
185
+
186
+ if 'outside' in sensor_filters :
187
+ relevant_sensors = [s for s in relevant_sensors if s .location_type == 'outside' ]
188
+ if 'useful' in sensor_filters :
189
+ relevant_sensors = [s for s in relevant_sensors if s .is_useful ()]
190
+ if 'family' in sensor_filters :
191
+ relevant_sensors = [s for s in relevant_sensors if s .parent and s .child ]
192
+ if 'no_child' in sensor_filters :
193
+ relevant_sensors = [s for s in relevant_sensors if not s .child ]
194
+
195
+ if 'column' in sensor_filters :
196
+ relevant_sensors = filter_column_to_array (
197
+ relevant_sensors , channel , column , value_filter )
198
+ else :
199
+ relevant_sensors = [s .as_flat_dict (channel ) for s in relevant_sensors ]
200
+ sensor_data = pd .DataFrame (relevant_sensors )
201
+
202
+ sensor_data .index = sensor_data .pop ('id' )
203
+ return sensor_data
204
+
205
+ def filter_column_to_array (
206
+ sensors , channel : str , column : Optional [str ],
207
+ value_filter : Union [str , int , float , None ]
208
+ ) -> List [dict ]:
209
+ """
210
+ Filter sensors by column and value_filter. If only column is passed, we
211
+ return rows that are not None. If the value_filter is passed, we only
212
+ return rows where the column matches that value.
213
+ """
214
+ out_l : List [dict ] = []
215
+ for sensor in sensors :
216
+ sensor_data = sensor .as_flat_dict (channel )
217
+ if column not in sensor_data :
218
+ raise ValueError (
219
+ f'Requested column { column } does not exist in sensor data!' )
220
+ result = sensor_data .get (column )
221
+ if value_filter and result != value_filter :
222
+ continue
223
+ if value_filter and result == value_filter :
224
+ out_l .append (sensor_data )
225
+ elif result is not None :
226
+ # If we do not want to filter the values, we filter out `None`s
227
+ out_l .append (sensor_data )
228
+ return out_l
0 commit comments