Skip to content

Instantly share code, notes, and snippets.

@Ruthenus
Last active February 18, 2025 07:15
Show Gist options
  • Save Ruthenus/94e11461558466a374f8f63e655b3fb5 to your computer and use it in GitHub Desktop.
Save Ruthenus/94e11461558466a374f8f63e655b3fb5 to your computer and use it in GitHub Desktop.
Week 9 Homework in IT STEP Academy (file tasks)
import pandas
import json
import math
def load_and_display_csv(filepath):
"""
Пробує завантажити файл 28,5 ГБ зі значеннями, розділеними комами (csv),
за вказаним шляхом filepath. Виводить індекси та назви колонок.
Перехоплює перші можливі помилки. Допоміжна функція для визначення
напрямку подальшого програмування та задля випробування ЕОМ.
"""
try:
# Нібито перший рядок містить назви колонок!
# https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html
df = pandas.read_csv(filepath, encoding='utf-8', nrows=1_000_000)
# Виводимо індекси та назви колонок:
# https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.columns.html
for index, column_header in enumerate(df.columns):
print(index, column_header)
except FileNotFoundError:
print(f"ERROR: файл CSV за вказаним шляхом відсутній.")
except pandas.errors.ParserError:
# https://pandas.pydata.org/docs/reference/api/pandas.errors.ParserError.html
print(f"ERROR: не вдалося обробити файл. Перевірте його формат!")
except pandas.errors.EmptyDataError:
# https://pandas.pydata.org/docs/reference/api/pandas.errors.EmptyDataError.html
print(f"ERROR: зустрічаються порожні дані або заголовок.")
except Exception as e:
# Загальна обробка інших НЕПЕРЕДБАЧЕНИХ помилок
print(f"Сталася непередбачувана помилка: {e}")
# РЕЗУЛЬТАТ ТЕСТУВАННЯ ФУНКЦІЇ load_and_display_csv(filepath)
"""
0 Captured Time
1 Latitude
2 Longitude
3 Value
4 Unit
5 Location Name
6 Device ID
7 MD5Sum
8 Height
9 Surface
10 Radiation
11 Uploaded Time
12 Loader ID
"""
# Встановлюємо тип даних для стовпців, де виявлено змішані типи:
dtype = {
5: str,
9: str,
10: str,
}
try:
# Друга спроба завантажити файл ПОВНІСТЮ
df = pandas.read_csv(filepath, encoding='utf-8', dtype=dtype,
low_memory=False)
print("Файл завантажено з обробленими типами даних.")
except Exception as e: # спіймав без nrows=1_000_000
print(f"FATAL ERROR: не вдалося завантажити файл: {e}")
# Визначення справжньої кількості рядків у DataFrame
print(f"Загальна кількість рядків: {len(df)}") # 244 мільйони!
def process_coordinates(filepath, chunk_size=1_000_000):
"""
Функція для обробки великого CSV файлу замірів радіаційного фону
та отримання унікальних координат з точністю до 1 знака після коми.
Помилки перехопила попередня функція load_and_display_csv(filepath)
:param filepath: шлях до CSV файлу
:param chunk_size: розмір частини, яку обробляємо за раз
:return: список координат у вигляді кортежів (широта, довгота)
"""
# Встановлюємо тип даних для стовпців, де виявлено змішані типи:
dtype = {
5: str,
9: str,
10: str,
} # Такі добрі інструкції в pandas!
# Застосуємо множину Set для автоматичного видалення дублікатів
coord_tuples = set()
try: # https://pandas.pydata.org/docs/user_guide/scale.html
for chunk in pandas.read_csv(filepath, header=0, chunksize=chunk_size,
dtype=dtype, low_memory=False):
# https://stackoverflow.com/questions/24251219/pandas-read-csv-low-memory-and-dtype-options
# Округлюємо координати до одного знака після коми:
chunk['Latitude'] = chunk['Latitude'].round(1)
chunk['Longitude'] = chunk['Longitude'].round(1)
# Не округлюючи отримуємо 5,9 ГБ!
# Множина кортежів (широта, довгота) для поточного шматка:
unique_chunk = set(zip(chunk['Latitude'], chunk['Longitude']))
# https://docs.python.org/3.3/library/functions.html#zip
# Додаємо нові унікальні пари координат до загальної множини
coord_tuples.update(unique_chunk) # 858250 рядків, 9,14 МБ
# Повертаємо список списків з множини кортежів:
return list(coord_tuples)
except Exception as e:
print(f"Знову (НЕ) сталася помилка з цим завеликим файлом: {e}")
def save_to_json(data, output_file):
"""
Функція для збереження даних обробленого CSV файлу в JSON файл.
:param data: дані, які потрібно зберегти
:param output_file: шлях до файлу для збереження
"""
try:
with open(output_file, 'w', encoding='utf-8') as f:
json.dump(data, f, indent=4)
except IOError:
print(f"ERROR: не вдалося відкрити файл '{output_file}' для запису.")
except Exception as e:
print(f"Помилка під час збереження даних у файл: {e}")
def remove_nan_from_json(input_file, output_file):
"""
Помітив, що JSON файл містить нечислові значення. Функція для
очищення JSON файлу від елементів, які містять NaN значення.
:param input_file: шлях до вхідного JSON файлу
:param output_file: шлях до вихідного очищеного JSON файлу
"""
try:
with open(input_file, 'r', encoding='utf-8') as f:
data = json.load(f)
# Функція для перевірки, чи є в списку "Not a number"
def is_valid_coordinates(coord):
return all(not math.isnan(x) for x in coord)
# Фільтруємо дані: залишаємо тільки валідні координати
filtered_data = [coord for coord in data if
is_valid_coordinates(coord)]
# Зберігаємо очищені дані в новий файл
with open(output_file, 'w', encoding='utf-8') as f:
json.dump(filtered_data, f, indent=4)
print(f"Дані успішно очищено та збережено у файл '{output_file}'.")
except FileNotFoundError:
print(f"ERROR: файл JSON за вказаним шляхом відсутній.")
except json.JSONDecodeError:
print(f"ERROR: не вдалося прочитати JSON файл '{input_file}'.")
except Exception as e:
print(f"Сталася непередбачувана помилка: {e}")
# Спільний виклик функцій
filepath = "D:/PYTHON/@radiazioni_ionizzanti_bot/data/measurements-out.csv"
output_file = "D:/PYTHON/@radiazioni_ionizzanti_bot/data/coordinates.json"
if __name__ == '__main__':
# load_and_display_csv(filepath)
unique_coords = process_coordinates(filepath)
save_to_json(unique_coords, output_file)
remove_nan_from_json(output_file, output_file)
print(f"Результат дивіться у файлі: {output_file}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment