Skip to content

pd.concat() crashes if dataframe contains duplicate indices but not df.join() #36263

@xuancong84

Description

@xuancong84

I just found out that when we concatenate two dataframes horizontally, if one dataframe has duplicate indices, pd.concat() will crash, but df.join() will not crash. Instead, df.join() will spread the values into all rows with the same index value. Is this behavior by design? Thanks!

df1 = pd.DataFrame(np.random.randn(5), index=[0,1,2,3,3], columns=['a']) df2 = pd.DataFrame(np.random.randn(5), index=[0,1,2,2,4], columns=['b']) dfj = df1.join(df2, how='outer') display(df1, df2, dfj) dfc = pd.concat([df1, df2], axis=1) display(dfc) 

image

--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-40-150ce3e802ea> in <module> 3 dfj = df1.join(df2, how='outer') 4 display(df1, df2, dfj) ----> 5 dfc = pd.concat([df1, df2], axis=1) 6 display(dfc) ~/anaconda3/lib/python3.7/site-packages/pandas/core/reshape/concat.py in concat(objs, axis, join, ignore_index, keys, levels, names, verify_integrity, sort, copy) 282 ) 283 --> 284 return op.get_result() 285 286 ~/anaconda3/lib/python3.7/site-packages/pandas/core/reshape/concat.py in get_result(self) 495 496 new_data = concatenate_block_managers( --> 497 mgrs_indexers, self.new_axes, concat_axis=self.axis, copy=self.copy 498 ) 499 if not self.copy: ~/anaconda3/lib/python3.7/site-packages/pandas/core/internals/managers.py in concatenate_block_managers(mgrs_indexers, axes, concat_axis, copy) 2025 blocks.append(b) 2026 -> 2027 return BlockManager(blocks, axes) ~/anaconda3/lib/python3.7/site-packages/pandas/core/internals/managers.py in __init__(self, blocks, axes, do_integrity_check) 137 138 if do_integrity_check: --> 139 self._verify_integrity() 140 141 self._consolidate_check() ~/anaconda3/lib/python3.7/site-packages/pandas/core/internals/managers.py in _verify_integrity(self) 332 for block in self.blocks: 333 if block._verify_integrity and block.shape[1:] != mgr_shape[1:]: --> 334 construction_error(tot_items, block.shape[1:], self.axes) 335 if len(self.items) != tot_items: 336 raise AssertionError( ~/anaconda3/lib/python3.7/site-packages/pandas/core/internals/managers.py in construction_error(tot_items, block_shape, axes, e) 1692 if block_shape[0] == 0: 1693 raise ValueError("Empty data passed with indices specified.") -> 1694 raise ValueError(f"Shape of passed values is {passed}, indices imply {implied}") 1695 1696 ValueError: Shape of passed values is (9, 2), indices imply (7, 2) 

By right, if the dataframes have duplicate indices, it can behave like df.join() and at least it should NOT crash.
I suggest we introduce additional arguments to handle duplicate indices, e.g., if the same index has X(>0) rows in df1, Y(>0) rows in df2, then if dup_index=:

  1. combinatorial: after merging, it will have X*Y rows for every combination possibility.
  2. outer-top-align: after merging, it will have max(X, Y) rows, in which the rows align from top
  3. outer-bottom-align: after merging, it will have max(X, Y) rows, in which the rows align from bottom
  4. inner-top-align: after merging, it will have min(X, Y) rows, in which the rows align from top
  5. inner-bottom-align: after merging, it will have min(X, Y) rows, in which the rows align from bottom
  6. raise: raise an exception with the warning message

Metadata

Metadata

Labels

Needs TestsUnit test(s) needed to prevent regressionsReshapingConcat, Merge/Join, Stack/Unstack, Explodegood first issue

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions