17
17
from pandas .core .internals import (IntBlock , BoolBlock , BlockManager ,
18
18
make_block , _consolidate )
19
19
from pandas .util .decorators import cache_readonly , Appender , Substitution
20
- from pandas .core .common import PandasError , ABCSeries
20
+ from pandas .core .common import (PandasError , ABCSeries ,
21
+ is_timedelta64_dtype , is_datetime64_dtype ,
22
+ is_integer_dtype )
23
+
21
24
import pandas .core .common as com
22
25
23
26
import pandas .lib as lib
24
27
import pandas .algos as algos
25
28
import pandas .hashtable as _hash
26
-
29
+ import pandas . tslib as tslib
27
30
28
31
@Substitution ('\n left : DataFrame' )
29
32
@Appender (_merge_doc , indents = 0 )
@@ -1128,6 +1131,8 @@ def _concat_blocks(self, blocks):
1128
1131
return block
1129
1132
1130
1133
def _concat_single_item (self , objs , item ):
1134
+ # this is called if we don't have consistent dtypes in a row-wise append
1135
+
1131
1136
all_values = []
1132
1137
dtypes = set ()
1133
1138
@@ -1141,22 +1146,57 @@ def _concat_single_item(self, objs, item):
1141
1146
else :
1142
1147
all_values .append (None )
1143
1148
1144
- # this stinks
1145
- have_object = False
1149
+ # figure out the resulting dtype of the combination
1150
+ alls = set ()
1151
+ seen = []
1146
1152
for dtype in dtypes :
1153
+ d = dict ([ (t ,False ) for t in ['object' ,'datetime' ,'timedelta' ,'other' ] ])
1147
1154
if issubclass (dtype .type , (np .object_ , np .bool_ )):
1148
- have_object = True
1149
- if have_object :
1150
- empty_dtype = np .object_
1151
- else :
1152
- empty_dtype = np .float64
1155
+ d ['object' ] = True
1156
+ alls .add ('object' )
1157
+ elif is_datetime64_dtype (dtype ):
1158
+ d ['datetime' ] = True
1159
+ alls .add ('datetime' )
1160
+ elif is_timedelta64_dtype (dtype ):
1161
+ d ['timedelta' ] = True
1162
+ alls .add ('timedelta' )
1163
+ else :
1164
+ d ['other' ] = True
1165
+ alls .add ('other' )
1166
+ seen .append (d )
1167
+
1168
+ if 'datetime' in alls or 'timedelta' in alls :
1169
+
1170
+ if 'object' in alls or 'other' in alls :
1171
+ for v , s in zip (all_values ,seen ):
1172
+ if s .get ('datetime' ) or s .get ('timedelta' ):
1173
+ pass
1174
+
1175
+ # if we have all null, then leave a date/time like type
1176
+ # if we have only that type left
1177
+ elif isnull (v ).all ():
1178
+
1179
+ alls .remove ('other' )
1180
+ alls .remove ('object' )
1181
+
1182
+ # create the result
1183
+ if 'object' in alls :
1184
+ empty_dtype , fill_value = np .object_ , np .nan
1185
+ elif 'other' in alls :
1186
+ empty_dtype , fill_value = np .float64 , np .nan
1187
+ elif 'datetime' in alls :
1188
+ empty_dtype , fill_value = 'M8[ns]' , tslib .iNaT
1189
+ elif 'timedelta' in alls :
1190
+ empty_dtype , fill_value = 'm8[ns]' , tslib .iNaT
1191
+ else : # pragma
1192
+ raise AssertionError ("invalid dtype determination in concat_single_item" )
1153
1193
1154
1194
to_concat = []
1155
1195
for obj , item_values in zip (objs , all_values ):
1156
1196
if item_values is None :
1157
1197
shape = obj .shape [1 :]
1158
1198
missing_arr = np .empty (shape , dtype = empty_dtype )
1159
- missing_arr .fill (np . nan )
1199
+ missing_arr .fill (fill_value )
1160
1200
to_concat .append (missing_arr )
1161
1201
else :
1162
1202
to_concat .append (item_values )
0 commit comments