Create a single numpy array from a dataset.

    The dataset must have only one dimension, that is,
    the length of its `output_shapes` and `output_types`
    is 1, and its output shape must be `[]`, that is,
    every tensor in the dataset must be a scalar.

    Args:
      ds:  a TF Dataset.
      batch_size:  how many elements to read per pass

    Returns:
      a single numpy array.

def make_single_array(ds, batch_size=8*1024):
    """Create a single numpy array from a dataset.

    The dataset must have only one dimension, that is,
    the length of its `output_shapes` and `output_types`
    is 1, and its output shape must be `[]`, that is,
    every tensor in the dataset must be a scalar.

    Args:
      ds:  a TF Dataset.
      batch_size:  how many elements to read per pass

    Returns:
      a single numpy array.
    """
    if isinstance(ds.output_types, tuple) or isinstance(ds.output_shapes, tuple):
        raise ValueError('Dataset must have a single type and shape')
    nshapes = len(ds.output_shapes)
    if nshapes > 0:
        raise ValueError('Dataset must be comprised of scalars (TensorShape=[])')
    batches = []
    with tf.Session() as sess:
        ds = ds.batch(batch_size)
        iterator = ds.make_initializable_iterator()
        sess.run(iterator.initializer)
        get_next = iterator.get_next()
        with tqdm(desc='Elements', unit_scale=1) as pbar:
            try:
                while True:
                    batches.append(sess.run(get_next))
                    pbar.update(len(batches[-1]))
            except tf.errors.OutOfRangeError:
                pass
    if batches:
        return np.concatenate(batches)
    return np.array([], dtype=ds.output_types.as_numpy_dtype)