from itertools import combinations
import pandas as pd
import numpy as np


class InteractionFeature:

    @staticmethod
    def general_interaction(X: pd.DataFrame, degree: int = 2) -> pd.DataFrame:

        X_values = X.values
        n_samples, n_features = X_values.shape

        cols_combinations = np.array(list(combinations(range(n_features), degree)))
        n_combinations = cols_combinations.shape[0]

        selected = X_values[:, cols_combinations]  # shape: (n_samples, n_combinations, degree)

        feature_array = np.prod(selected, axis=2)  # shape: (n_samples, n_combinations)

        feature_names = ["__inter__".join(X.columns[list(cols)]) for cols in cols_combinations]

        return pd.DataFrame(feature_array, columns=feature_names, index=X.index)