microsoft/qlib · error · ValueError

axis must be 0 or 1

Error message

axis must be 0 or 1

What it means

Raised by the concat helper in qlib/utils/index_data.py when merging SingleData/MultiData objects along an axis other than 0 or 1. The underlying storage is a plain numpy matrix, so only stacking by rows (axis=0) or by columns (axis=1) is meaningful. Any other axis value has no equivalent operation on this data structure.

Source

Thrown at qlib/utils/index_data.py:54

        raise NotImplementedError(f"please implement this func when axis == 0")
    elif axis == 1:
        # get all index and row
        all_index = set()
        for index_data in data_list:
            all_index = all_index | set(index_data.index)
        all_index = list(all_index)
        all_index.sort()
        all_index_map = dict(zip(all_index, range(len(all_index))))

        # concat all
        tmp_data = np.full((len(all_index), len(data_list)), np.nan)
        for data_id, index_data in enumerate(data_list):
            assert isinstance(index_data, SingleData)
            now_data_map = [all_index_map[index] for index in index_data.index]
            tmp_data[now_data_map, data_id] = index_data.data
        return MultiData(tmp_data, all_index)
    else:
        raise ValueError(f"axis must be 0 or 1")


def sum_by_index(data_list: Union[SingleData], new_index: list, fill_value=0) -> SingleData:
    """concat all SingleData by new index.

    Parameters
    ----------
    data_list : List[SingleData]
        the list of all SingleData to sum.
    new_index : list
        the new_index of new SingleData.
    fill_value : float
        fill the missing values or replace np.nan.

    Returns
    -------
    SingleData
        the SingleData with new_index and values after sum.

View on GitHub (pinned to 79633dd950)

Solutions

  1. Use axis=0 to stack data on new rows (result keeps column index) or axis=1 to add new columns (result keeps row index).
  2. If you need a higher-dimensional merge, do it in two steps: concat with axis=1 first, then wrap or transform the resulting MultiData manually.
  3. Convert to pandas (data.to_dataframe() or pd.DataFrame(multi_data.data, index=..., columns=...)) if your operation genuinely requires axes beyond 2.

Example fix

// before
merged = concat(single_data_list, axis=2)  # ValueError

// after
merged = concat(single_data_list, axis=1)  # add each SingleData as a new column
Defensive patterns

Strategy: validation

Validate before calling

from qlib.utils.index_data import concat
assert axis in (0, 1), f"concat supports axis 0/1 only, got {axis}"
merged = concat(data_list, axis=axis)

Type guard

def is_valid_concat_axis(axis) -> bool:
    return axis in (0, 1)

Prevention

When it happens

Trigger: Calling concat(data_list, axis=2), axis=-1, or passing a non-integer axis (e.g. a string like 'columns') to qlib.utils.index_data.concat with a list of SingleData objects.

Common situations: Porting pandas concat/df.stack code that uses axis names or higher axes; refactoring expression or data-handler pipelines that assumed DataFrame semantics; copy-pasting an axis value from a numpy call that allowed axis=2 on 3-D arrays.

Related errors


AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15). Data as JSON: /api/errors/e7151c8a39630a08. Report an issue: GitHub.