from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler

import pandas as pd
import numpy as np


class PCAFeatureReducer:
    """Reduces the dimensionality of a dataset using their principal components."""

    def __init__(self, data: pd.DataFrame, n_components: int = 2):
        self.data = data
        self.n_components = n_components
        self.pca = PCA(n_components=self.n_components)

    def preprocess_data(self, variance_threshold: float = 0.01):
        variances = np.var(self.data, axis=0)
        features_to_keep = variances > variance_threshold
        return self.data.loc[:, features_to_keep]

    def apply_pca(self):
        data_filtered = self.preprocess_data()
        scaler = StandardScaler()
        data_scaled = scaler.fit_transform(data_filtered)
        principal_components = self.pca.fit_transform(data_scaled)
        return principal_components