@@ -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 )
323
+ def _get_counts_nanvar (mask , axis , ddof , dtype ):
324
+ count = _get_counts (mask , axis , dtype )
322
325
323
- d = count - ddof
326
+ d = count - dtype . type ( ddof )
324
327
325
328
# always return NaN, never inf
326
329
if np .isscalar (count ):
@@ -341,15 +344,15 @@ 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
+ count , d = _get_counts_nanvar (mask , axis , ddof , values . dtype )
345
348
346
349
if skipna :
347
350
values = values .copy ()
348
351
np .putmask (values , mask , 0 )
349
352
350
353
X = _ensure_numeric (values .sum (axis ))
351
354
XX = _ensure_numeric ((values ** 2 ).sum (axis ))
352
- return np .fabs ((XX - X ** 2 / count ) / d )
355
+ return np .fabs ((XX - X * X / count ) / d )
353
356
354
357
@disallow ('M8' )
355
358
@bottleneck_switch (ddof = 1 )
@@ -375,9 +378,9 @@ def nansem(values, axis=None, skipna=True, ddof=1):
375
378
mask = isnull (values )
376
379
if not is_floating_dtype (values ):
377
380
values = values .astype ('f8' )
378
- count , _ = _get_counts_nanvar (mask , axis , ddof )
381
+ count , _ = _get_counts_nanvar (mask , axis , ddof , values . dtype )
379
382
380
- return np .sqrt (var )/ np .sqrt (count )
383
+ return np .sqrt (var ) / np .sqrt (count )
381
384
382
385
383
386
@bottleneck_switch ()
@@ -467,25 +470,29 @@ def nanargmin(values, axis=None, skipna=True):
467
470
def nanskew (values , axis = None , skipna = True ):
468
471
469
472
mask = isnull (values )
470
- if not is_floating_dtype (values ):
473
+ if not is_float_dtype (values ):
471
474
values = values .astype ('f8' )
472
-
473
- count = _get_counts (mask , axis )
475
+ count = _get_counts (mask , axis )
476
+ else :
477
+ count = _get_counts (mask , axis , dtype = values .dtype )
474
478
475
479
if skipna :
476
480
values = values .copy ()
477
481
np .putmask (values , mask , 0 )
478
482
483
+ typ = values .dtype .type
479
484
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
485
+ B = (values ** 2 ).sum (axis ) / count - A ** typ ( 2 )
486
+ C = (values ** 3 ).sum (axis ) / count - A ** typ ( 3 ) - typ ( 3 ) * A * B
482
487
483
488
# floating point error
484
489
B = _zero_out_fperr (B )
485
490
C = _zero_out_fperr (C )
486
491
487
- result = ((np .sqrt ((count ** 2 - count )) * C ) /
488
- ((count - 2 ) * np .sqrt (B ) ** 3 ))
492
+ # result = ((np.sqrt((count ** 2 - count)) * C) /
493
+ # ((count - 2) * np.sqrt(B) ** 3))
494
+ result = ((np .sqrt (count * count - count ) * C ) /
495
+ ((count - typ (2 )) * np .sqrt (B ) ** typ (3 )))
489
496
490
497
if isinstance (result , np .ndarray ):
491
498
result = np .where (B == 0 , 0 , result )
@@ -502,19 +509,21 @@ def nanskew(values, axis=None, skipna=True):
502
509
def nankurt (values , axis = None , skipna = True ):
503
510
504
511
mask = isnull (values )
505
- if not is_floating_dtype (values ):
512
+ if not is_float_dtype (values ):
506
513
values = values .astype ('f8' )
507
-
508
- count = _get_counts (mask , axis )
514
+ count = _get_counts (mask , axis )
515
+ else :
516
+ count = _get_counts (mask , axis , dtype = values .dtype )
509
517
510
518
if skipna :
511
519
values = values .copy ()
512
520
np .putmask (values , mask , 0 )
513
521
522
+ typ = values .dtype .type
514
523
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
524
+ B = (values ** 2 ).sum (axis ) / count - A ** typ ( 2 )
525
+ C = (values ** 3 ).sum (axis ) / count - A ** typ ( 3 ) - typ ( 3 ) * A * B
526
+ D = (values ** 4 ).sum (axis ) / count - A ** typ ( 4 ) - typ ( 6 ) * B * A * A - typ ( 4 ) * C * A
518
527
519
528
B = _zero_out_fperr (B )
520
529
D = _zero_out_fperr (D )
@@ -526,8 +535,8 @@ def nankurt(values, axis=None, skipna=True):
526
535
if B == 0 :
527
536
return 0
528
537
529
- result = (((count * count - 1. ) * D / (B * B ) - 3 * ((count - 1. ) ** 2 )) /
530
- ((count - 2. ) * (count - 3. )))
538
+ result = (((count * count - typ ( 1 )) * D / (B * B ) - typ ( 3 ) * ((count - typ ( 1 )) ** typ ( 2 ) )) /
539
+ ((count - typ ( 2 )) * (count - typ ( 3 ) )))
531
540
532
541
if isinstance (result , np .ndarray ):
533
542
result = np .where (B == 0 , 0 , result )
@@ -598,7 +607,7 @@ def _zero_out_fperr(arg):
598
607
if isinstance (arg , np .ndarray ):
599
608
return np .where (np .abs (arg ) < 1e-14 , 0 , arg )
600
609
else :
601
- return 0 if np .abs (arg ) < 1e-14 else arg
610
+ return arg . dtype . type ( 0 ) if np .abs (arg ) < 1e-14 else arg
602
611
603
612
604
613
@disallow ('M8' ,'m8' )
0 commit comments