Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
xuancong84 opened this issue Sep 10, 2020 · 2 comments · Fixed by #36290 or #45888
Closed

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

xuancong84 opened this issue Sep 10, 2020 · 2 comments · Fixed by #36290 or #45888
Assignees
Labels
good first issue Needs Tests Unit test(s) needed to prevent regressions Reshaping Concat, Merge/Join, Stack/Unstack, Explode
Milestone

Comments

@xuancong84
Copy link

xuancong84 commented Sep 10, 2020

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
@xuancong84 xuancong84 added Bug Needs Triage Issue that has not been reviewed by a pandas team member labels Sep 10, 2020
@dsaxton dsaxton added Reshaping Concat, Merge/Join, Stack/Unstack, Explode and removed Needs Triage Issue that has not been reviewed by a pandas team member labels Sep 10, 2020
@phofl phofl self-assigned this Sep 10, 2020
@jreback jreback added this to the 1.2 milestone Sep 13, 2020
@jreback jreback modified the milestones: 1.2, Contributions Welcome Nov 19, 2020
@jreback jreback reopened this Dec 24, 2020
@jreback
Copy link
Contributor

jreback commented Dec 24, 2020

this should now raise (need tests)

cc @ivirshup @phofl

@jreback jreback modified the milestones: 1.2, 1.2.1 Dec 24, 2020
@jreback jreback modified the milestones: 1.2.1, 1.3 Jan 6, 2021
@simonjayhawkins simonjayhawkins modified the milestones: 1.3, Contributions Welcome May 24, 2021
@mroeschke mroeschke added good first issue Needs Tests Unit test(s) needed to prevent regressions and removed Bug labels Aug 13, 2021
@kasmith11
Copy link
Contributor

take

@mroeschke mroeschke modified the milestones: Contributions Welcome, 1.5 Feb 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment