@@ -52,19 +52,24 @@ def __init__(self, obj, orient, date_format, double_precision, ensure_ascii):
52
52
self ._format_axes ()
53
53
self ._format_dates ()
54
54
55
+ def _needs_to_date (self , obj ):
56
+ return obj .dtype == 'datetime64[ns]'
57
+
55
58
def _format_dates (self ):
56
59
raise NotImplementedError
57
60
58
61
def _format_axes (self ):
59
62
raise NotImplementedError
60
63
61
- def _needs_to_date (self , data ):
62
- return self .date_format == 'iso' and data .dtype == 'datetime64[ns]'
63
-
64
64
def _format_to_date (self , data ):
65
- if self ._needs_to_date (data ):
65
+
66
+ # iso
67
+ if self .date_format == 'iso' :
66
68
return data .apply (lambda x : x .isoformat ())
67
- return data
69
+
70
+ # int64
71
+ else :
72
+ return data .astype (np .int64 )
68
73
69
74
def copy_if_needed (self ):
70
75
""" copy myself if necessary """
@@ -87,13 +92,11 @@ def _format_axes(self):
87
92
self .obj .index = self ._format_to_date (self .obj .index .to_series ())
88
93
89
94
def _format_dates (self ):
90
- if self ._needs_to_date (self .obj ):
91
- self .copy_if_needed ()
95
+ if self .obj .dtype == 'datetime64[ns]' :
92
96
self .obj = self ._format_to_date (self .obj )
93
97
94
98
def _format_bools (self ):
95
99
if self ._needs_to_bool (self .obj ):
96
- self .copy_if_needed ()
97
100
self .obj = self ._format_to_bool (self .obj )
98
101
99
102
class FrameWriter (Writer ):
@@ -123,13 +126,22 @@ def _format_axes(self):
123
126
setattr (self .obj ,axis ,self ._format_to_date (a .to_series ()))
124
127
125
128
def _format_dates (self ):
126
- if self .date_format == 'iso' :
127
- dtypes = self .obj .dtypes
128
- dtypes = dtypes [dtypes == 'datetime64[ns]' ]
129
- if len (dtypes ):
130
- self .copy_if_needed ()
131
- for c in dtypes .index :
132
- self .obj [c ] = self ._format_to_date (self .obj [c ])
129
+ dtypes = self .obj .dtypes
130
+ if len (dtypes [dtypes == 'datetime64[ns]' ]):
131
+
132
+ # need to create a new object
133
+ d = {}
134
+
135
+ for i , (col , c ) in enumerate (self .obj .iteritems ()):
136
+
137
+ if c .dtype == 'datetime64[ns]' :
138
+ c = self ._format_to_date (c )
139
+
140
+ d [i ] = c
141
+
142
+ d = DataFrame (d ,index = self .obj .index )
143
+ d .columns = self .obj .columns
144
+ self .obj = d
133
145
134
146
def read_json (path_or_buf = None , orient = None , typ = 'frame' , dtype = True ,
135
147
convert_axes = True , convert_dates = True , keep_default_dates = True ,
@@ -291,14 +303,16 @@ def _try_convert_data(self, name, data, use_dtypes=True, convert_dates=True):
291
303
except :
292
304
pass
293
305
294
- if data .dtype == 'float ' :
306
+ if data .dtype . kind == 'f ' :
295
307
296
- # coerce floats to 64
297
- try :
298
- data = data .astype ('float64' )
299
- result = True
300
- except :
301
- pass
308
+ if data .dtype != 'float64' :
309
+
310
+ # coerce floats to 64
311
+ try :
312
+ data = data .astype ('float64' )
313
+ result = True
314
+ except :
315
+ pass
302
316
303
317
# do't coerce 0-len data
304
318
if len (data ) and (data .dtype == 'float' or data .dtype == 'object' ):
@@ -448,14 +462,35 @@ def _parse_no_numpy(self):
448
462
self .obj = DataFrame (
449
463
loads (json , precise_float = self .precise_float ), dtype = None )
450
464
465
+ def _process_converter (self , f , filt = None ):
466
+ """ take a conversion function and possibly recreate the frame """
467
+
468
+ if filt is None :
469
+ filt = lambda col , c : True
470
+
471
+ needs_new_obj = False
472
+ new_obj = dict ()
473
+ for i , (col , c ) in enumerate (self .obj .iteritems ()):
474
+ if filt (col , c ):
475
+ new_data , result = f (col , c )
476
+ if result :
477
+ c = new_data
478
+ needs_new_obj = True
479
+ new_obj [i ] = c
480
+
481
+ if needs_new_obj :
482
+
483
+ # possibly handle dup columns
484
+ new_obj = DataFrame (new_obj ,index = self .obj .index )
485
+ new_obj .columns = self .obj .columns
486
+ self .obj = new_obj
487
+
451
488
def _try_convert_types (self ):
452
489
if self .obj is None : return
453
490
if self .convert_dates :
454
491
self ._try_convert_dates ()
455
- for col in self .obj .columns :
456
- new_data , result = self ._try_convert_data (col , self .obj [col ], convert_dates = False )
457
- if result :
458
- self .obj [col ] = new_data
492
+
493
+ self ._process_converter (lambda col , c : self ._try_convert_data (col , c , convert_dates = False ))
459
494
460
495
def _try_convert_dates (self ):
461
496
if self .obj is None : return
@@ -478,9 +513,6 @@ def is_ok(col):
478
513
return True
479
514
return False
480
515
516
+ self ._process_converter (lambda col , c : self ._try_convert_to_date (c ),
517
+ lambda col , c : (self .keep_default_dates and is_ok (col )) or col in convert_dates )
481
518
482
- for col in self .obj .columns :
483
- if (self .keep_default_dates and is_ok (col )) or col in convert_dates :
484
- new_data , result = self ._try_convert_to_date (self .obj [col ])
485
- if result :
486
- self .obj [col ] = new_data
0 commit comments