Shiutang Li
Shiutang Li Data Scientist @ Verisk Analytics

10 przydatnych komend Pandas

Poznaj 10 komend Pandas, które ułatwią Ci pracę z danymi w Pythonie.
4.04.20215 min
10 przydatnych komend Pandas

Niektóre komendy może już znasz, ale nie raczej nie wiedziałeś, że mogą być używane w ten sposób. Pandas to pakiet Pythona powszechnie używany do pracy z danymi ustrukturyzowanymi. W internecie znajdziesz wiele dobrych samouczków na jego temat, jednak dziś chciałbym przedstawić Ci kilka fajnych sztuczek, których mogłeś wcześniej nie znać, a są całkiem przydatne.

read_csv

Wszyscy zapewne znają to polecenie. Ale jeśli danych, które próbujesz odczytać, jest wiele, spróbuj dodać argument: nrows = 5, aby przeczytać tylko niewielką część tabeli, zanim faktycznie załadujesz jej całość. W ten sposób możesz uniknąć błędów, polegających na wyborze złego separatora (nie zawsze może być on oddzielony przecinkami).

(lub, możesz też użyć polecenia head w linuxie, aby sprawdzić pierwsze 5 wierszy (mniej więcej) w dowolnym pliku tekstowym: head -n 5 data.txt.

W ten sposób możesz wyodrębnić listę kolumn, używając df.columns.tolist(), aby wyodrębnić wszystkie kolumny, a następnie dodać argument usecols = ['c1', 'c2',…], aby załadować tylko potrzebne kolumny. Ponadto, jeśli znasz typy danych kilku konkretnych kolumn, możesz dodać argument dtype = {'c1': str, 'c2': int,…}, aby ładowały się szybciej. Kolejną zaletą tego argumentu jest to, że jeśli masz kolumnę zawierającą zarówno łańcuchy znaków, jak i liczby, dobrą praktyką jest zadeklarowanie jej typu jako stringa, dzięki czemu nie wystąpią błędy podczas próby łączenia tabel przy użyciu tej kolumny jako klucza.

select_dtypes

Jeśli już musisz wykonać przetwarzanie danych w Pythonie, to to polecenie zaoszczędzi Ci trochę czasu. Po odczytaniu tabeli domyślnymi typami danych dla każdej kolumny mogą być bool, int64, float64, object, category, timedelta64 lub datetime64. Możesz najpierw sprawdzić dystrybucję przez:

df.dtypes.value_counts()


aby poznać wszystkie możliwe typy danych w ramce, a następnie wykonać:

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


aby wybrać ramkę danych tylko z funkcjami numerycznymi.

copy

To dość ważne polecenie, jeśli jeszcze o nim nie słyszałeś. Jeśli wykonasz następujące polecenia:

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


Okaże się, że df1 zostało zmienione. Dzieje się tak, ponieważ df2 = df1 nie tworzy kopii df1 i nie przypisuje jej do df2, ale ustawia wskaźnik wskazujący na df1. Wszelkie zmiany w df2 spowodują zmiany w df1. Aby to naprawić, możesz wykonać:

df2 = df1.copy()


lub:

from copy import deepcopy
df2 = deepcopy(df1)

map

To fajne polecenie do łatwej transformacji danych. Najpierw definiujesz słownik, gdzie „klucze”, to stare wartości, a „wartości” to nowe wartości.

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


Kilka przykładów: True, False to 1, 0 (do modelowania); definiowanie poziomów; zdefiniowane przez użytkownika kodowanie leksykalne.

apply czy nie apply?

Gdybyśmy chcieli utworzyć nową kolumnę z kilkoma innymi kolumnami jako wejściami, funkcja apply bywa czasem bardzo przydatna.

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()


W powyższych kodach definiujemy funkcję z dwiema zmiennymi wejściowymi i używamy funkcji apply, aby zastosować ją do kolumn „c1” i „c2”.

Ale problem funkcji apply polega na tym, że czasami jest ona zbyt wolna. Powiedzmy,  że chcesz obliczyć maksymalnie dwie kolumny „c1” i „c2”, oczywiście możesz to zrobić:

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


ale znajdziesz wynik znacznie wolniej niż używając tego polecenia:

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


Wniosek
: Nie używaj apply, jeśli możesz wykonać tę samą pracę z innymi wbudowanymi funkcjami (często są szybsze). Na przykład, jeśli chcesz zaokrąglić kolumnę „c” do liczb całkowitych, wykonaj round(df['c'], 0) lub df['c'].round(0), zamiast używać funkcji: df.apply(lambda x: round(x['c'], 0), axis = 1).

Liczniki wartości

Jest to polecenie do sprawdzania dystrybucji wartości. Na przykład, jeśli chcesz sprawdzić, jakie są możliwe wartości i częstotliwość dla każdej indywidualnej wartości w kolumnie „c”, możesz użyć:

df['c'].value_counts()


Znajdziemy tu też parę przydatnych sztuczek/argumentów :

  1. normalize = True: jeśli chcesz sprawdzić częstotliwość zamiast ilości.
  2. dropna = False: jeśli chcesz również uwzględnić brakujące wartości w stats.
  3. df['c'].value_counts().reset_index(): jeśli chcesz przekonwertować tabelę statsów na dataframe Pandasa i manipulować nią.
  4. df['c'].value_counts().reset_index().sort_values(by='index'): pokazuje statystyki posortowane według odrębnych wartości w kolumnie „c” zamiast ilości.

Liczba brakujących wartości

Podczas budowania modeli możesz chcieć wykluczyć wiersz ze zbyt wieloma brakującymi wartościami lub kilka wierszy ze wszystkimi brakującymi wartościami. Możesz użyć .isnull () i .sum (), aby policzyć liczbę brakujących wartości w określonych kolumnach.

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()

Wybierz wiersze z określonymi identyfikatorami

W SQL możemy to zrobić za pomocą SELECT * FROM… WHERE ID in ("A001", "C022",…), aby uzyskać wpisy z określonymi identyfikatorami. Jeśli chcesz zrobić to samo w pandas, możesz użyć:

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

Percentyle

Masz kolumnę liczbową i chcesz sklasyfikować wartości w tej kolumnie w grupy, powiedzmy najwyższe 5% w grupie 1, 5–20% w grupie 2, 20%-50% w grupie 3, 50% w grupie 4. Oczywiście, możesz to zrobić za pomocą pandas.cut, ale chciałbym zaproponować inne rozwiązanie:

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]


które to uruchamia się znacznie szybciej (gdyż nie używa funkcji apply).

to_csv

Znowu, to polecenie, z którego wszyscy korzystają. Chciałbym jednak wskazać dwie sztuczki. Pierwsza z nich to:

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


Możesz użyć tego polecenia, aby wydrukować pierwsze pięć wierszy dokładnie tego, co zostanie zapisane w pliku.

Inną sztuczką jest łączenie liczb całkowitych i brakujących wartości. Jeśli kolumna zawiera zarówno brakujące wartości, jak i liczby całkowite, typ danych nadal będzie floatem, a nie int. Kiedy eksportujesz tabelę, możesz dodać float_format='%.0f', aby zaokrąglić wszystkie float do liczb całkowitych. Użyj tej sztuczki, jeśli chcesz otrzymać tylko liczby całkowite na wyjściu dla wszystkich kolumn - pozbędziesz się wszystkich denerwujących '.0'.


Oryginał artykułu w języku angielskim możesz przeczytać tutaj.

<p>Loading...</p>