Меню Закрити

Python Pandas: 10 прийомів, які підвищать ефективність вашої роботи

Pandas — пакет Python, який широко використовується для структурованих даних. Для нього існує багато хороших посібників, але не всі знають цікаві прийоми, які ми розглянемо у статті.

read_csv

Кожен знає цю команду. Але якщо ви намагаєтеся прочитати великі дані, то спробуйте додати цей аргумент: nrows = 5, щоб прочитати спочатку невелику частину таблиці, перш ніж  завантажувати її всю. Тоді ви можете уникнути помилки, вибравши неправильний роздільник.

(Також ви можете скористатися командою head у linux, щоб перевірити перші 5 рядків, наприклад, у будь-якому текстовому файлі: head -c 5 data.txt)

Після цього можна отримати список стовпців за допомогою df.columns.tolist() — для отримання всіх стовпців, а потім додати аргумент usecols = [‘c1’, ‘c2’,…] для завантаження потрібних стовпців. Крім того, якщо ви знаєте типи даних кількох конкретних стовпців, ви можете додати аргумент dtype = {'c1': str, 'c2': int,…}, щоб він завантажувався швидше. Ще однією перевагою цього аргументу є те, що, коли у вас є стовпець, який містить і рядки, і числа, то зручно оголосити його тип рядком. Тож ви не наробите помилок, намагаючись об’єднати таблиці, використовуючи цей стовпець як ключ.

select_dtypes

Якщо в Python треба виконати попередню обробку даних, то ця команда допоможе вам зекономити час. Після читання в таблиці типи даних за замовчуванням для кожного стовпця можуть бути bool, int64, float64, object, category, timedelta64 або datetime64. Спочатку можна перевірити всі доступні типи даних за допомогою команди

df.dtypes.value_counts()

а потім виконати

df.select_dtypes(include=[‘float64’, ‘int64’])

для вибору числових типів даних.

copy

Це важлива команда, навіть якщо ви про неї ще не чули. Якщо ви виконуєте такі команди:

import pandas as pd
df1 = pd.DataFrame({ ‘a’:[0,0,0], ‘b’: [1,1,1]})
df2 = df1
df2[‘a’] = df2[‘a’] + 1
df1.head()

Ви побачите, що значення df1 змінилося. Це відбувається тому, що df2 = df1 означає не копіювання df1 і призначення її df2, а встановлення вказівника, який вказує на df1. Тому будь-які зміни в df2 призведуть до змін у df1. Щоб виправити це, можете зробити так:

df2 = df1.copy()

або

from copy import deepcopy
df2 = deepcopy(df1)

map

Це чудова команда для легких перетворень даних. Спочатку визначається словник (dict), у якому “ключі” (keys) є старими значеннями, а “значеннями” (values) є нові значення.

level_map = {1: ‘high’, 2: ‘medium’, 3: ‘low’}
df[‘c_level’] = df[‘c’].map(level_map)

Кілька прикладів: True, False до 1, 0; визначення рівнів; визначені користувачем лексичні кодування.

apply or not apply?

Якби ми хотіли створити новий стовпець із кількома іншими стовпцями в ролі вхідних даних, функція apply стала б у пригоді.

def rule(x, y):
    if x == ‘high’ and y > 10:
         return 1
    else:
         return 0
df = pd.DataFrame({ 'c1':[ 'high' ,'high', 'low', 'low'], 'c2': [0, 23, 17, 4]})
df['new'] = df.apply(lambda x: rule(x['c1'], x['c2']), axis =  1)
df.head()

У наведених вище прикладах ми визначаємо функцію з двома вхідними змінними й використовуємо функцію apply, щоб застосувати її до стовпців c1 і c2.

Але проблема apply полягає в тому, що вона іноді занадто повільна. Скажімо, якщо потрібно розрахувати максимум двох стовпцівc1 і c2, звичайно, ви можете зробити це:

df[‘maximum’] = df.apply(lambda x: max(x[‘c1’], x[‘c2’]), axis = 1)

Але ви побачите, що вона працює значно повільніше, ніж ця команда:

df[‘maximum’] = df[[‘c1’,’c2']].max(axis =1)

Висновок: не застосовуйте apply, якщо ви можете виконати ту саму роботу з іншими вбудованими функціями (часто вони швидші). Наприклад, якщо потрібно округлити стовпець c до цілих чисел, зробіть round(df[‘c’], 0) замість використання функції apply.

value counts

Це команда для перевірки розподілу значень. Наприклад, якщо ви хочете перевірити можливі значення та частоту для кожного окремого значення в стовпці c, ви можете зробити:

df[‘c’].value_counts()

Ось деякі корисні аргументи і прийоми:

А. normalize=True: якщо ви хочете перевірити частоту замість кількості.

В. dropna=False: якщо ви також хочете внести до статистики відсутні значення.

С. sort=False: показувати статистику, відсортовану за значеннями, а не порядковими номерами.

D. df[‘c].value_counts().reset_index(): якщо ви хочете перетворити таблицю статистики у фрейм даних Pandas та управляти ним.

Кількість пустих значень

Будуючи моделі, можна вилучити рядок із завеликою кількістю пустих значень або рядки з усіма пустими значеннями. Ви можете використовувати .isnull() і .sum() для підрахунку кількості пустих значень у зазначених стовпцях.

import pandas as pd
import numpy as np
df = pd.DataFrame({ ‘id’: [1,2,3], ‘c1’:[0,0,np.nan], ‘c2’: [np.nan,1,1]})
df = df[[‘id’, ‘c1’, ‘c2’]]
df[‘num_nulls’] = df[[‘c1’, ‘c2’]].isnull().sum(axis=1)
df.head()

Вибрати рядки з певними ідентифікаторами

У SQL ми можемо зробити це, використовуючи SELECT * FROM… WHERE ID in ("A001", "C022",…), щоб одержати записи з конкретними ідентифікаторами. Якщо хочете зробити те саме з Pandas, ви можете зробити так:

df_filter = df[‘ID’].isin([‘A001’,‘C022’,...])
df[df_filter]

Процентні групи

У вас є числовий стовпець, і ви хотіли б класифікувати значення в цьому стовпці за групами, наприклад, до 5% у групі 1, 5–20% у групі 2, 20% –50% у групі 3, понад 50% — у групі 4. Звісно, ви можете зробити це за допомогою pandas.cut, але я хотів би показати інший варіант:

import numpy as np
cut_points = [np.percentile(df[‘c’], i) for i in [50, 80, 95]]
df[‘group’] = 1
for i in range(3):
    df[‘group’] = df[‘group’] + (df[‘c’] < cut_points[i])
# or <= cut_points[i]

який швидко виконується (не треба застосовувати функцію apply).

to_csv

І знову команда, яку кожен використовує. Тут хотілося б відзначити два прийоми. Перший:

 

print(df[:5].to_csv())

Ви можете скористатися цією командою, щоб роздрукувати перші п’ять рядків того, що буде записано у файл.

Другий прийом полягає в тому, щоб оперувати набором цілих та відсутніми значеннями. Якщо стовпець містить як відсутні значення, так і цілі числа, тип даних усе одно буде “плаваючим” замість цілочисельного. Експортуючи таблицю, можете додати float_format=‘%.0f’, щоб округлити всі “плаваючі” до цілих чисел. Використовуйте цей прийом, якщо хочете мати лише цілочисельні відображення даних для всіх стовпців — ви позбудетеся всіх набридливих .0.

Сподіваємося, ви знайшли для себе щось нове. Пишіть в коментарях, якщо ви знаєте інші цікаві команди.

Якщо ви знайшли помилку, будь ласка, виділіть фрагмент тексту та натисніть Ctrl+Enter.

0

Повідомити про помилку

Текст, який буде надіслано нашим редакторам: