@@ -2461,7 +2461,8 @@ def set_index(self, keys, drop=True, append=False, inplace=False,
2461
2461
frame .index = index
2462
2462
return frame
2463
2463
2464
- def reset_index (self , level = None , drop = False , inplace = False ):
2464
+ def reset_index (self , level = None , drop = False , inplace = False , col_level = 0 ,
2465
+ col_fill = '' ):
2465
2466
"""
2466
2467
For DataFrame with multi-level index, return new DataFrame with
2467
2468
labeling information in the columns under the index names, defaulting
@@ -2479,6 +2480,13 @@ def reset_index(self, level=None, drop=False, inplace=False):
2479
2480
the index to the default integer index.
2480
2481
inplace : boolean, default False
2481
2482
Modify the DataFrame in place (do not create a new object)
2483
+ col_level : int or str, default 0
2484
+ If the columns have multiple levels, determines which level the
2485
+ labels are inserted into. By default it is inserted into the first
2486
+ level.
2487
+ col_fill : object, default ''
2488
+ If the columns have multiple levels, determines how the other levels
2489
+ are named. If None then the index name is repeated.
2482
2490
2483
2491
Returns
2484
2492
-------
@@ -2507,11 +2515,22 @@ def _maybe_cast(values):
2507
2515
names = self .index .names
2508
2516
zipped = zip (self .index .levels , self .index .labels )
2509
2517
2518
+ multi_col = isinstance (self .columns , MultiIndex )
2510
2519
for i , (lev , lab ) in reversed (list (enumerate (zipped ))):
2511
2520
col_name = names [i ]
2512
2521
if col_name is None :
2513
2522
col_name = 'level_%d' % i
2514
2523
2524
+ if multi_col :
2525
+ if col_fill is None :
2526
+ col_name = tuple ([col_name ] *
2527
+ self .columns .nlevels )
2528
+ else :
2529
+ name_lst = [col_fill ] * self .columns .nlevels
2530
+ lev_num = self .columns ._get_level_number (col_level )
2531
+ name_lst [lev_num ] = col_name
2532
+ col_name = tuple (name_lst )
2533
+
2515
2534
# to ndarray and maybe infer different dtype
2516
2535
level_values = _maybe_cast (lev .values )
2517
2536
if level is None or i in level :
@@ -2521,6 +2540,14 @@ def _maybe_cast(values):
2521
2540
name = self .index .name
2522
2541
if name is None or name == 'index' :
2523
2542
name = 'index' if 'index' not in self else 'level_0'
2543
+ if isinstance (self .columns , MultiIndex ):
2544
+ if col_fill is None :
2545
+ name = tuple ([name ] * self .columns .nlevels )
2546
+ else :
2547
+ name_lst = [col_fill ] * self .columns .nlevels
2548
+ lev_num = self .columns ._get_level_number (col_level )
2549
+ name_lst [lev_num ] = name
2550
+ name = tuple (name_lst )
2524
2551
new_obj .insert (0 , name , _maybe_cast (self .index .values ))
2525
2552
2526
2553
new_obj .index = new_index
@@ -3368,7 +3395,7 @@ def update(self, other, join='left', overwrite=True, filter_func=None,
3368
3395
3369
3396
Parameters
3370
3397
----------
3371
- other : DataFrame
3398
+ other : DataFrame, or object coercible into a DataFrame
3372
3399
join : {'left', 'right', 'outer', 'inner'}, default 'left'
3373
3400
overwrite : boolean, default True
3374
3401
If True then overwrite values for common keys in the calling frame
@@ -3382,7 +3409,11 @@ def update(self, other, join='left', overwrite=True, filter_func=None,
3382
3409
if join != 'left' :
3383
3410
raise NotImplementedError
3384
3411
3412
+ if not isinstance (other , DataFrame ):
3413
+ other = DataFrame (other )
3414
+
3385
3415
other = other .reindex_like (self )
3416
+
3386
3417
for col in self .columns :
3387
3418
this = self [col ].values
3388
3419
that = other [col ].values
0 commit comments