Панди read_csv() у Python з прикладом

⚡ Розумний підсумок

Pandas read_csv() перетворює файл, розділений комами, локальний або віддалений, на DataFrame за один виклик. Цей покроковий посібник імпортує набір даних перепису дорослого населення UCI, іменує його п'ятнадцять стовпців та підсумовує результат за допомогою агрегацій groupby.

  • 🔘 Один дзвінок: pd.read_csv() приймає шлях до файлу, a URLабо будь-який об'єкт, що надає доступ до методу читання.
  • ☑️ Керування колонкою: Передайте імена для позначення стовпців та index_col=False, щоб зберегти простий цілочисельний індекс.
  • Пробіли: skipinitialspace=True видаляє пробіли після кожної коми в наборі даних для дорослих.
  • 🧪 Група та агрегація: groupby() підсумовує кадр за допомогою count, min, max, mean, median або std.
  • 🛠️ Великі файли: usecols, dtype та chunksize скорочують час розбору та пам'ять для експорту обсягом у кілька гігабайт.
  • ⚠️ Поширені помилки: Кодування, некоректні рядки та змішані типи даних мають задокументований аргумент, який їх виправляє.

Pandas read_csv() із прикладом

Імпорт 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)

Поширені запитання

Обидва викликають один і той самий парсер. read_csv() за замовчуванням використовує роздільник у вигляді ком, тоді як read_table() зчитує загальний файл з роздільниками та очікує, що ви самі встановите роздільник. Використовуйте read_csv() для файлів з роздільниками у вигляді ком, а read_table() для експорту, розділеного табуляцією або вертикальною рискою.

Виклик df.to_csv('output.csv', index=False). Видалитиping Індекс уникає неназваного першого стовпця під час наступного читання. Додайте аргументи sep, encoding або compression, щоб відобразити будь-які налаштування, які ви використовували під час імпорту файлу.

Передавайте parse_dates з іменами або позиціями стовпців та додавайте date_format, якщо макет не відповідає ISO 8601, наприклад date_format='%d/%m/%Y'. Без нього стовпці дати надходять як звичайні рядки об'єктів і потребують окремого виклику to_datetime.

Встановіть sep на символ, наприклад, sep=';' або sep='\t'. Роздільники, довші за один символ, обробляються як регулярні вирази та примусово повільніше Python engine.sep=None дозволяє цьому движку перехоплювати роздільник з першого дійсного рядка.

Використовуйте nrows для обмеження кількості повернутих рядків даних, а skiprows для переходу за блок початкових рядків. Їх поєднання переглядає файл по сторінках, наприклад, skiprows=1000000 з nrows=999999 для зчитування другого мільйона рядків.

Так. Стиснення за замовчуванням використовує функцію «infer», тому шлях, що закінчується на .gz, .zip, .bz2, .xz або .zst, розпаковується автоматично. URLВикористання http, ftp, s3, gs або file працює, а storage_options передає облікові дані до віддаленого сервера.

Навчені моделі позначають ймовірні помилки типу, кластеризують майже дублікати написання категорій та імпутують відсутні значення з навколишніх стовпців. Це звужує ручне очищення до рядків, які на основі правил параметр na_values ​​або dtype не може самостійно розв'язати.

Copilot швидко створює чернетку шаблону, як тільки бачить зразок файлу. Розглядайте список аргументів як чернетку, оскільки він часто вгадує тип даних та кодування. Перевірте кожне згенероване ключове слово за посиланням API pandas перед його запуском.

Підсумуйте цей пост за допомогою: