Biblioteka - Pandas

Opublikowano

09.05.2023 22:42

Pandas

Pandas jest biblioteką Pythona służącą do analizy i manipulowania danymi

Import:

import pandas as pd

Podstawowe byty

Seria - Series


Ramka danych - DataFrame

import pandas as pd
import numpy as np

s = pd.Series([3, -5, 7, 4])
print(s)
print("values")
print(s.values)
print(type(s.values))
t = np.sort(s.values)
print(t)
print(s.index)
print(type(s.index))
0    3
1   -5
2    7
3    4
dtype: int64
values
[ 3 -5  7  4]
<class 'numpy.ndarray'>
[-5  3  4  7]
RangeIndex(start=0, stop=4, step=1)
<class 'pandas.core.indexes.range.RangeIndex'>
import pandas as pd
import numpy as np

s = pd.Series([3, -5, 7, 4], index=['a', 'b', 'c', 'd'])
print(s)
print(s['b'])
s['b'] = 8
print(s)
print(s[s > 5])
print(s * 2)
print(np.sin(s))
a    3
b   -5
c    7
d    4
dtype: int64
-5
a    3
b    8
c    7
d    4
dtype: int64
b    8
c    7
dtype: int64
a     6
b    16
c    14
d     8
dtype: int64
a    0.141120
b    0.989358
c    0.656987
d   -0.756802
dtype: float64
import pandas as pd

d = {'key1': 350, 'key2': 700, 'key3': 70}
s = pd.Series(d)
print(s)
key1    350
key2    700
key3     70
dtype: int64
import pandas as pd

d = {'key1': 350, 'key2': 700, 'key3': 70}
k = ['key0', 'key2', 'key3', 'key1']
s = pd.Series(d, index=k)
print(s)
pd.isnull(s)
pd.notnull(s)
s.isnull()
s.notnull()
s.name = "Wartosc"
s.index.name = "Klucz"
print(s)
key0      NaN
key2    700.0
key3     70.0
key1    350.0
dtype: float64
Klucz
key0      NaN
key2    700.0
key3     70.0
key1    350.0
Name: Wartosc, dtype: float64
import pandas as pd

data = {'Country': ['Belgium', 'India', 'Brazil'],
        'Capital': ['Brussels', 'New Delhi', 'Brasília'],
        'Population': [11190846, 1303171035, 207847528]}
frame = pd.DataFrame(data)
print(frame)
df = pd.DataFrame(data, columns=['Country', 'Population', 'Capital'])
print(df)
   Country    Capital  Population
0  Belgium   Brussels    11190846
1    India  New Delhi  1303171035
2   Brazil   Brasília   207847528
   Country  Population    Capital
0  Belgium    11190846   Brussels
1    India  1303171035  New Delhi
2   Brazil   207847528   Brasília
import pandas as pd

data = {'Country': ['Belgium', 'India', 'Brazil'],
        'Capital': ['Brussels', 'New Delhi', 'Brasília'],
        'Population': [11190846, 1303171035, 207847528]}
print(df.iloc[[0], [0]])
print("--")
print(df.loc[[0], ['Country']])
print("--")
print(df.loc[2])
print("--")
print(df.loc[:, 'Capital'])
print("--")
print(df.loc[1, 'Capital'])
   Country
0  Belgium
--
   Country
0  Belgium
--
Country          Brazil
Population    207847528
Capital        Brasília
Name: 2, dtype: object
--
0     Brussels
1    New Delhi
2     Brasília
Name: Capital, dtype: object
--
New Delhi
  1. loc:
  • To metoda indeksowania oparta na etykietach, co oznacza, że używa nazw etykiet kolumn i indeksów wierszy do wyboru danych.
  • Działa na podstawie etykiet indeksu oraz etykiet kolumny, co pozwala na wygodniejsze filtrowanie danych.
  • Obsługuje zarówno jednostkowe etykiety, jak i zakresy etykiet.
  • Działa również z etykietami nieliczbowymi.
  • Przykład użycia: df.loc[1:3, ['A', 'B']] - zwraca wiersze od indeksu 1 do 3 (włącznie) oraz kolumny ‘A’ i ‘B’.
  1. iloc:
  • To metoda indeksowania oparta na pozycji, co oznacza, że używa liczbowych indeksów kolumn i wierszy do wyboru danych.
  • Działa na podstawie liczbowych indeksów zarówno dla wierszy, jak i kolumn.
  • Obsługuje jednostkowe indeksy oraz zakresy indeksów.
  • W przypadku używania zakresów indeksów, zakres jest półotwarty, co oznacza, że prawy kraniec nie jest uwzględniany.
  • Przykład użycia: df.iloc[1:3, 0:2] - zwraca wiersze od indeksu 1 do 3 (bez 3) oraz kolumny od indeksu 0 do 2 (bez 2).
import pandas as pd

data = {'Country': ['Belgium', 'India', 'Brazil'],
        'Capital': ['Brussels', 'New Delhi', 'Brasília'],
        'Population': [11190846, 1303171035, 207847528]}
print(df['Population'])       
print("--")
print(df[df['Population'] > 1200000000])
print("--")
print(df.drop('Country', axis=1))
print("--")
0      11190846
1    1303171035
2     207847528
Name: Population, dtype: int64
--
  Country  Population    Capital
1   India  1303171035  New Delhi
--
   Population    Capital
0    11190846   Brussels
1  1303171035  New Delhi
2   207847528   Brasília
--
import pandas as pd

data = {'Country': ['Belgium', 'India', 'Brazil'],
        'Capital': ['Brussels', 'New Delhi', 'Brasília'],
        'Population': [11190846, 1303171035, 207847528]}
print("Shape:", df.shape)
print("--")
print("Index:", df.index)
print("--")
print("columns:", df.columns)
print("--")
df.info()
print("--")
print(df.count())
Shape: (3, 3)
--
Index: RangeIndex(start=0, stop=3, step=1)
--
columns: Index(['Country', 'Population', 'Capital'], dtype='object')
--
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3 entries, 0 to 2
Data columns (total 3 columns):
 #   Column      Non-Null Count  Dtype 
---  ------      --------------  ----- 
 0   Country     3 non-null      object
 1   Population  3 non-null      int64 
 2   Capital     3 non-null      object
dtypes: int64(1), object(2)
memory usage: 200.0+ bytes
--
Country       3
Population    3
Capital       3
dtype: int64

Uzupełnianie braków

import pandas as pd

s = pd.Series([3, -5, 7, 4], index=['a', 'b', 'c', 'd'])
s2 = pd.Series([7, -2, 3], index=['a', 'c', 'd'])
print(s + s2)
print("--")
print(s.add(s2, fill_value=0))
print("--")
print(s.mul(s2, fill_value=2))
a    10.0
b     NaN
c     5.0
d     7.0
dtype: float64
--
a    10.0
b    -5.0
c     5.0
d     7.0
dtype: float64
--
a    21.0
b   -10.0
c   -14.0
d    12.0
dtype: float64

Obsługa plików csv

Funkcja pandas.read_csv

Dokumentacja: link

Wybrane argumenty:

  • filepath - ścieżka dostępu
  • sep=_NoDefault.no_default, delimiter=None - separator
  • header='infer' - nagłówek - domyślnie nazwy kolumn, ew. header=None oznacza brak nagłówka
  • index_col=None - ustalenie kolumny na indeksy (nazwy wierszy)
  • thousands=None - separator tysięczny
  • decimal='.' - separator dziesiętny

Zapis pandas.DataFrame.to_csv

Dokumentacja: link

Obsługa plików z Excela

Funkcja pandas.read_excel

https://pandas.pydata.org/docs/reference/api/pandas.read_excel.html

** Ważne: trzeba zainstalować bibliotekę openpyxl do importu .xlsx oraz xlrd do importu .xls (nie trzeba ich importować w kodzie jawnie w większości wypadków)

Wybrane argumenty:

  • io - ścieżka dostępu
  • sheet_name=0 - nazwa arkusza
  • header='infer' - nagłówek - domyślnie nazwy kolumn, ew. header=None oznacza brak nagłówka
  • index_col=None - ustalenie kolumny na indeksy (nazwy wierszy)
  • thousands=None - separator tysięczny
  • decimal='.' - separator dziesiętny

Repozytorium z testowymi plikami

Operacje manipulacyjne

Ściągawka https://pandas.pydata.org/Pandas_Cheat_Sheet.pdf

  • merge

https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.merge.html

Funkcja merge służy do łączenia dwóch ramek danych wzdłuż wspólnej kolumny, podobnie jak operacje JOIN w SQL.

DataFrame.merge(right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=('_x', '_y'), copy=True, indicator=False, validate=None)

Gdzie:

  • right: ramka danych, którą chcesz dołączyć do oryginalnej ramki danych.
  • how: określa typ łączenia. Dostępne są cztery typy: ‘inner’, ‘outer’, ‘left’ i ‘right’. ‘inner’ to domyślna wartość, która zwraca tylko te wiersze, które mają pasujące klucze w obu ramkach danych.
  • on: nazwa lub lista nazw, które mają być używane do łączenia. Musi to być nazwa występująca zarówno w oryginalnej, jak i prawej ramce danych.
  • left_on i right_on: nazwy kolumn w lewej i prawej ramce danych, które mają być używane do łączenia. Można to użyć, jeśli nazwy kolumn nie są takie same.
  • left_index i right_index: czy indeksy z lewej i prawej ramki danych mają być używane do łączenia.
  • sort: czy wynikowa ramka danych ma być posortowany według łączonych kluczy.
  • suffixes: sufiksy, które mają być dodane do nazw kolumn, które nachodzą na siebie. Domyślnie to (’_x’, ’_y’).
  • copy: czy zawsze kopiować dane, nawet jeśli nie są potrzebne.
  • indicator: dodaj kolumnę do wynikowej ramki danych, która pokazuje źródło każdego wiersza.
  • validate: sprawdź, czy określone zasady łączenia są spełnione.
import pandas as pd

df1 = pd.DataFrame({
    'A': ['A0', 'A1', 'A2', 'A3'],
    'B': ['B0', 'B1', 'B2', 'B3'],
    'key': ['K0', 'K1', 'K0', 'K1']
})

df2 = pd.DataFrame({
    'C': ['C0', 'C1'],
    'D': ['D0', 'D1']},
    index=['K0', 'K1']
)

print(df1)
print(df2)
merged_df = df1.merge(df2, left_on='key', right_index=True)
print(merged_df)
    A   B key
0  A0  B0  K0
1  A1  B1  K1
2  A2  B2  K0
3  A3  B3  K1
     C   D
K0  C0  D0
K1  C1  D1
    A   B key   C   D
0  A0  B0  K0  C0  D0
2  A2  B2  K0  C0  D0
1  A1  B1  K1  C1  D1
3  A3  B3  K1  C1  D1
import pandas as pd

df1 = pd.DataFrame({
    'key': ['K0', 'K1', 'K2', 'K3'],
    'A': ['A0', 'A1', 'A2', 'A3'],
    'B': ['B0', 'B1', 'B2', 'B3']
})

df2 = pd.DataFrame({
    'key': ['K0', 'K1', 'K4', 'K5'],
    'C': ['C0', 'C1', 'C2', 'C3'],
    'D': ['D0', 'D1', 'D2', 'D3']
})

print(df1)

print(df2)

inner_merged_df = df1.merge(df2, how='inner', on='key', suffixes=('_left', '_right'), indicator=True)
outer_merged_df = df1.merge(df2, how='outer', on='key', suffixes=('_left', '_right'), indicator=True)
left_merged_df = df1.merge(df2, how='left', on='key', suffixes=('_left', '_right'), indicator=True)
right_merged_df = df1.merge(df2, how='right', on='key', suffixes=('_left', '_right'), indicator=True)

print("Inner join")
print(inner_merged_df)

print("Outer join")
print(outer_merged_df)

print("Left join")
print(left_merged_df)

print("Right join")
print(right_merged_df)
  key   A   B
0  K0  A0  B0
1  K1  A1  B1
2  K2  A2  B2
3  K3  A3  B3
  key   C   D
0  K0  C0  D0
1  K1  C1  D1
2  K4  C2  D2
3  K5  C3  D3
Inner join
  key   A   B   C   D _merge
0  K0  A0  B0  C0  D0   both
1  K1  A1  B1  C1  D1   both
Outer join
  key    A    B    C    D      _merge
0  K0   A0   B0   C0   D0        both
1  K1   A1   B1   C1   D1        both
2  K2   A2   B2  NaN  NaN   left_only
3  K3   A3   B3  NaN  NaN   left_only
4  K4  NaN  NaN   C2   D2  right_only
5  K5  NaN  NaN   C3   D3  right_only
Left join
  key   A   B    C    D     _merge
0  K0  A0  B0   C0   D0       both
1  K1  A1  B1   C1   D1       both
2  K2  A2  B2  NaN  NaN  left_only
3  K3  A3  B3  NaN  NaN  left_only
Right join
  key    A    B   C   D      _merge
0  K0   A0   B0  C0  D0        both
1  K1   A1   B1  C1  D1        both
2  K4  NaN  NaN  C2  D2  right_only
3  K5  NaN  NaN  C3  D3  right_only
  • join

https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.join.html

Metoda join jest używana do łączenia dwóch ramek danych wzdłuż osi.

Podstawowe użycie tej metody wygląda następująco:

DataFrame.join(other, on=None, how='left', lsuffix='', rsuffix='', sort=False)

Gdzie:

  • other: ramka danych, którą chcesz dołączyć do oryginalnej ramki danych.
  • on: nazwa lub lista nazw kolumn w oryginalnej ramxce danych, do których chcesz dołączyć.
  • how: określa typ łączenia. Dostępne są cztery typy: ‘inner’, ‘outer’, ‘left’ i ‘right’. ‘left’ to domyślna wartość, która zwraca wszystkie wiersze z oryginalnej ramki danych i pasujące wiersze z drugiej ramki danych. Wartości są uzupełniane wartością NaN, jeśli nie ma dopasowania.
  • lsuffix i rsuffix: sufiksy do dodania do kolumn, które się powtarzają. Domyślnie jest to puste.
  • sort: czy sortować dane według klucza.
import pandas as pd

df1 = pd.DataFrame({
    'A': ['A0', 'A1', 'A2'],
    'B': ['B0', 'B1', 'B2']},
    index=['K0', 'K1', 'K2']
)

df2 = pd.DataFrame({
    'C': ['C0', 'C2', 'C3'],
    'D': ['D0', 'D2', 'D3']},
    index=['K0', 'K2', 'K3']
)

print(df1)

print(df2)

joined_df = df1.join(df2)
print(joined_df)
     A   B
K0  A0  B0
K1  A1  B1
K2  A2  B2
     C   D
K0  C0  D0
K2  C2  D2
K3  C3  D3
     A   B    C    D
K0  A0  B0   C0   D0
K1  A1  B1  NaN  NaN
K2  A2  B2   C2   D2
  • concat

https://pandas.pydata.org/docs/reference/api/pandas.concat.html

Metoda concat jest używana do łączenia dwóch lub więcej ramek danych wzdłuż określonej osi.

Podstawowe użycie tej metody wygląda następująco:

pandas.concat(objs, axis=0, join='outer', ignore_index=False, keys=None, levels=None, names=None, verify_integrity=False, sort=False, copy=True)

Gdzie:

  • objs: sekwencja ramek danych, które chcesz połączyć.
  • axis: oś, wzdłuż której chcesz łączyć ramki danych. Domyślnie to 0 (łączenie wierszy, pionowo), ale można także ustawić na 1 (łączenie kolumn, poziomo).
  • join: określa typ łączenia. Dostępne są dwa typy: ‘outer’ i ‘inner’. ‘outer’ to domyślna wartość, która zwraca wszystkie kolumny z każdej ramki danych. ‘inner’ zwraca tylko te kolumny, które są wspólne dla wszystkich ramek danych.
  • ignore_index: jeśli ustawione na True, nie używa indeksów z ramek danych do tworzenia indeksu w wynikowej ramce danych. Zamiast tego tworzy nowy indeks od 0 do n-1.
  • keys: wartości do skojarzenia z obiektami.
  • levels: określone indeksy dla nowej ramki danych.
  • names: nazwy dla poziomów indeksów (jeśli są wielopoziomowe).
  • verify_integrity: sprawdza, czy nowy, skonkatenowana ramka danych nie ma powtarzających się indeksów.
  • sort: czy sortować niekonkatenacyjną oś (np. indeksy, jeśli axis=0), niezależnie od danych.
  • copy: czy zawsze kopiować dane, nawet jeśli nie są potrzebne.
import pandas as pd

df1 = pd.DataFrame({
    'A': ['A0', 'A1', 'A2'],
    'B': ['B0', 'B1', 'B2']
})

df2 = pd.DataFrame({
    'A': ['A3', 'A4', 'A5'],
    'B': ['B3', 'B4', 'B5']
})

print(df1)

print(df2)

concatenated_df = pd.concat([df1, df2], ignore_index=True)
print(concatenated_df)
    A   B
0  A0  B0
1  A1  B1
2  A2  B2
    A   B
0  A3  B3
1  A4  B4
2  A5  B5
    A   B
0  A0  B0
1  A1  B1
2  A2  B2
3  A3  B3
4  A4  B4
5  A5  B5
import pandas as pd

df1 = pd.DataFrame({
    'A': ['A0', 'A1', 'A2'],
    'B': ['B0', 'B1', 'B2']
})

df2 = pd.DataFrame({
    'C': ['C0', 'C1', 'C2'],
    'D': ['D0', 'D1', 'D2']
})

print(df1)

print(df2)

concatenated_df_axis1 = pd.concat([df1, df2], axis=1)
concatenated_df_keys = pd.concat([df1, df2], keys=['df1', 'df2'])

print(concatenated_df_axis1)
print(concatenated_df_keys)
    A   B
0  A0  B0
1  A1  B1
2  A2  B2
    C   D
0  C0  D0
1  C1  D1
2  C2  D2
    A   B   C   D
0  A0  B0  C0  D0
1  A1  B1  C1  D1
2  A2  B2  C2  D2
         A    B    C    D
df1 0   A0   B0  NaN  NaN
    1   A1   B1  NaN  NaN
    2   A2   B2  NaN  NaN
df2 0  NaN  NaN   C0   D0
    1  NaN  NaN   C1   D1
    2  NaN  NaN   C2   D2
  • pivot

https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.pivot.html

Metoda pivot jest używana do przekształcenia danych z formatu “długiego” do “szerokiego”.

Podstawowe użycie tej metody wygląda następująco:

DataFrame.pivot(index=None, columns=None, values=None)

Gdzie:

  • index: nazwa kolumny lub lista nazw kolumn, które mają stać się indeksem w nowej ramce danych.
  • columns: nazwa kolumny, z której unikalne wartości mają stać się kolumnami w nowej ramce danych.
  • values: nazwa kolumny lub lista nazw kolumn, które mają stać się wartościami dla nowych kolumn w nowej ramce danych.
import pandas as pd

df = pd.DataFrame({
    'foo': ['one', 'one', 'one', 'two', 'two', 'two'],
    'bar': ['A', 'B', 'C', 'A', 'B', 'C'],
    'baz': [1, 2, 3, 4, 5, 6],
    'zoo': ['x', 'y', 'z', 'q', 'w', 't'],
})

print(df)

pivot_df = df.pivot(index='foo', columns='bar', values='baz')
print(pivot_df)
   foo bar  baz zoo
0  one   A    1   x
1  one   B    2   y
2  one   C    3   z
3  two   A    4   q
4  two   B    5   w
5  two   C    6   t
bar  A  B  C
foo         
one  1  2  3
two  4  5  6
  • wide_to_long

https://pandas.pydata.org/docs/reference/api/pandas.wide_to_long.html

  • melt

https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.melt.html

Funkcja melt służy do przekształcania danych z formatu szerokiego na długi.

Podstawowe użycie tej metody wygląda następująco:

pandas.melt(frame, id_vars=None, value_vars=None, var_name=None, value_name='value', col_level=None)

Gdzie:

  • frame: ramka danych, którą chcesz przetworzyć.
  • id_vars: kolumna(y), które chcesz zachować jako identyfikatory. Te kolumny nie będą zmieniane.
  • value_vars: kolumna(y), które chcesz przekształcić na pary klucz-wartość. Jeżeli nie jest podane, wszystkie kolumny nie będące id_vars zostaną użyte.
  • var_name: nazwa nowej kolumny, która będzie zawierała nazwy kolumn przekształconych na pary klucz-wartość. Domyślnie to ‘variable’.
  • value_name: nazwa nowej kolumny, która będzie zawierała wartości kolumn przekształconych na pary klucz-wartość. Domyślnie to ‘value’.
  • col_level: jeżeli kolumny są wielopoziomowe, to jest poziom, który będzie użyty do przekształcania kolumn na pary klucz-wartość.
import pandas as pd

df = pd.DataFrame({
    'A': ['foo', 'bar', 'baz'],
    'B': ['one', 'one', 'two'],
    'C': [2.0, 1.0, 3.0],
    'D': [3.0, 2.0, 1.0]
})
print(df)
melted_df = df.melt(id_vars=['A', 'B'], value_vars=['C', 'D'], var_name='My_Var', value_name='My_Val')
print(melted_df)
     A    B    C    D
0  foo  one  2.0  3.0
1  bar  one  1.0  2.0
2  baz  two  3.0  1.0
     A    B My_Var  My_Val
0  foo  one      C     2.0
1  bar  one      C     1.0
2  baz  two      C     3.0
3  foo  one      D     3.0
4  bar  one      D     2.0
5  baz  two      D     1.0

“Tidy data”

Imię Wiek Wzrost Kolor oczu
Adam 26 167 Brązowe
Sylwia 34 164 Piwne
Tomasz 42 183 Niebieskie
  • jedna obserwacja (jednostka statystyczna) = jeden wiersz w tabeli/macierzy/ramce danych
  • wartosci danej cechy znajduja sie w kolumnach
  • jeden typ/rodzaj obserwacji w jednej tabeli/macierzy/ramce danych

Obsługa brakujących danych

import numpy as np
import pandas as pd

string_data = pd.Series(['aardvark', 'artichoke', np.nan, 'avocado'])
print(string_data)
print(string_data.isnull())
print(string_data.dropna())
0     aardvark
1    artichoke
2          NaN
3      avocado
dtype: object
0    False
1    False
2     True
3    False
dtype: bool
0     aardvark
1    artichoke
3      avocado
dtype: object

from numpy import nan as NA
import pandas as pd

data = pd.DataFrame([[1., 6.5, 3.], [1., NA, NA], 
                     [NA, NA, NA], [NA, 6.5, 3.]])
cleaned = data.dropna()
print(cleaned)
print(data.dropna(how='all'))
data[4] = NA
print(data.dropna(how='all', axis=1))
print(data)
print(data.fillna(0))
print(data.fillna({1: 0.5, 2: 0}))
     0    1    2
0  1.0  6.5  3.0
     0    1    2
0  1.0  6.5  3.0
1  1.0  NaN  NaN
3  NaN  6.5  3.0
     0    1    2
0  1.0  6.5  3.0
1  1.0  NaN  NaN
2  NaN  NaN  NaN
3  NaN  6.5  3.0
     0    1    2   4
0  1.0  6.5  3.0 NaN
1  1.0  NaN  NaN NaN
2  NaN  NaN  NaN NaN
3  NaN  6.5  3.0 NaN
     0    1    2    4
0  1.0  6.5  3.0  0.0
1  1.0  0.0  0.0  0.0
2  0.0  0.0  0.0  0.0
3  0.0  6.5  3.0  0.0
     0    1    2   4
0  1.0  6.5  3.0 NaN
1  1.0  0.5  0.0 NaN
2  NaN  0.5  0.0 NaN
3  NaN  6.5  3.0 NaN

Usuwanie duplikatów

import pandas as pd

data = pd.DataFrame({'k1': ['one', 'two'] * 3 + ['two'],
                     'k2': [1, 1, 2, 3, 3, 4, 4]})
print(data)
print(data.duplicated())
print(data.drop_duplicates())
    k1  k2
0  one   1
1  two   1
2  one   2
3  two   3
4  one   3
5  two   4
6  two   4
0    False
1    False
2    False
3    False
4    False
5    False
6     True
dtype: bool
    k1  k2
0  one   1
1  two   1
2  one   2
3  two   3
4  one   3
5  two   4

Zastępowanie wartościami

import pandas as pd
import numpy as np

data = pd.Series([1., -999., 2., -999., -1000., 3.])
print(data)
print(data.replace(-999, np.nan))
print(data.replace([-999, -1000], np.nan))
print(data.replace([-999, -1000], [np.nan, 0]))
print(data.replace({-999: np.nan, -1000: 0}))
0       1.0
1    -999.0
2       2.0
3    -999.0
4   -1000.0
5       3.0
dtype: float64
0       1.0
1       NaN
2       2.0
3       NaN
4   -1000.0
5       3.0
dtype: float64
0    1.0
1    NaN
2    2.0
3    NaN
4    NaN
5    3.0
dtype: float64
0    1.0
1    NaN
2    2.0
3    NaN
4    0.0
5    3.0
dtype: float64
0    1.0
1    NaN
2    2.0
3    NaN
4    0.0
5    3.0
dtype: float64

Dyskretyzacja i podział na koszyki

import pandas as pd

ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32]
bins = [18, 25, 35, 60, 100]
cats = pd.cut(ages, bins)
print(cats)
print(cats.codes)
print(cats.categories)
print(pd.value_counts(cats))
[(18, 25], (18, 25], (18, 25], (25, 35], (18, 25], ..., (25, 35], (60, 100], (35, 60], (35, 60], (25, 35]]
Length: 12
Categories (4, interval[int64, right]): [(18, 25] < (25, 35] < (35, 60] < (60, 100]]
[0 0 0 1 0 0 2 1 3 2 2 1]
IntervalIndex([(18, 25], (25, 35], (35, 60], (60, 100]], dtype='interval[int64, right]')
(18, 25]     5
(25, 35]     3
(35, 60]     3
(60, 100]    1
dtype: int64

import pandas as pd

ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32]
bins = [18, 25, 35, 60, 100]
cats2 = pd.cut(ages, [18, 26, 36, 61, 100], right=False)
print(cats2)
group_names = ['Youth', 'YoungAdult',
               'MiddleAged', 'Senior']
