Untitled
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