@@ -244,7 +244,10 @@ def nanall(values, axis=None, skipna=True):
244
244
@bottleneck_switch (zero_value = 0 )
245
245
def nansum (values , axis = None , skipna = True ):
246
246
values , mask , dtype , dtype_max = _get_values (values , skipna , 0 )
247
- the_sum = values .sum (axis , dtype = dtype_max )
247
+ dtype_sum = dtype_max
248
+ if is_float_dtype (dtype ):
249
+ dtype_sum = dtype
250
+ the_sum = values .sum (axis , dtype = dtype_sum )
248
251
the_sum = _maybe_null_out (the_sum , axis , mask )
249
252
250
253
return _wrap_results (the_sum , dtype )
@@ -288,7 +291,7 @@ def get_median(x):
288
291
return np .nan
289
292
return algos .median (_values_from_object (x [mask ]))
290
293
291
- if values . dtype != np . float64 :
294
+ if not is_float_dtype ( values ) :
292
295
values = values .astype ('f8' )
293
296
values [mask ] = np .nan
294
297
@@ -317,10 +320,10 @@ def get_median(x):
317
320
return _wrap_results (get_median (values ) if notempty else np .nan , dtype )
318
321
319
322
320
- def _get_counts_nanvar (mask , axis , ddof ):
321
- count = _get_counts ( mask , axis )
322
-
323
- d = count - ddof
323
+ def _get_counts_nanvar (mask , axis , ddof , dtype = float ):
324
+ dtype = _get_dtype ( dtype )
325
+ count = _get_counts ( mask , axis , dtype = dtype )
326
+ d = count - dtype . type ( ddof )
324
327
325
328
# always return NaN, never inf
326
329
if np .isscalar (count ):
@@ -341,15 +344,19 @@ def _nanvar(values, axis=None, skipna=True, ddof=1):
341
344
if is_any_int_dtype (values ):
342
345
values = values .astype ('f8' )
343
346
344
- count , d = _get_counts_nanvar (mask , axis , ddof )
347
+ if is_float_dtype (values ):
348
+ count , d = _get_counts_nanvar (mask , axis , ddof , values .dtype )
349
+ else :
350
+ count , d = _get_counts_nanvar (mask , axis , ddof )
345
351
346
352
if skipna :
347
353
values = values .copy ()
348
354
np .putmask (values , mask , 0 )
349
355
350
356
X = _ensure_numeric (values .sum (axis ))
351
357
XX = _ensure_numeric ((values ** 2 ).sum (axis ))
352
- return np .fabs ((XX - X ** 2 / count ) / d )
358
+ result = np .fabs ((XX - X * X / count ) / d )
359
+ return result
353
360
354
361
@disallow ('M8' )
355
362
@bottleneck_switch (ddof = 1 )
@@ -375,9 +382,9 @@ def nansem(values, axis=None, skipna=True, ddof=1):
375
382
mask = isnull (values )
376
383
if not is_float_dtype (values .dtype ):
377
384
values = values .astype ('f8' )
378
- count , _ = _get_counts_nanvar (mask , axis , ddof )
385
+ count , _ = _get_counts_nanvar (mask , axis , ddof , values . dtype )
379
386
380
- return np .sqrt (var )/ np .sqrt (count )
387
+ return np .sqrt (var ) / np .sqrt (count )
381
388
382
389
383
390
@bottleneck_switch ()
@@ -469,23 +476,25 @@ def nanskew(values, axis=None, skipna=True):
469
476
mask = isnull (values )
470
477
if not is_float_dtype (values .dtype ):
471
478
values = values .astype ('f8' )
472
-
473
- count = _get_counts (mask , axis )
479
+ count = _get_counts (mask , axis )
480
+ else :
481
+ count = _get_counts (mask , axis , dtype = values .dtype )
474
482
475
483
if skipna :
476
484
values = values .copy ()
477
485
np .putmask (values , mask , 0 )
478
486
487
+ typ = values .dtype .type
479
488
A = values .sum (axis ) / count
480
- B = (values ** 2 ).sum (axis ) / count - A ** 2
481
- C = (values ** 3 ).sum (axis ) / count - A ** 3 - 3 * A * B
489
+ B = (values ** 2 ).sum (axis ) / count - A ** typ ( 2 )
490
+ C = (values ** 3 ).sum (axis ) / count - A ** typ ( 3 ) - typ ( 3 ) * A * B
482
491
483
492
# floating point error
484
493
B = _zero_out_fperr (B )
485
494
C = _zero_out_fperr (C )
486
495
487
- result = ((np .sqrt (( count ** 2 - count ) ) * C ) /
488
- ((count - 2 ) * np .sqrt (B ) ** 3 ))
496
+ result = ((np .sqrt (count * count - count ) * C ) /
497
+ ((count - typ ( 2 )) * np .sqrt (B ) ** typ ( 3 ) ))
489
498
490
499
if isinstance (result , np .ndarray ):
491
500
result = np .where (B == 0 , 0 , result )
@@ -504,17 +513,19 @@ def nankurt(values, axis=None, skipna=True):
504
513
mask = isnull (values )
505
514
if not is_float_dtype (values .dtype ):
506
515
values = values .astype ('f8' )
507
-
508
- count = _get_counts (mask , axis )
516
+ count = _get_counts (mask , axis )
517
+ else :
518
+ count = _get_counts (mask , axis , dtype = values .dtype )
509
519
510
520
if skipna :
511
521
values = values .copy ()
512
522
np .putmask (values , mask , 0 )
513
523
524
+ typ = values .dtype .type
514
525
A = values .sum (axis ) / count
515
- B = (values ** 2 ).sum (axis ) / count - A ** 2
516
- C = (values ** 3 ).sum (axis ) / count - A ** 3 - 3 * A * B
517
- D = (values ** 4 ).sum (axis ) / count - A ** 4 - 6 * B * A * A - 4 * C * A
526
+ B = (values ** 2 ).sum (axis ) / count - A ** typ ( 2 )
527
+ C = (values ** 3 ).sum (axis ) / count - A ** typ ( 3 ) - typ ( 3 ) * A * B
528
+ D = (values ** 4 ).sum (axis ) / count - A ** typ ( 4 ) - typ ( 6 ) * B * A * A - typ ( 4 ) * C * A
518
529
519
530
B = _zero_out_fperr (B )
520
531
D = _zero_out_fperr (D )
@@ -526,8 +537,8 @@ def nankurt(values, axis=None, skipna=True):
526
537
if B == 0 :
527
538
return 0
528
539
529
- result = (((count * count - 1. ) * D / (B * B ) - 3 * ((count - 1. ) ** 2 )) /
530
- ((count - 2. ) * (count - 3. )))
540
+ result = (((count * count - typ ( 1 )) * D / (B * B ) - typ ( 3 ) * ((count - typ ( 1 )) ** typ ( 2 ) )) /
541
+ ((count - typ ( 2 )) * (count - typ ( 3 ) )))
531
542
532
543
if isinstance (result , np .ndarray ):
533
544
result = np .where (B == 0 , 0 , result )
@@ -598,7 +609,7 @@ def _zero_out_fperr(arg):
598
609
if isinstance (arg , np .ndarray ):
599
610
return np .where (np .abs (arg ) < 1e-14 , 0 , arg )
600
611
else :
601
- return 0 if np .abs (arg ) < 1e-14 else arg
612
+ return arg . dtype . type ( 0 ) if np .abs (arg ) < 1e-14 else arg
602
613
603
614
604
615
@disallow ('M8' ,'m8' )
0 commit comments