<jupyter_start><jupyter_text>Summary- there are no benefits in using numba- use `lagmat_2` as it supports row-oriented time series  Load packages<jupyter_code>import numpy as np
import numba
import csv<jupyter_output><empty_output><jupyter_text>Load Data<jupyter_code>x1 = list(csv.reader(open('data1.csv', 'r')))
x1 = np.array(x1, dtype=float)

x2 = list(csv.reader(open('data2.csv', 'r')))
x2 = np.array(x2, dtype=float)<jupyter_output><empty_output><jupyter_text>lagmat prototypes<jupyter_code>def lagmat_1(A: np.array, lags: list, order: str = 'F') -> np.array:
    # detect negative lags
    if min(lags) < 0:
        raise Exception((
            "Negative lags are not allowed. Only provided integers "
            "greater equal 0 as list/tuple elements"))

    # correct dimensions
    if len(A.shape) == 1:
        A = A.reshape(-1, 1)

    # number of colums and lags
    n_rows, n_cols = A.shape
    n_lags = len(lags)

    # allocate memory
    B = np.empty(
        shape=(n_rows, n_cols * n_lags),
        order=order,
        dtype=A.dtype)
    B[:] = np.nan

    # Copy lagged columns of A into B
    for i, l in enumerate(lags):
        # target columns of B
        j = i * n_cols
        k = j + n_cols  # (i+1) * ncols
        # number rows of A
        nl = n_rows - l
        # Copy
        B[l:, j:k] = A[:nl, :]

    return B
def lagmat_2(A: np.array, lags: list, orient: str = 'col') -> np.array:
    # detect negative lags
    if min(lags) < 0:
        raise Exception((
            "Negative lags are not allowed. Only provided integers "
            "greater equal 0 as list/tuple elements"))
    
    if orient in ('row', 'rows'):
        if len(A.shape) == 1:
            A = A.reshape(1, -1)
        A = np.array(A, order='C')
        return lagmat_rows_2(A, lags)
    
    elif orient in ('col', 'columns'):
        if len(A.shape) == 1:
            A = A.reshape(-1, 1)
        A = np.array(A, order='F')
        return lagmat_cols_2(A, lags)
    else:
        return None


def lagmat_rows_2(A: np.array, lags: list):
    # number of colums and lags
    n_rows, n_cols = A.shape
    n_lags = len(lags)
    # allocate memory
    B = np.empty(shape=(n_rows * n_lags, n_cols), order='C', dtype=A.dtype)
    B[:] = np.nan
    # Copy lagged columns of A into B
    for i, l in enumerate(lags):
        # target rows of B
        j = i * n_rows
        k = j + n_rows  # (i+1) * n_rows
        # number cols of A
        nc = n_cols - l
        # Copy
        B[j:k, l:] = A[:, :nc]
    return B


def lagmat_cols_2(A: np.array, lags: list):
    # number of colums and lags
    n_rows, n_cols = A.shape
    n_lags = len(lags)
    # allocate memory
    B = np.empty(shape=(n_rows, n_cols * n_lags), order='F', dtype=A.dtype)
    B[:] = np.nan
    # Copy lagged columns of A into B
    for i, l in enumerate(lags):
        # target columns of B
        j = i * n_cols
        k = j + n_cols  # (i+1) * ncols
        # number rows of A
        nl = n_rows - l
        # Copy
        B[l:, j:k] = A[:nl, :]
    return B
def lagmat_3(A: np.array, lags: np.array, orient: str = 'col') -> np.array:
    # detect negative lags
    if np.min(lags) < 0:
        raise Exception((
            "Negative lags are not allowed. Only provided integers "
            "greater equal 0 as list/tuple elements"))
    # enforce numpy
    #lags = np.array(lags)
    # enforce float dtype
    
    if orient in ('row', 'rows', 'C'):
        if len(A.shape) == 1:
            A = A.reshape(1, -1)
        #A = np.array(A, order='C')
        return lagmat_rows_3(A, lags)
    
    elif orient in ('col', 'columns', 'F'):
        if len(A.shape) == 1:
            A = A.reshape(1, -1)
        else:
            A = A.T            
        #A = np.array(A, order='C')
        return lagmat_rows_3(A, lags).T
    else:
        return None


