@@ -139,6 +139,7 @@ def __init__(self, kind: str, how: str, has_dropped_na: bool) -> None:
139
139
"var" : "group_var" ,
140
140
"std" : functools .partial (libgroupby .group_var , name = "std" ),
141
141
"sem" : functools .partial (libgroupby .group_var , name = "sem" ),
142
+ "skew" : "group_skew" ,
142
143
"first" : "group_nth" ,
143
144
"last" : "group_last" ,
144
145
"ohlc" : "group_ohlc" ,
@@ -182,7 +183,10 @@ def _get_cython_function(
182
183
elif how in ["std" , "sem" ]:
183
184
# We have a partial object that does not have __signatures__
184
185
return f
185
- if "object" not in f .__signatures__ :
186
+ elif how == "skew" :
187
+ # _get_cython_vals will convert to float64
188
+ pass
189
+ elif "object" not in f .__signatures__ :
186
190
# raise NotImplementedError here rather than TypeError later
187
191
raise NotImplementedError (
188
192
f"function is not implemented for this dtype: "
@@ -210,7 +214,7 @@ def _get_cython_vals(self, values: np.ndarray) -> np.ndarray:
210
214
"""
211
215
how = self .how
212
216
213
- if how in ["median" , "std" , "sem" ]:
217
+ if how in ["median" , "std" , "sem" , "skew" ]:
214
218
# median only has a float64 implementation
215
219
# We should only get here with is_numeric, as non-numeric cases
216
220
# should raise in _get_cython_function
@@ -252,7 +256,7 @@ def _disallow_invalid_ops(self, dtype: DtypeObj):
252
256
return
253
257
254
258
if isinstance (dtype , CategoricalDtype ):
255
- if how in ["sum" , "prod" , "cumsum" , "cumprod" ]:
259
+ if how in ["sum" , "prod" , "cumsum" , "cumprod" , "skew" ]:
256
260
raise TypeError (f"{ dtype } type does not support { how } operations" )
257
261
if how in ["min" , "max" , "rank" ] and not dtype .ordered :
258
262
# raise TypeError instead of NotImplementedError to ensure we
@@ -268,7 +272,7 @@ def _disallow_invalid_ops(self, dtype: DtypeObj):
268
272
raise NotImplementedError (f"{ dtype } dtype not supported" )
269
273
elif is_datetime64_any_dtype (dtype ):
270
274
# Adding/multiplying datetimes is not valid
271
- if how in ["sum" , "prod" , "cumsum" , "cumprod" , "var" ]:
275
+ if how in ["sum" , "prod" , "cumsum" , "cumprod" , "var" , "skew" ]:
272
276
raise TypeError (f"datetime64 type does not support { how } operations" )
273
277
if how in ["any" , "all" ]:
274
278
# GH#34479
@@ -281,7 +285,7 @@ def _disallow_invalid_ops(self, dtype: DtypeObj):
281
285
282
286
elif is_period_dtype (dtype ):
283
287
# Adding/multiplying Periods is not valid
284
- if how in ["sum" , "prod" , "cumsum" , "cumprod" , "var" ]:
288
+ if how in ["sum" , "prod" , "cumsum" , "cumprod" , "var" , "skew" ]:
285
289
raise TypeError (f"Period type does not support { how } operations" )
286
290
if how in ["any" , "all" ]:
287
291
# GH#34479
@@ -294,7 +298,7 @@ def _disallow_invalid_ops(self, dtype: DtypeObj):
294
298
295
299
elif is_timedelta64_dtype (dtype ):
296
300
# timedeltas we can add but not multiply
297
- if how in ["prod" , "cumprod" ]:
301
+ if how in ["prod" , "cumprod" , "skew" ]:
298
302
raise TypeError (f"timedelta64 type does not support { how } operations" )
299
303
300
304
def _get_output_shape (self , ngroups : int , values : np .ndarray ) -> Shape :
@@ -643,6 +647,19 @@ def _call_cython_op(
643
647
** kwargs ,
644
648
)
645
649
result = result .astype (bool , copy = False )
650
+ elif self .how in ["skew" ]:
651
+ func (
652
+ out = result ,
653
+ counts = counts ,
654
+ values = values ,
655
+ labels = comp_ids ,
656
+ mask = mask ,
657
+ result_mask = result_mask ,
658
+ ** kwargs ,
659
+ )
660
+ if dtype == object :
661
+ result = result .astype (object )
662
+
646
663
else :
647
664
raise NotImplementedError (f"{ self .how } is not implemented" )
648
665
else :
0 commit comments