Untitled

 avatar
unknown
plain_text
5 months ago
6.7 kB
2
Indexable
import pandas as pd

def process_csv(file_path, output_path):
    # Wczytanie pliku CSV z odpowiednim kodowaniem i ignorowaniem błędnych linii
    df = pd.read_csv(file_path, encoding='ISO-8859-1', on_bad_lines='skip', delimiter=';')

    # Wyświetlenie dostępnych kolumn
    print("Available columns:", df.columns)

    # Sprawdzenie czy kolumna "Data" istnieje
    if 'Data' in df.columns:
        # Zmiana formatu daty w kolumnie "Data"
        df['Data'] = pd.to_datetime(df['Data'], format='%d-%m-%Y, %H:%M:%S').dt.date
    else:
        print("Kolumna 'Data' nie istnieje w pliku CSV.")
        return

    # Sprawdzanie czy wymagane kolumny istnieją
    required_columns = ['zamowienie', 'status', 'Nazwa paczki', 'Data']
    for col in required_columns:
        if col not in df.columns:
            print(f"Kolumna '{col}' nie istnieje w pliku CSV.")
            return

    # Funkcja do filtrowania i podziału na różne kolumny na podstawie nazwy paczki
    def filter_and_split_strefa_klienta(df):
        df_filtered = df[
            (df['zamowienie'] == 'strefa klienta') & 
            (df['status'] == 'zbilingowany')
        ].copy()  # użycie .copy() aby uniknąć problemów z SettingWithCopyWarning
        
        if df_filtered.empty:
            print("Brak danych po filtracji dla 'strefa klienta'.")
            return None

        # Dodanie kolumn zliczających wystąpienia według słów kluczowych
        df_filtered.loc[:, 'INT'] = df_filtered['Nazwa paczki'].apply(lambda x: 1 if 'K INT' in x else 0)
        df_filtered.loc[:, 'MVNO'] = df_filtered['Nazwa paczki'].apply(lambda x: 1 if 'MVNO' in x else 0)
        df_filtered.loc[:, 'DATA'] = df_filtered['Nazwa paczki'].apply(lambda x: 1 if 'K Int Mobi' in x else 0)
        df_filtered.loc[:, 'K Vectra TV Smart'] = df_filtered['Nazwa paczki'].apply(lambda x: 1 if 'K Vectra TV Smart' in x else 0)

        # Grupowanie według daty i zliczanie wyników dla każdej kategorii
        grouped = df_filtered.groupby('Data').agg({
            'INT': 'sum',
            'MVNO': 'sum',
            'DATA': 'sum',
            'K Vectra TV Smart': 'sum'
        }).reset_index()

        # Zliczanie pozostałych paczek, które nie pasują do powyższych kategorii
        other_products = df_filtered[~df_filtered['Nazwa paczki'].str.contains('INT|MVNO|DATA|K Vectra TV Smart', regex=True)]
        other_grouped = other_products.groupby(['Data', 'Nazwa paczki']).size().reset_index(name='Liczba powtórzeń')

        # Dodanie sumy powtórzeń dla każdego dnia
        total_by_day = other_grouped.groupby('Data')['Liczba powtórzeń'].sum().reset_index(name='Suma powtórzeń')

        # Scalanie z 'other_grouped' poprzez dodanie wiersza sumy poniżej każdej grupy daty
        other_grouped_with_total = pd.concat([
            other_grouped,
            total_by_day.assign(Nazwa_paczki='Suma powtórzeń')  # Dodanie wiersza z sumą
        ]).sort_values(by=['Data', 'Nazwa paczki'], key=lambda col: col.apply(lambda x: 'ZZZ' if x == 'Suma powtórzeń' else x))

        return grouped, other_grouped_with_total

    # Funkcja pomocnicza do filtrowania i dodawania sumy powtórzeń na koniec dnia
    def filter_and_count_with_total(df, filter_value, sheet_name):
        df_filtered = df[
            (df['zamowienie'] == filter_value) & 
            (df['status'] == 'zbilingowany')
        ]
        if df_filtered.empty:
            print(f"Brak danych po filtracji dla {filter_value}.")
            return None
        
        # Grupowanie danych według daty i nazwy paczki oraz zliczanie wystąpień
        grouped = df_filtered.groupby(['Data', 'Nazwa paczki']).size().reset_index(name='Liczba powtórzeń')

        # Dodanie sumy powtórzeń dla każdego dnia
        total_by_day = grouped.groupby('Data')['Liczba powtórzeń'].sum().reset_index(name='Suma powtórzeń')

        # Scalanie z 'grouped' poprzez dodanie wiersza sumy poniżej każdej grupy daty
        grouped_with_total = pd.concat([
            grouped,
            total_by_day.assign(Nazwa_paczki='Suma powtórzeń')  # Dodanie wiersza z sumą
        ]).sort_values(by=['Data', 'Nazwa paczki'], key=lambda col: col.apply(lambda x: 'ZZZ' if x == 'Suma powtórzeń' else x))

        return grouped_with_total

    # Nowa funkcja do zliczania elementów w kolumnie "okres" dla danej grupy
    def count_elements_in_okres_for_group(df_filtered, sheet_name):
        if 'okres' in df_filtered.columns:
            okres_grouped = df_filtered.groupby('okres').size().reset_index(name='Liczba powtórzeń')
            return okres_grouped
        else:
            print(f"Kolumna 'okres' nie istnieje w danych dla zakładki {sheet_name}.")
            return None

    # Lista filtrów i odpowiednich nazw arkuszy (oprócz "Strefa Klienta")
    filters = [
        ('tvo', 'TVO'),
        ('ott', 'OTT'),
        ('stb', 'STB')
    ]

    # Tworzenie pliku Excel z wieloma arkuszami
    with pd.ExcelWriter(output_path, engine='openpyxl') as writer:
        # Zapisanie wyników dla "Strefa Klienta"
        strefa_klienta_grouped, strefa_klienta_other = filter_and_split_strefa_klienta(df)
        if strefa_klienta_grouped is not None:
            # Zapisanie tabeli z INT, MVNO, DATA, K Vectra TV Smart
            strefa_klienta_grouped.to_excel(writer, sheet_name='Strefa Klienta', index=False, startrow=0)
            # Zapisanie tabeli z pozostałymi nazwami paczek poniżej
            strefa_klienta_other.to_excel(writer, sheet_name='Strefa Klienta', index=False, startrow=len(strefa_klienta_grouped) + 2)
            
            # Zliczenie kolumny "okres" dla "Strefa Klienta"
            okres_strefa_klienta = count_elements_in_okres_for_group(df[df['zamowienie'] == 'strefa klienta'], 'Strefa Klienta')
            if okres_strefa_klienta is not None:
                okres_strefa_klienta.to_excel(writer, sheet_name='Strefa Klienta Okres', index=False)

        # Zapisanie wyników dla innych filtrów (TVO, OTT, STB) i zliczenie kolumny "okres"
        for filter_value, sheet_name in filters:
            result = filter_and_count_with_total(df, filter_value, sheet_name)
            if result is not None:
                result.to_excel(writer, sheet_name=sheet_name, index=False)
                
                # Zliczenie kolumny "okres" dla danej zakładki
                okres_grouped = count_elements_in_okres_for_group(df[df['zamowienie'] == filter_value], sheet_name)
                if okres_grouped is not None:
                    okres_grouped.to_excel(writer, sheet_name=f'{sheet_name} Okres', index=False)

# Przykład użycia
process_csv('input.csv', 'output.xlsx')
Editor is loading...
Leave a Comment