print(pd.cut(ages, bins, labels=group_names))
[[18, 26), [18, 26), [18, 26), [26, 36), [18, 26), ..., [26, 36), [61, 100), [36, 61), [36, 61), [26, 36)]
Length: 12
Categories (4, interval[int64, left]): [[18, 26) < [26, 36) < [36, 61) < [61, 100)]
['Youth', 'Youth', 'Youth', 'YoungAdult', 'Youth', ..., 'YoungAdult', 'Senior', 'MiddleAged', 'MiddleAged', 'YoungAdult']
Length: 12
Categories (4, object): ['Youth' < 'YoungAdult' < 'MiddleAged' < 'Senior']

import pandas as pd
import numpy as np

data = np.random.rand(20)
print(pd.cut(data, 4, precision=2))
[(0.25, 0.46], (0.25, 0.46], (0.25, 0.46], (0.043, 0.25], (0.67, 0.88], ..., (0.46, 0.67], (0.043, 0.25], (0.043, 0.25], (0.46, 0.67], (0.46, 0.67]]
Length: 20
Categories (4, interval[float64, right]): [(0.043, 0.25] < (0.25, 0.46] < (0.46, 0.67] < (0.67, 0.88]]

import pandas as pd
import numpy as np

data = np.random.randn(1000)
cats = pd.qcut(data, 4)
print(cats)
print(pd.value_counts(cats))
[(-0.717, -0.0615], (-0.0615, 0.644], (0.644, 4.055], (-0.0615, 0.644], (-0.0615, 0.644], ..., (0.644, 4.055], (0.644, 4.055], (-0.0615, 0.644], (-0.717, -0.0615], (-2.698, -0.717]]
Length: 1000
Categories (4, interval[float64, right]): [(-2.698, -0.717] < (-0.717, -0.0615] < (-0.0615, 0.644] < (0.644, 4.055]]
(-2.698, -0.717]     250
(-0.717, -0.0615]    250
(-0.0615, 0.644]     250
(0.644, 4.055]       250
dtype: int64

Wykrywanie i filtrowanie elementów odstających

import pandas as pd
import numpy as np

data = pd.DataFrame(np.random.randn(1000, 4))
print(data.describe())
print("---")
col = data[2]
print(col[np.abs(col) > 3])
print("---")
print(data[(np.abs(data) > 3).any(axis=1)])
                 0            1            2            3
count  1000.000000  1000.000000  1000.000000  1000.000000
mean      0.060253     0.042921    -0.045572    -0.009812
std       1.001095     1.001682     0.988745     0.979808
min      -2.658864    -4.137047    -2.923842    -3.451026
25%      -0.613159    -0.641558    -0.733673    -0.626279
50%       0.048476     0.018188    -0.051406    -0.018437
75%       0.741319     0.714492     0.615344     0.622985
max       3.328931     3.355495     3.036254     3.298667
---
979    3.036254
Name: 2, dtype: float64
---
            0         1         2         3
26   0.253202 -3.216112  1.723595 -0.967542
58  -0.959981  0.362328 -0.341353  3.000685
99   1.184832  3.001836  0.130076  0.445298
150 -0.139375 -4.137047 -0.875463  0.693014
255 -0.043186  3.044995 -1.825525  0.084556
396  1.592125 -0.551964  0.369992  3.021877
399  0.161776  3.355495 -0.794017 -1.217621
422  3.328931 -0.367044  0.234019 -0.117407
475  3.001016 -1.687679  1.756672  0.674678
710  1.993710  0.266014  0.232733 -3.451026
883 -1.023090 -0.999332 -0.793367  3.298667
890 -0.661033 -0.110789 -2.554383  3.190457
946  3.142321  0.132215 -0.993316  0.718742
979  0.243397 -0.224590  3.036254  1.457108

Bibliografia:

  • Dokumentacja biblioteki, https://pandas.pydata.org/, dostęp online 5.03.2021.
  • Hannah Stepanek, Thinking in Pandas, How to Use the Python Data Analysis Library the Right Way, Apress, 2020.