<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def fromarray(values, index=None, labels=None, npartitions=None, engine=None):
 """ Load series data from an array. Assumes that all but final dimension index the records, and the size of the final dimension is the length of each record, e.g. a (2, 3, 4) array will be treated as 2 x 3 records of size (4,) Parameters values : array-like An array containing the data. Can be a numpy array, a bolt array, or an array-like. index : array, optional, default = None where N is the length of each record. labels : array, optional, default = None Labels for records. If provided, should have same shape as values.shape[:-1]. npartitions : int, default = None Number of partitions for parallelization (Spark only) engine : object, default = None Computational engine (e.g. a SparkContext for Spark) """

    from .series import Series
    import bolt

    if isinstance(values, bolt.spark.array.BoltArraySpark):
        return Series(values)

    values = asarray(values)

    if values.ndim < 2:
        values = expand_dims(values, 0)

    if index is not None and not asarray(index).shape[0] == values.shape[-1]:
        raise ValueError('Index length %s not equal to record length %s'
                         % (asarray(index).shape[0], values.shape[-1]))
    if index is None:
        index = arange(values.shape[-1])

    if spark and isinstance(engine, spark):
        axis = tuple(range(values.ndim - 1))
        values = bolt.array(values, context=engine, npartitions=npartitions, axis=axis)
        values._ordered = True
        return Series(values, index=index)

    return Series(values, index=index, labels=labels)