22
22
notnull , _DATELIKE_DTYPES , is_numeric_dtype ,
23
23
is_timedelta64_dtype , is_datetime64_dtype )
24
24
25
+ from pandas import _np_version_under1p7
25
26
import pandas .lib as lib
26
27
from pandas .lib import Timestamp
27
28
import pandas .algos as _algos
@@ -2243,16 +2244,19 @@ def _wrap_applied_output(self, keys, values, not_indexed_same=False):
2243
2244
try :
2244
2245
if self .axis == 0 :
2245
2246
2246
- stacked_values = np .vstack ([np .asarray (x )
2247
- for x in values ])
2248
- columns = v .index
2249
- index = key_index
2247
+ # normally use vstack as its faster than concat
2248
+ # and if we have mi-columns
2249
+ if not _np_version_under1p7 or isinstance (v .index ,MultiIndex ):
2250
+ stacked_values = np .vstack ([np .asarray (x ) for x in values ])
2251
+ result = DataFrame (stacked_values ,index = key_index ,columns = v .index )
2252
+ else :
2253
+ # GH5788 instead of stacking; concat gets the dtypes correct
2254
+ from pandas .tools .merge import concat
2255
+ result = concat (values ,keys = key_index ,names = key_index .names ,
2256
+ axis = self .axis ).unstack ()
2250
2257
else :
2251
- stacked_values = np .vstack ([np .asarray (x )
2252
- for x in values ]).T
2253
-
2254
- index = v .index
2255
- columns = key_index
2258
+ stacked_values = np .vstack ([np .asarray (x ) for x in values ])
2259
+ result = DataFrame (stacked_values .T ,index = v .index ,columns = key_index )
2256
2260
2257
2261
except (ValueError , AttributeError ):
2258
2262
# GH1738: values is list of arrays of unequal lengths fall
@@ -2261,17 +2265,12 @@ def _wrap_applied_output(self, keys, values, not_indexed_same=False):
2261
2265
2262
2266
# if we have date/time like in the original, then coerce dates
2263
2267
# as we are stacking can easily have object dtypes here
2264
- cd = True
2265
- if self .obj .ndim == 2 and self .obj .dtypes .isin (_DATELIKE_DTYPES ).any ():
2266
- cd = 'coerce'
2267
- return DataFrame (stacked_values , index = index ,
2268
- columns = columns ).convert_objects (convert_dates = cd , convert_numeric = True )
2268
+ cd = 'coerce' if self .obj .ndim == 2 and self .obj .dtypes .isin (_DATELIKE_DTYPES ).any () else True
2269
+ return result .convert_objects (convert_dates = cd , convert_numeric = True )
2269
2270
2270
2271
else :
2271
2272
# only coerce dates if we find at least 1 datetime
2272
- cd = False
2273
- if any ([ isinstance (v ,Timestamp ) for v in values ]):
2274
- cd = 'coerce'
2273
+ cd = 'coerce' if any ([ isinstance (v ,Timestamp ) for v in values ]) else False
2275
2274
return Series (values , index = key_index ).convert_objects (convert_dates = cd )
2276
2275
2277
2276
else :
0 commit comments