Панди read_csv() у Python з прикладом
⚡ Розумний підсумок
Pandas read_csv() перетворює файл, розділений комами, локальний або віддалений, на DataFrame за один виклик. Цей покроковий посібник імпортує набір даних перепису дорослого населення UCI, іменує його п'ятнадцять стовпців та підсумовує результат за допомогою агрегацій groupby.
Імпорт CSV у Pandas
Під час навчання з TensorFlow ви використовуватимете набір даних для дорослих, який часто використовується для завдань класифікації. Файл, що використовується нижче, є необробленим adult.data експорт з репозиторію машинного навчання UCI, а на сторінці набору даних також пропонується завантаження зip-архіву та ucimlrepo пакет, якщо прямий шлях коли-небудь перестане розв'язуватися.
Дані зберігаються у форматі CSV. Набір даних містить 8 категоріальних змінних:
- робочий клас
- освіту
- подружній
- окупація
- відносини
- гонки
- секс
- Батьківщина
І 6 неперервних змінних:
- вік
- fnlwgt
- номер_освіти
- приріст капіталу
- капітал_збиток
- години_тиждень
Разом із доходом label стовпець, що створює 15 імен стовпців, яким ви передасте Панди у наступному розділі.
Метод Pandas read_csv().
Щоб імпортувати набір даних CSV, можна скористатися об'єктом pd.read_csv(). Базова сигнатура:
Синтаксис Pandas read_csv().
pandas.read_csv(filepath_or_buffer, sep=',', names=None, index_col=None, skipinitialspace=False)
- filepath_or_bufferшлях, URL, або файлоподібний об'єкт, що містить дані
- sep=','роздільник, який потрібно використовувати
- імена=Жоден: назвіть стовпці. Якщо набір даних має десять стовпців, вам потрібно передати десять назв
- index_col=Немає: який стовпець використовувати як індекс рядка. Передайте значення False, щоб примусово встановити новий цілочисельний індекс
- skipinitialspace=Хибністьпропускати пробіли після роздільника
Повний список аргументів дивіться на офіційному сайті Документація pandas.read_csv().
Pandas read_csv() Приклад
У наведеному нижче фрагменті наведено імена всіх 15 стовпців, вказано на файл UCI та видалено пробіл після кожної коми в цьому конкретному наборі даних.
## Import csv import pandas as pd ## Define path data COLUMNS = ['age','workclass', 'fnlwgt', 'education', 'education_num', 'marital', 'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss', 'hours_week', 'native_country', 'label'] PATH = "https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data" df_train = pd.read_csv(PATH, skipinitialspace=True, names = COLUMNS, index_col=False) df_train.shape
вихід:
(32561, 15)
Фігура підтверджує 32 561 рядок і 15 стовпців, тому кожне ім'я в COLUMNS зіставляється з полем у файлі.
Ключові параметри Pandas read_csv()
read_csv() приймає понад п'ятдесят аргументів, але невелика група охоплює майже кожен реальний імпорт. Значення за замовчуванням, наведені нижче, задокументовані в поточному довіднику API pandas.
| Параметр | дефолт | Що вона робить |
| Вересень | ',' | Символ або регулярний вираз, що використовується як роздільник. Використовуйте sep=';' або sep='\t' для інших форматів. |
| заголовок | 'виводити' | Номер рядка, що містить підписи стовпців. Передайте header=None, якщо файл не має рядка заголовка. |
| Імена | не встановлено | Явний список підписів стовпців. Поєднайте з header=0, щоб замінити існуючий заголовок. |
| index_col | ніхто | Стовпець, який використовуватиметься як індекс рядка. index_col=False примусово використовує простий цілочисельний індекс. |
| usecols | ніхто | Підмножина стовпців для завантаження, за міткою або позицією. Зменшує час розбору та обсяг пам'яті. |
| dtype | ніхто | Типи даних для кожного стовпця, наприклад {'age': 'int32'}. Пропускає виведення типів. |
| na_values | ніхто | Додаткові рядки для читання як NaN, такі як заповнювач '?' у наборі даних для дорослих. |
| пропускні ряди / ряди | ніхто | Пропустити початкові рядки або прочитати лише перші N рядків даних. |
| дати_розбору | ніхто | Стовпці для перетворення на дату та час під час читання, у парі з date_format. |
| кодування | 'utf-8' | Кодування тексту файлу. Використовуйте «latin-1» або «cp1252» для експорту застарілих форматів. |
| розмір фрагмента | ніхто | Повертає ітератор, який видає файл у блоках з N рядків. |
| на поганих лініях | помилка | Що робити з деформованими рядками: підвищувати, попереджати або пропускати їх. |
Два з них заслуговують на окрему увагу. index_col=False це не те саме, що залишити його невстановленим: це явно вказує Pandas не просувати перший стовпець, що саме те, що потрібно, коли файл закінчує кожен рядок випадковим роздільником. І names тихо перезаписує все, що оголошує файл, тому передайте header=0 поруч із ним, коли CSV-файл справді містить рядок заголовка.
Метод Pandas groupby().
Простий спосіб переглянути дані – це використовувати метод groupby. Цей метод може допомогти вам узагальнити дані за групами. Нижче наведено список агрегацій, доступних за допомогою методу groupby():
- рахувати: рахувати
- хв.: хв
- макс.: макс
- середній: середній
- медіана: медіана
- стандартне відхилення: стд
- та інші
Усередині groupby() ви називаєте стовпець, за яким потрібно згрупувати дані, перш ніж застосовувати агрегацію.
Давайте розглянемо одну групуping з набором даних для дорослих. Ви отримаєте середнє значення всіх безперервних змінних за типом доходу, тобто вище 50 тисяч або нижче 50 тисяч:
df_train.groupby(['label']).mean()
| етикетка | вік | fnlwgt | номер_освіти | приріст капіталу | капітал_збиток | години_тиждень |
| <= 50 тис | 36.783738 | 190340.86517 | 9.595065 | 148.752468 | 53.142921 | 38.840210 |
| >50 тис | 44.249841 | 188005.00000 | 11.611657 | 4006.142456 | 195.001530 | 45.473026 |
Ви можете дізнатися мінімальний вік за типом домогосподарства:
df_train.groupby(['label'])['age'].min() label <=50K 17 >50K 19 Name: age, dtype: int64
Ви також можете групувати за кількома стовпцями. Наприклад, ви можете отримати максимальний приріст капіталу відповідно до типу домогосподарства та сімейного стану.
df_train.groupby(['label', 'marital'])['capital_gain'].max() label marital <=50K Divorced 34095 Married-AF-spouse 2653 Married-civ-spouse 41310 Married-spouse-absent 6849 Never-married 34095 Separated 7443 Widowed 6849 >50K Divorced 99999 Married-AF-spouse 7298 Married-civ-spouse 99999 Married-spouse-absent 99999 Never-married 99999 Separated 99999 Widowed 99999 Name: capital_gain, dtype: int64
Ви можете створити графік після групування. Один зі способів зробити це – безпосередньо побудувати графік згрупованого результату.
Щоб створити чіткіший графік, застосуйте unstack() після mean(), щоб сімейний стан перемістився з індексу в стовпці. Тоді діаграма матиме дві групи, по одній на кожну мітку доходу, замість чотирнадцяти (2*7) стовпців, які створив би плоский багаторівневий індекс.
Якщо ви використовуєте a Jupyter ноутбук, не забудьте додати %matplotlib в код, інакше графік не відображатиметься.
%matplotlib inline df_plot = df_train.groupby(['label', 'marital'])['capital_gain'].mean().unstack() df_plot
Побудова цього нерозкладеного кадру у вигляді стовпчастої діаграми дає малюнок нижче.
Як читати великі CSV-файли за допомогою Pandas
Набір даних для дорослих невеликий, але той самий виклик може зависнути під час експорту обсягом у кілька гігабайт. Три аргументи виконують більшу частину роботи.
- usecols завантажує лише ті стовпці, які вам дійсно потрібні. У документації pandas зазначається, що це призводить до набагато швидшого розбору та зменшення використання пам'яті.
- dtype прив'язує кожен стовпець до типу, тому Pandas пропускає висновок і не розширює цілі числа до 64-біт за замовчуванням.
- розмір фрагмента повертає TextFileReader замість DataFrame, що дозволяє вам перебирати блоки з N рядків та агрегувати їх по ходу роботи.
import pandas as pd # read only the columns you need, with explicit types cols = ['age', 'education', 'capital_gain', 'label'] types = {'age': 'int32', 'capital_gain': 'int32'} df = pd.read_csv(PATH, names=COLUMNS, usecols=cols, dtype=types, skipinitialspace=True, index_col=False) # stream the file in fixed-size chunks instead of loading it whole total = 0 for chunk in pd.read_csv(PATH, names=COLUMNS, chunksize=10000, skipinitialspace=True, index_col=False): total = total + len(chunk) print(total)
Після того, як основи будуть налаштовані, допоможуть ще два варіанти. engine='pyarrow' перемикається на багатопотоковий парсер Arrow, та dtype_backend='pyarrow' зберігає результат у стовпцях, розділених стрілками. low_memory За замовчуванням значення True, що дозволяє внутрішньо розбирати файл по частинах, але може створювати змішані типи у стовпці; встановіть явний тип даних, а не покладайтеся на нього.
Нарешті, compression='infer' означає, що шлях, що закінчується на .gz, .zip, .bz2, .xz або .zst, розпаковується на льоту, тому немає потреби розпаковувати архів перед його читанням.
Поширені помилки read_csv() у Pandas та як їх виправити
Більшість збоїв read_csv() виникають з чотирьох причин, і кожна з них має задокументований аргумент, який її вирішує.
| помилка | Викликати | виправляти |
| FileNotFoundError | Шлях вказується відносно робочого каталогу, а не до скрипта. | Використайте абсолютний шлях або підтвердіть URL Схема може бути однією з http, ftp, s3, gs або file. |
| Помилка декодування Юнікоду | Файл не має кодування UTF-8, яке є кодуванням за замовчуванням. | Передайте encoding='latin-1′ або правильний кодек, або encoding_errors='replace'. |
| ParserError: Помилка токенізації даних | Рядок містить більше полів, ніж зазначено в заголовку. | Передайте on_bad_lines='skip' або 'warn', або встановіть правильний розділ. |
| DtypeWarning: стовпці мають змішані типи | Виведення фрагментованих типів бачило різні типи в одному стовпці. | Встановіть явний тип даних або low_memory=False. |
| Стовпці зміщені на один | Кінцевий роздільник змушує Pandas просувати перше поле до індексу. | Передайте index_col=False. |
Набір даних для дорослих безпосередньо показує випадок відсутнього значення: невідомі записи workclass, occupation та native_country зберігаються як буквальний знак питання, тому вони надходять як рядок '?', якщо ви їх не оголосите.
# tolerate rows with too many fields instead of raising df = pd.read_csv(PATH, names=COLUMNS, on_bad_lines='skip') # read a file that is not UTF-8 df = pd.read_csv('sales.csv', encoding='latin-1') # treat the dataset's '?' placeholder as a missing value df = pd.read_csv(PATH, names=COLUMNS, na_values='?', skipinitialspace=True)