@numba.jit(nopython=True, parallel=True)
def lagmat_rows_3(A: np.array, lags: np.array):
    # number of colums and lags
    n_rows, n_cols = A.shape
    n_lags = lags.shape[0]
    # allocate memory
    B = np.empty(shape=(n_rows * n_lags, n_cols), dtype=A.dtype)
    B[:] = np.nan
    # Copy lagged columns of A into B
    for i, l in enumerate(lags):
        # target rows of B
        j = i * n_rows
        k = j + n_rows  # (i+1) * n_rows
        # number cols of A
        nc = n_cols - l
        # Copy
        B[j:k, l:] = A[:, :nc]
    return B<jupyter_output><empty_output><jupyter_text>Pre-Run<jupyter_code>lags = range(100)
lags2 = np.array(lags)
x1T = x1.T

print("column-oriented time series:")
%time _ = lagmat_1(x1, lags, order='F')
%time _ = lagmat_1(x1, lags, order='C')
%time _ = lagmat_2(x1, lags, orient='col')
%time _ = lagmat_3(x1, lags2, orient='col')

print("row-oriented time series:")
%time _ = lagmat_2(x1T, lags, orient='row')
%time _ = lagmat_3(x1T, lags2, orient='row')<jupyter_output>column-oriented time series:
CPU times: user 374 ms, sys: 249 ms, total: 622 ms
Wall time: 627 ms
CPU times: user 1.39 s, sys: 327 ms, total: 1.71 s
Wall time: 1.96 s
CPU times: user 369 ms, sys: 315 ms, total: 684 ms
Wall time: 684 ms
CPU times: user 1.8 s, sys: 358 ms, total: 2.15 s
Wall time: 1.96 s
row-oriented time series:
CPU times: user 378 ms, sys: 324 ms, total: 701 ms
Wall time: 705 ms
CPU times: user 555 ms, sys: 320 ms, total: 875 ms
Wall time: 653 ms<jupyter_text>Speed Test<jupyter_code>lags = range(100)
lags2 = np.array(lags)
x1T = x1.T

print("column-oriented time series:")
%timeit _ = lagmat_1(x1, lags, order='F')
%timeit _ = lagmat_1(x1, lags, order='C')
%timeit _ = lagmat_2(x1, lags, orient='col')
%timeit _ = lagmat_3(x1, lags2, orient='col')

print("\nrow-oriented time series:")
%timeit _ = lagmat_2(x1T, lags, orient='row')
%timeit _ = lagmat_3(x1T, lags2, orient='row')
lags = range(100)
lags2 = np.array(lags)
x2T = x2.T

print("column-oriented time series:")
%timeit _ = lagmat_1(x2, lags, order='F')
%timeit _ = lagmat_1(x2, lags, order='C')
%timeit _ = lagmat_2(x2, lags, orient='col')
%timeit _ = lagmat_3(x2, lags2, orient='col')

print("\nrow-oriented time series:")
%timeit _ = lagmat_2(x2T, lags, orient='row')
%timeit _ = lagmat_3(x2T, lags2, orient='row')<jupyter_output>column-oriented time series:
592 ms ± 5.56 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
548 ms ± 27.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
576 ms ± 5.05 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
546 ms ± 4.09 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

row-oriented time series:
573 ms ± 3.47 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
567 ms ± 47.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
{'fraction_non_alphanumeric': 0.13848704038577456, 'fraction_numerical': 0.03375527426160337, 'mean_word_length': 2.5644468313641244, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '423028', 'license': 'Apache-2.0', 'n_tokens_mistral': 2688, 'n_tokens_neox': 2548, 'n_words': 780, 'path': 'examples/lagmat - Benchmark implementations.ipynb', 'repo_name': 'kmedian/lagmat', 'size': '6636'}