def create_mgr(descr, item_shape=None):
if item_shape is None:<EOL><INDENT>item_shape = (N, )<EOL><DEDENT>offset = <NUM_LIT:0><EOL>mgr_items = []<EOL>block_placements = OrderedDict()<EOL>for d in descr.split('<STR_LIT:;>'):<EOL><INDENT>d = d.strip()<EOL>if not len(d):<EOL><INDENT>continue<EOL><DEDENT>names, blockstr = d.partition('<STR_LIT::>')[::<NUM_LIT:2>]<EOL>blockstr = blockstr.strip()<EOL>names = names.strip().split('<STR_LIT:U+002C>')<EOL>mgr_items.extend(names)<EOL>placement = list(np.arange(len(names)) + offset)<EOL>try:<EOL><INDENT>block_placements[blockstr].extend(placement)<EOL><DEDENT>except KeyError:<EOL><INDENT>block_placements[blockstr] = placement<EOL><DEDENT>offset += len(names)<EOL><DEDENT>mgr_items = Index(mgr_items)<EOL>blocks = []<EOL>num_offset = <NUM_LIT:0><EOL>for blockstr, placement in block_placements.items():<EOL><INDENT>typestr = blockstr.split('<STR_LIT:->')[<NUM_LIT:0>]<EOL>blocks.append(create_block(typestr,<EOL>placement,<EOL>item_shape=item_shape,<EOL>num_offset=num_offset, ))<EOL>num_offset += len(placement)<EOL><DEDENT>return BlockManager(sorted(blocks, key=lambda b: b.mgr_locs[<NUM_LIT:0>]),<EOL>[mgr_items] + [np.arange(n) for n in item_shape])<EOL>
Construct BlockManager from string description.

String description syntax looks similar to np.matrix initializer.  It looks
like this::

    a,b,c: f8; d,e,f: i8

Rules are rather simple:

* see list of supported datatypes in `create_block` method
* components are semicolon-separated
* each component is `NAME,NAME,NAME: DTYPE_ID`
* whitespace around colons & semicolons are removed
* components with same DTYPE_ID are combined into single block
* to force multiple blocks with same dtype, use '-SUFFIX'::

    'a:f8-1; b:f8-2; c:f8-foobar'