def concatenate_block_managers(mgrs_indexers, axes, concat_axis, copy):
concat_plans = [get_mgr_concatenation_plan(mgr, indexers)<EOL>for mgr, indexers in mgrs_indexers]<EOL>concat_plan = combine_concat_plans(concat_plans, concat_axis)<EOL>blocks = []<EOL>for placement, join_units in concat_plan:<EOL><INDENT>if len(join_units) == <NUM_LIT:1> and not join_units[<NUM_LIT:0>].indexers:<EOL><INDENT>b = join_units[<NUM_LIT:0>].block<EOL>values = b.values<EOL>if copy:<EOL><INDENT>values = values.copy()<EOL><DEDENT>elif not copy:<EOL><INDENT>values = values.view()<EOL><DEDENT>b = b.make_block_same_class(values, placement=placement)<EOL><DEDENT>elif is_uniform_join_units(join_units):<EOL><INDENT>b = join_units[<NUM_LIT:0>].block.concat_same_type(<EOL>[ju.block for ju in join_units], placement=placement)<EOL><DEDENT>else:<EOL><INDENT>b = make_block(<EOL>concatenate_join_units(join_units, concat_axis, copy=copy),<EOL>placement=placement)<EOL><DEDENT>blocks.append(b)<EOL><DEDENT>return BlockManager(blocks, axes)<EOL>
Concatenate block managers into one.

Parameters
----------
mgrs_indexers : list of (BlockManager, {axis: indexer,...}) tuples
axes : list of Index
concat_axis : int
copy : bool