236 KiB
Analiza Danych w Pythonie: pandas
pandas
Biblioteka pandas
jest podstawowym narzędziem w ekosystemie Pythona do analizy danych:
- dostarcza dwa podstawowe typy danych:
Series
(szereg, 1D)DataFrame
(ramka danych, 2D)
- operacje na tych obiektach: obsługa brakujących wartości, łączenie danych;
- obsługuje dane różnego typu, np. szeregi czasowe;
- biblioteka bazuje na
numpy
-- bibliotece do obliczeń numerycznych; - pozwala też na prostą wizualizację danych;
- ETL: extract, transform, load.
Żeby zaimportowąc bibliotekę pandas
wystarczy:
import pandas as pd
Zadanie 0: sprawdź, czy masz zainstalowaną bibliotekę pandas
.
Szeregi (pd.Series
)
Szereg reprezentuje jednorodne dane jednowymiarowe - jest odpowiednikiem wektora w R.
Szeregi możemy tworzyć na różne sposoby (więcej za chwilę), np. z obiektów tj. listy i słowniki.
Dane muszą być jednorodne. W przeciwnym przypadku nastąpi automatyczna konwersja.
Podczas tworzenia szeregu musimy podać jeden obowiązkowy argument
data
- dane.Ponadto możemy podać też indeks (
index
), typ danych (dtype
) lub nazwę (name
).class pandas.Series(data=None, index=None, dtype=None, name=None)
Podczas tworzenie szeregu mozemy podać dane w formacie listy lub słownika.
Poniżej jest przykład przedstawiający tworzenie szeregu z danych, które są zawarte w liście:
data = [211819, 682758, 737011, 779511, 673790, 673790, 444177, 136791]
s = pd.Series(data)
s
0 211819 1 682758 2 737011 3 779511 4 673790 5 673790 6 444177 7 136791 dtype: int64
W przypadku, gdy dane pochodzą z listy i nie podaliśmy indeksu, pandas doda automatyczny indeks liczbowy zaczynający się od 0.
W przypadku przekazania słownika jako danych do szeregu, pandas wykorzysta klucze do stworzenia indeksu:
members = {'April': 211819,'May': 682758, 'June': 737011, 'July': 779511}
s = pd.Series(members)
s
April 211819 May 682758 June 737011 July 779511 dtype: int64
Podczas tworzenia szeregu możemy zdefiniować indeks, jak i nazwę szeregu:
months = ['April', 'May', 'June', 'July']
data = [211819, 682758, 737011, 779511]
s = pd.Series(data=data, index=months, dtype=float, name='Rides')
s
April 211819.0 May 682758.0 June 737011.0 July 779511.0 Name: Rides, dtype: float64
Odwołanie się do poszczególnego elementu odbywa się przy pomocy klucza z indeksu.
members = {'April': 211819,'May': 682758, 'June': 737011, 'July': 779511}
s = pd.Series(members)
print(s['April'])
s['August'] = 673790
s
211819
April 211819 May 682758 June 737011 July 779511 August 673790 dtype: int64
Dodanie elementu do szeregu odbywa się poprzez definiowanie nowego klucza:
members = {'April': 211819,'May': 682758, 'June': 737011, 'July': 779511}
s = pd.Series(members)
s['August'] = 673790
s
April 211819 May 682758 June 737011 July 779511 August 673790 dtype: int64
Więcej nt. indeksowania w szeregach w dalszej części kursu.
Podstawowa cechą szeregu jest wykonywanie operacji w sposób wektorowy. Działa to w następujący sposób:
- gdy w obu szeregach jest zawarty ten sam klucz, to są sumowane ich wartości;
- w przeciwnym przypadku wartość klucza w wynikowym szeregu to
pd.NaN
. - Równoważnie możemy wykorzystać metodę
pandas.Series.add
. W tym przypadku możemy podać domyślną wartość w przypadku braku klucza.
members = pd.Series({'May': 682758, 'June': 737011, 'August': 673790, 'July': 779511,
'September': 673790, 'October': 444177})
occasionals = pd.Series({'May': 147898, 'June': 171494, 'July': 194316, 'August': 206809,
'September': 140492})
all_data = members + occasionals
# Równoważnie
all_data = members.add(occasionals)
all_data
August 880599.0 July 973827.0 June 908505.0 May 830656.0 October NaN September 814282.0 dtype: float64
Możemy wykonać operacje arytmetyczne na szeregu:
members = pd.Series({'May': 682758, 'June': 737011, 'July': 779511, 'August': 673790,
'September': 673790, 'October': 444177})
members += 1000
members
May 683758 June 738011 July 780511 August 674790 September 674790 October 445177 dtype: int64
Podsumowanie
- Szeregi działają podobnie do słowników, z tą różnicą, że wartości muszą być jednorodne (tego samego typu).
- Odwołanie do poszczególnych elementów odbywa się poprzez nawiasy
[]
i podanie klucza. - W przeciwieństwie do słowników, możemy w prosty sposób wykonywać operacje arytmetyczne.
Zadanie 1
- Stwórz szereg
n
, który będzie zawierać liczby od 0 do 10 (włącznie). - Stwórz szereg
n2
, który będzie zawierać kwadraty liczb od 0 do 10 (włącznie). - Następnie stwórz szereg
trojkatne
, który będzie sumą powyższych szeregów podzieloną przez 2.
Ramka danych (pd.DataFrame
)
Ramka danych jest podstawową strukturą danych w bibliotece pandas
, która pozwala na trzymanie i reprezentowanie danych tabelarycznych (dwuwymiarowych).
- Posiada kolumny (cechy) i wiersze (obserwacje, przykłady).
- Możemy też patrzeć na nią jak na słownik, którego wartościami są szeregi.
class pandas.DataFrame(data=None, index=None, columns=None, dtype=None)
Ramkę danych możemy stworzyć na różne sposoby.
Pierwszy z nich ("kolumnowy") polega na zdefiniowaniu ramki poprzez podanie szeregów jako kolumn:
members = pd.Series({'May': 682758, 'June': 737011, 'July': 779511})
occasionals = pd.Series({'May': 147898, 'June': 171494, 'July': 194316})
df = pd.DataFrame({'members': members, 'occasionals': occasionals})
df
members | occasionals | |
---|---|---|
May | 682758 | 147898 |
June | 737011 | 171494 |
July | 779511 | 194316 |
Drugim popularnym sposobem jest przekazanie listy słowników. Wtedy pandas
zinterpretuje to jako listę przykładów:
data = [
{'members': 682758, 'occasionals': 147898},
{'occasionals': 171494,'members': 737011},
{'members': 779511, 'occasionals': 194316},
]
df = pd.DataFrame(data)
df
members | occasionals | |
---|---|---|
0 | 682758 | 147898 |
1 | 737011 | 171494 |
2 | 779511 | 194316 |
Możemy też wykorzystać metodę from_dict
(doc), która pozwala zdefiniować czy podane dane są w podane w postaci kolumnowej lub wierszowej:
data = {
'May': {'members': 682758, 'occasionals': 147898},
'June': {'members': 737011, 'occasionals': 171494},
'July': {'members': 779511, 'occasionals': 194316}
}
df = pd.DataFrame.from_dict(data, orient='index')
print('index\n', df)
print()
df = pd.DataFrame.from_dict(data, orient='columns')
print('columns\n', df)
index members occasionals May 682758 147898 June 737011 171494 July 779511 194316 columns May June July members 682758 737011 779511 occasionals 147898 171494 194316
Wczytywanie danych
Biblioteka pandas
pozwala na wczytanie i zapis danych z różnych formatów:
- formaty tekstowe, np.
csv
,json
- pliki arkuszy kalkulacyjnych: Excel (xls, xlsx)
- bazy danych
- inne:
sas
spss
Efektem wczytania danych jest odpowiednio stworzona ramka danych (DataFrame
).
Jednym z najprostszych formatów danych jest format csv
, gdzie kolejne wartości są rozdzielone przecinkiem.
Żeby wczytać dane w takim formacie należy użyć funkcji pandas.read_csv
.
Pandas pozwala na ustawienie wielu parametrów (np. separator, cudzysłowy). Więcej na ten temat w dokumentacji.
df = pd.read_csv('gapminder.csv')
df
Country | female_BMI | male_BMI | gdp | population | under5mortality | life_expectancy | fertility | |
---|---|---|---|---|---|---|---|---|
0 | Afghanistan | 21.07402 | 20.62058 | 1311.0 | 26528741.0 | 110.4 | 52.8 | 6.20 |
1 | Albania | 25.65726 | 26.44657 | 8644.0 | 2968026.0 | 17.9 | 76.8 | 1.76 |
2 | Algeria | 26.36841 | 24.59620 | 12314.0 | 34811059.0 | 29.5 | 75.5 | 2.73 |
3 | Angola | 23.48431 | 22.25083 | 7103.0 | 19842251.0 | 192.0 | 56.7 | 6.43 |
4 | Antigua and Barbuda | 27.50545 | 25.76602 | 25736.0 | 85350.0 | 10.9 | 75.5 | 2.16 |
... | ... | ... | ... | ... | ... | ... | ... | ... |
170 | Venezuela | 28.13408 | 27.44500 | 17911.0 | 28116716.0 | 17.1 | 74.2 | 2.53 |
171 | Vietnam | 21.06500 | 20.91630 | 4085.0 | 86589342.0 | 26.2 | 74.1 | 1.86 |
172 | Palestine | 29.02643 | 26.57750 | 3564.0 | 3854667.0 | 24.7 | 74.1 | 4.38 |
173 | Zambia | 23.05436 | 20.68321 | 3039.0 | 13114579.0 | 94.9 | 51.1 | 5.88 |
174 | Zimbabwe | 24.64522 | 22.02660 | 1286.0 | 13495462.0 | 98.3 | 47.3 | 3.85 |
175 rows × 8 columns
df = pd.read_csv('./titanic_train.tsv', delimiter='\t', index_col=0, nrows=5)
df
Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|
PassengerId | |||||||||||
1 | 0 | 3 | Braund\t Mr. Owen Harris | male | 22 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
2 | 1 | 1 | Cumings\t Mrs. John Bradley (Florence Briggs T... | female | 38 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
3 | 1 | 3 | Heikkinen\t Miss. Laina | female | 26 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S |
4 | 1 | 1 | Futrelle\t Mrs. Jacques Heath (Lily May Peel) | female | 35 | 1 | 0 | 113803 | 53.1000 | C123 | S |
5 | 0 | 3 | Allen\t Mr. William Henry | male | 35 | 0 | 0 | 373450 | 8.0500 | NaN | S |
Do wczytania danych z arkusza kalkulacyjnego służy funkcja pandas.read_excel
. Do otworzenia pliku xlsx
może być koniecnze ustawienie parametru: engine='openpyxl
. Więcej opcji w dokumentacji.
df = pd.read_excel('./bikes.xlsx', engine='openpyxl', nrows=5)
df
start_date | start_station_code | end_date | end_station_code | duration_sec | is_member | |
---|---|---|---|---|---|---|
0 | 2019-04-14 07:55:22 | 6001 | 2019-04-14 08:07:16 | 6132 | 713 | 1 |
1 | 2019-04-14 07:59:31 | 6411 | 2019-04-14 08:09:18 | 6411 | 587 | 1 |
2 | 2019-04-14 07:59:55 | 6097 | 2019-04-14 08:12:11 | 6036 | 736 | 1 |
3 | 2019-04-14 07:59:57 | 6310 | 2019-04-14 08:27:58 | 6345 | 1680 | 1 |
4 | 2019-04-14 08:00:37 | 7029 | 2019-04-14 08:14:12 | 6250 | 814 | 0 |
Innym ważnym źródłem informacji są bazy danych. Pandas potrafi komunikować się z bazą danych za pomocą biblioteki SQLAlchemy i dostarcza odpowiedną funkcję:
pandas.read_sql
- wczytanie całej tabeli lub zapytania do bazy danych
df = pd.read_sql('Album', con='sqlite:///Chinook.sqlite', index_col='AlbumId')
df
Title | ArtistId | |
---|---|---|
AlbumId | ||
1 | For Those About To Rock We Salute You | 1 |
2 | Balls to the Wall | 2 |
3 | Restless and Wild | 2 |
4 | Let There Be Rock | 1 |
5 | Big Ones | 3 |
... | ... | ... |
343 | Respighi:Pines of Rome | 226 |
344 | Schubert: The Late String Quartets & String Qu... | 272 |
345 | Monteverdi: L'Orfeo | 273 |
346 | Mozart: Chamber Music | 274 |
347 | Koyaanisqatsi (Soundtrack from the Motion Pict... | 275 |
347 rows × 2 columns
import sqlalchemy
engine = sqlalchemy.create_engine('sqlite:///Chinook.sqlite', echo=True)
connection = engine.raw_connection()
df = pd.read_sql('SELECT * FROM Album', con='sqlite:///Chinook.sqlite', index_col='AlbumId')
df
2023-11-17 15:53:28,542 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 2023-11-17 15:53:28,543 INFO sqlalchemy.engine.base.Engine () 2023-11-17 15:53:28,544 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 2023-11-17 15:53:28,545 INFO sqlalchemy.engine.base.Engine ()
Title | ArtistId | |
---|---|---|
AlbumId | ||
1 | For Those About To Rock We Salute You | 1 |
2 | Balls to the Wall | 2 |
3 | Restless and Wild | 2 |
4 | Let There Be Rock | 1 |
5 | Big Ones | 3 |
... | ... | ... |
343 | Respighi:Pines of Rome | 226 |
344 | Schubert: The Late String Quartets & String Qu... | 272 |
345 | Monteverdi: L'Orfeo | 273 |
346 | Mozart: Chamber Music | 274 |
347 | Koyaanisqatsi (Soundtrack from the Motion Pict... | 275 |
347 rows × 2 columns
Podsumowanie
- Biblioteka
pandas
wspiera pobieranie danych z różnych formatów i źródeł. - Każda funkcja ma listę argumentów, które pozwalają na ustawić poszczególne parametry (np. read_csv).
Zapis i eksport danych
Pandas pozwala w prosty sposób na zapisywanie ramki danych do pliku.
members = pd.Series({'May': 682758, 'June': 737011, 'July': 779511})
occasionals = pd.Series({'May': 147898, 'June': 171494, 'July': 194316})
df = pd.DataFrame({'members': members, 'occasionals': occasionals})
# zapis do formatu CSV
df.to_csv('tmp.csv')
# zapis do arkusza kalkulacyjnego
df.to_excel('tmp.xlsx')
Ponadto możemy przekonwertować ramkę danych do JSONa lub Pythonowego słownika:
print(df.to_json())
{"members":{"May":682758,"June":737011,"July":779511},"occasionals":{"May":147898,"June":171494,"July":194316}}
print(df.to_dict())
{'members': {'May': 682758, 'June': 737011, 'July': 779511}, 'occasionals': {'May': 147898, 'June': 171494, 'July': 194316}}
Lub przekopiować dane do schowka:
df.to_clipboard()
Zadanie
- Przekonwertuj tabele
Customer
z bazyChinook.sqlite
do arkusza kalkulacyjnego. Plik wynikowy nazwijcustomers.xlsx
. - Tabela
Employee
zawiera informacje o pracownikach firmy Chinook. Wyswietl dane na ekranie i podaj miasta, w których mieszkają pracownicy. - Tabela
Invoice
zawiera informacje o fakturach. Przekonwertuj kolumnęBillingCountry
do pythonowego słownika, a następnie podaj najcześciej występującą wartość. Ile razy pojawiła się?
Ramka danych - podstawy
Kolumny
Na ramkę danych możemy patrzeć jak na swego rodzaju słownik, którego wartościami są szeregi. Pozwoli to na uzyskanie lepszej intuicji.
df = pd.read_csv('./gapminder.csv', index_col='Country', nrows=8, usecols=['Country', 'gdp', 'population','life_expectancy'])
df
gdp | population | life_expectancy | |
---|---|---|---|
Country | |||
Afghanistan | 1311.0 | 26528741.0 | 52.8 |
Albania | 8644.0 | 2968026.0 | 76.8 |
Algeria | 12314.0 | 34811059.0 | 75.5 |
Angola | 7103.0 | 19842251.0 | 56.7 |
Antigua and Barbuda | 25736.0 | 85350.0 | 75.5 |
Argentina | 14646.0 | 40381860.0 | 75.4 |
Armenia | 7383.0 | 2975029.0 | 72.3 |
Australia | 41312.0 | 21370348.0 | 81.6 |
Dostęp do poszczególnej kolumny możemy uzystać na dwa sposoby:
# notacja z kropką
df.population
Country Afghanistan 26528741.0 Albania 2968026.0 Algeria 34811059.0 Angola 19842251.0 Antigua and Barbuda 85350.0 Argentina 40381860.0 Armenia 2975029.0 Australia 21370348.0 Name: population, dtype: float64
# Operator []
df['population']
Country Afghanistan 26528741.0 Albania 2968026.0 Algeria 34811059.0 Angola 19842251.0 Antigua and Barbuda 85350.0 Argentina 40381860.0 Armenia 2975029.0 Australia 21370348.0 Name: population, dtype: float64
Do operatora []
możemy też podać listę nazw kolumn:
df[['gdp','population']]
gdp | population | |
---|---|---|
Country | ||
Afghanistan | 1311.0 | 26528741.0 |
Albania | 8644.0 | 2968026.0 |
Algeria | 12314.0 | 34811059.0 |
Angola | 7103.0 | 19842251.0 |
Antigua and Barbuda | 25736.0 | 85350.0 |
Argentina | 14646.0 | 40381860.0 |
Armenia | 7383.0 | 2975029.0 |
Australia | 41312.0 | 21370348.0 |
Listę kolumn możemy pobrać za pomocą:
df.columns
Index(['gdp', 'population', 'life_expectancy'], dtype='object')
df.columns = ['PKB', 'Populacja', 'ODŻ']
df
PKB | Populacja | ODŻ | |
---|---|---|---|
Country | |||
Afghanistan | 1311.0 | 26528741.0 | 52.8 |
Albania | 8644.0 | 2968026.0 | 76.8 |
Algeria | 12314.0 | 34811059.0 | 75.5 |
Angola | 7103.0 | 19842251.0 | 56.7 |
Antigua and Barbuda | 25736.0 | 85350.0 | 75.5 |
Argentina | 14646.0 | 40381860.0 | 75.4 |
Armenia | 7383.0 | 2975029.0 | 72.3 |
Australia | 41312.0 | 21370348.0 | 81.6 |
Żeby odwołać się do poszczególnych wierszy należy wykorzystać metodę loc
:
df.loc['Argentina']
PKB 14646.0 Populacja 40381860.0 ODŻ 75.4 Name: Argentina, dtype: float64
Metoda loc
również może przyjąć listę wierszy:
df.loc[['Albania', 'Angola']]
PKB | Populacja | ODŻ | |
---|---|---|---|
Country | |||
Albania | 8644.0 | 2968026.0 | 76.8 |
Angola | 7103.0 | 19842251.0 | 56.7 |
Możemy również podać drugi parametr: nazwy kolumn:
df2 = df.loc[['Albania', 'Angola'], ['PKB', 'Populacja']]
df2
PKB | Populacja | |
---|---|---|
Country | ||
Albania | 8644.0 | 2968026.0 |
Angola | 7103.0 | 19842251.0 |
Albo wykorzystać tzw. _slicing, cyzli operator :
:
df.loc['Albania': 'Angola', 'PKB': 'ODŻ']
PKB | Populacja | ODŻ | |
---|---|---|---|
Country | |||
Albania | 8644.0 | 2968026.0 | 76.8 |
Algeria | 12314.0 | 34811059.0 | 75.5 |
Angola | 7103.0 | 19842251.0 | 56.7 |
Żeby odwołać się do pojedyńczej wartości możemy użyć metody at
:
df.at['Angola', 'PKB']
7103.0
Dostęp do indeksu:
df.index
Index(['Afghanistan', 'Albania', 'Algeria', 'Angola', 'Antigua and Barbuda', 'Argentina', 'Armenia', 'Australia'], dtype='object', name='Country')
Podstawowe metody pd.Series
i pd.DataFrame
members = pd.Series({'May': 682758, 'June': 737011, 'July': 779511, 'August': 673790,
'September': 673790, 'October': 444177})
occasionals = pd.Series({'May': 147898, 'June': 171494, 'July': 194316, 'August': 206809,
'September': 140492, 'October': 53596})
df = pd.DataFrame({'members': members, 'occasionals': occasionals})
df
members | occasionals | |
---|---|---|
May | 682758 | 147898 |
June | 737011 | 171494 |
July | 779511 | 194316 |
August | 673790 | 206809 |
September | 673790 | 140492 |
October | 444177 | 53596 |
Metoda head
pozwala tworzy nową ramkę danych z pierwszymi 5 przykładami:
df.head()
members | occasionals | |
---|---|---|
May | 682758 | 147898 |
June | 737011 | 171494 |
July | 779511 | 194316 |
August | 673790 | 206809 |
September | 673790 | 140492 |
Metoda tail
robi to samo, ale z 5 ostatnymi przykładami:
df.tail()
members | occasionals | |
---|---|---|
June | 737011 | 171494 |
July | 779511 | 194316 |
August | 673790 | 206809 |
September | 673790 | 140492 |
October | 444177 | 53596 |
Metoda sample
pozwala na stworzenie nowej ramki danych z wylosowanymi n
przykładami:
df.sample(3)
members | occasionals | |
---|---|---|
October | 444177 | 53596 |
June | 737011 | 171494 |
May | 682758 | 147898 |
Metoda describe
zwraca podstawowe statystyki m.in.: liczebność, średnią, wartości skrajne:
df.describe()
members | occasionals | |
---|---|---|
count | 6.000000 | 6.000000 |
mean | 665172.833333 | 152434.166667 |
std | 116216.045456 | 54783.506738 |
min | 444177.000000 | 53596.000000 |
25% | 673790.000000 | 142343.500000 |
50% | 678274.000000 | 159696.000000 |
75% | 723447.750000 | 188610.500000 |
max | 779511.000000 | 206809.000000 |
Metoda info
zwraca informacje techniczne o kolumnach: np. typ danych:
df.info()
<class 'pandas.core.frame.DataFrame'> Index: 6 entries, May to October Data columns (total 2 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 members 6 non-null int64 1 occasionals 6 non-null int64 dtypes: int64(2) memory usage: 144.0+ bytes
Podstawową informacją o ramce danych to liczba przykładów w ramce danych. Możemy wykorzystać to tego funkcję len
:
len(df)
6
Natomiast atrybut shape
zwraca nam krotkę z liczbą przykładów i liczbą kolumn:
df.shape
(6, 2)
Operacja arytmetyczne
max
,idxmax
min
,idxmin
mean
count
df.mean()
members 665172.833333 occasionals 152434.166667 dtype: float64
Zbiór wartości i zliczanie wartości:
dane = pd.Series([1, 3, 2, 3, 1, 1, 2, 3, 2, 3])
print(dane.unique())
dane = pd.Series([1, 3, 2, 3, 1, 1, 2, 3, 2, 3])
print(dane.value_counts())
[1 3 2] 3 4 1 3 2 3 dtype: int64
Sprawdzanie czy brakuje danych:
df = pd.read_csv('./titanic_train.tsv', sep='\t', index_col='PassengerId')
df.Age.isnull()
PassengerId 1 False 2 False 3 False 4 False 5 False ... 887 False 888 False 889 True 890 False 891 False Name: Age, Length: 891, dtype: bool
Dodawanie i modyfikowanie danych
df = pd.read_csv('./gapminder.csv', index_col='Country', nrows=5)
df
female_BMI | male_BMI | gdp | population | under5mortality | life_expectancy | fertility | |
---|---|---|---|---|---|---|---|
Country | |||||||
Afghanistan | 21.07402 | 20.62058 | 1311.0 | 26528741.0 | 110.4 | 52.8 | 6.20 |
Albania | 25.65726 | 26.44657 | 8644.0 | 2968026.0 | 17.9 | 76.8 | 1.76 |
Algeria | 26.36841 | 24.59620 | 12314.0 | 34811059.0 | 29.5 | 75.5 | 2.73 |
Angola | 23.48431 | 22.25083 | 7103.0 | 19842251.0 | 192.0 | 56.7 | 6.43 |
Antigua and Barbuda | 27.50545 | 25.76602 | 25736.0 | 85350.0 | 10.9 | 75.5 | 2.16 |
conts = pd.Series({
'Afghanistan': 'Asia', 'Albania': 'Europe', 'Algeria':' Africa', 'Angola': 'Africa', 'Antigua and Barbuda': 'Americas'})
df['continent'] = conts
df['tmp'] = 1
df
female_BMI | male_BMI | gdp | population | under5mortality | life_expectancy | fertility | continent | tmp | |
---|---|---|---|---|---|---|---|---|---|
Country | |||||||||
Afghanistan | 21.07402 | 20.62058 | 1311.0 | 26528741.0 | 110.4 | 52.8 | 6.20 | Asia | 1 |
Albania | 25.65726 | 26.44657 | 8644.0 | 2968026.0 | 17.9 | 76.8 | 1.76 | Europe | 1 |
Algeria | 26.36841 | 24.59620 | 12314.0 | 34811059.0 | 29.5 | 75.5 | 2.73 | Africa | 1 |
Angola | 23.48431 | 22.25083 | 7103.0 | 19842251.0 | 192.0 | 56.7 | 6.43 | Africa | 1 |
Antigua and Barbuda | 27.50545 | 25.76602 | 25736.0 | 85350.0 | 10.9 | 75.5 | 2.16 | Americas | 1 |
df.loc['Argentina'] = {
'female_BMI': 27.46523,
'male_BMI': 27.5017,
'gdp': 14646.0,
'population': 40381860.0,
'under5mortality': 15.4,
'life_expectancy': 75.4,
'fertility': 2.24
}
df
female_BMI | male_BMI | gdp | population | under5mortality | life_expectancy | fertility | continent | tmp | |
---|---|---|---|---|---|---|---|---|---|
Country | |||||||||
Afghanistan | 21.07402 | 20.62058 | 1311.0 | 26528741.0 | 110.4 | 52.8 | 6.20 | Asia | 1.0 |
Albania | 25.65726 | 26.44657 | 8644.0 | 2968026.0 | 17.9 | 76.8 | 1.76 | Europe | 1.0 |
Algeria | 26.36841 | 24.59620 | 12314.0 | 34811059.0 | 29.5 | 75.5 | 2.73 | Africa | 1.0 |
Angola | 23.48431 | 22.25083 | 7103.0 | 19842251.0 | 192.0 | 56.7 | 6.43 | Africa | 1.0 |
Antigua and Barbuda | 27.50545 | 25.76602 | 25736.0 | 85350.0 | 10.9 | 75.5 | 2.16 | Americas | 1.0 |
Argentina | 27.46523 | 27.50170 | 14646.0 | 40381860.0 | 15.4 | 75.4 | 2.24 | NaN | NaN |
df.drop('gdp', axis='columns')
female_BMI | male_BMI | population | under5mortality | life_expectancy | fertility | continent | tmp | |
---|---|---|---|---|---|---|---|---|
Country | ||||||||
Afghanistan | 21.07402 | 20.62058 | 26528741.0 | 110.4 | 52.8 | 6.20 | Asia | 1.0 |
Albania | 25.65726 | 26.44657 | 2968026.0 | 17.9 | 76.8 | 1.76 | Europe | 1.0 |
Algeria | 26.36841 | 24.59620 | 34811059.0 | 29.5 | 75.5 | 2.73 | Africa | 1.0 |
Angola | 23.48431 | 22.25083 | 19842251.0 | 192.0 | 56.7 | 6.43 | Africa | 1.0 |
Antigua and Barbuda | 27.50545 | 25.76602 | 85350.0 | 10.9 | 75.5 | 2.16 | Americas | 1.0 |
Argentina | 27.46523 | 27.50170 | 40381860.0 | 15.4 | 75.4 | 2.24 | NaN | NaN |
Filtrowanie danych
Biblioteka pandas posiada 2 sposoby na filtrowanie danych zawartych w ramce danych:
- operator
[]
-- najbardziej rozpowszechniony; - metoda
query()
. Oba sposoby mają różną składnię.
df = pd.read_csv('./titanic_train.tsv', sep='\t', index_col='PassengerId')
df.head()
Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|
PassengerId | |||||||||||
1 | 0 | 3 | Braund\t Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
2 | 1 | 1 | Cumings\t Mrs. John Bradley (Florence Briggs T... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
3 | 1 | 3 | Heikkinen\t Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S |
4 | 1 | 1 | Futrelle\t Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
5 | 0 | 3 | Allen\t Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S |
df['Survived']
PassengerId 1 0 2 1 3 1 4 1 5 0 .. 887 0 888 1 889 0 890 1 891 0 Name: Survived, Length: 891, dtype: int64
df['Survived'] == 1
PassengerId 1 False 2 True 3 True 4 True 5 False ... 887 False 888 True 889 False 890 True 891 False Name: Survived, Length: 891, dtype: bool
df[df['Pclass'] == 1]
Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|
PassengerId | |||||||||||
2 | 1 | 1 | Cumings\t Mrs. John Bradley (Florence Briggs T... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
4 | 1 | 1 | Futrelle\t Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
7 | 0 | 1 | McCarthy\t Mr. Timothy J | male | 54.0 | 0 | 0 | 17463 | 51.8625 | E46 | S |
12 | 1 | 1 | Bonnell\t Miss. Elizabeth | female | 58.0 | 0 | 0 | 113783 | 26.5500 | C103 | S |
24 | 1 | 1 | Sloper\t Mr. William Thompson | male | 28.0 | 0 | 0 | 113788 | 35.5000 | A6 | S |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
872 | 1 | 1 | Beckwith\t Mrs. Richard Leonard (Sallie Monypeny) | female | 47.0 | 1 | 1 | 11751 | 52.5542 | D35 | S |
873 | 0 | 1 | Carlsson\t Mr. Frans Olof | male | 33.0 | 0 | 0 | 695 | 5.0000 | B51 B53 B55 | S |
880 | 1 | 1 | Potter\t Mrs. Thomas Jr (Lily Alexenia Wilson) | female | 56.0 | 0 | 1 | 11767 | 83.1583 | C50 | C |
888 | 1 | 1 | Graham\t Miss. Margaret Edith | female | 19.0 | 0 | 0 | 112053 | 30.0000 | B42 | S |
890 | 1 | 1 | Behr\t Mr. Karl Howell | male | 26.0 | 0 | 0 | 111369 | 30.0000 | C148 | C |
216 rows × 11 columns
Operatory
&
- koniukcja (i)|
- alternatywa (lub)~
- negacja (nie)()
- jeżeli mamy kilka warunków to warto je uporządkować w nawiasy
pierwsza_klasa = df['Pclass'] == 1
kobiety = df['Sex'] == 'female'
df[pierwsza_klasa & kobiety]
Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|
PassengerId | |||||||||||
2 | 1 | 1 | Cumings\t Mrs. John Bradley (Florence Briggs T... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
4 | 1 | 1 | Futrelle\t Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
12 | 1 | 1 | Bonnell\t Miss. Elizabeth | female | 58.0 | 0 | 0 | 113783 | 26.5500 | C103 | S |
32 | 1 | 1 | Spencer\t Mrs. William Augustus (Marie Eugenie) | female | NaN | 1 | 0 | PC 17569 | 146.5208 | B78 | C |
53 | 1 | 1 | Harper\t Mrs. Henry Sleeper (Myna Haxtun) | female | 49.0 | 1 | 0 | PC 17572 | 76.7292 | D33 | C |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
857 | 1 | 1 | Wick\t Mrs. George Dennick (Mary Hitchcock) | female | 45.0 | 1 | 1 | 36928 | 164.8667 | NaN | S |
863 | 1 | 1 | Swift\t Mrs. Frederick Joel (Margaret Welles B... | female | 48.0 | 0 | 0 | 17466 | 25.9292 | D17 | S |
872 | 1 | 1 | Beckwith\t Mrs. Richard Leonard (Sallie Monypeny) | female | 47.0 | 1 | 1 | 11751 | 52.5542 | D35 | S |
880 | 1 | 1 | Potter\t Mrs. Thomas Jr (Lily Alexenia Wilson) | female | 56.0 | 0 | 1 | 11767 | 83.1583 | C50 | C |
888 | 1 | 1 | Graham\t Miss. Margaret Edith | female | 19.0 | 0 | 0 | 112053 | 30.0000 | B42 | S |
94 rows × 11 columns
df[df['SibSp'] > df['Parch']]
Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|
PassengerId | |||||||||||
1 | 0 | 3 | Braund\t Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
2 | 1 | 1 | Cumings\t Mrs. John Bradley (Florence Briggs T... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
4 | 1 | 1 | Futrelle\t Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
8 | 0 | 3 | Palsson\t Master. Gosta Leonard | male | 2.0 | 3 | 1 | 349909 | 21.0750 | NaN | S |
10 | 1 | 2 | Nasser\t Mrs. Nicholas (Adele Achem) | female | 14.0 | 1 | 0 | 237736 | 30.0708 | NaN | C |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
861 | 0 | 3 | Hansen\t Mr. Claus Peter | male | 41.0 | 2 | 0 | 350026 | 14.1083 | NaN | S |
862 | 0 | 2 | Giles\t Mr. Frederick Edward | male | 21.0 | 1 | 0 | 28134 | 11.5000 | NaN | S |
864 | 0 | 3 | Sage\t Miss. Dorothy Edith "Dolly" | female | NaN | 8 | 2 | CA. 2343 | 69.5500 | NaN | S |
867 | 1 | 2 | Duran y More\t Miss. Asuncion | female | 27.0 | 1 | 0 | SC/PARIS 2149 | 13.8583 | NaN | C |
875 | 1 | 2 | Abelson\t Mrs. Samuel (Hannah Wizosky) | female | 28.0 | 1 | 0 | P/PP 3381 | 24.0000 | NaN | C |
192 rows × 11 columns
pd.DataFrame.query
Innym sposobem na filtrowanie danych jest metoda query
, która jako argument przyjmuje wyrażenie:
df.query('Pclass == 1').head()
Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|
PassengerId | |||||||||||
2 | 1 | 1 | Cumings\t Mrs. John Bradley (Florence Briggs T... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
4 | 1 | 1 | Futrelle\t Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
7 | 0 | 1 | McCarthy\t Mr. Timothy J | male | 54.0 | 0 | 0 | 17463 | 51.8625 | E46 | S |
12 | 1 | 1 | Bonnell\t Miss. Elizabeth | female | 58.0 | 0 | 0 | 113783 | 26.5500 | C103 | S |
24 | 1 | 1 | Sloper\t Mr. William Thompson | male | 28.0 | 0 | 0 | 113788 | 35.5000 | A6 | S |
df.query('(Pclass == 1) and (Sex == "female")').head()
Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|
PassengerId | |||||||||||
2 | 1 | 1 | Cumings\t Mrs. John Bradley (Florence Briggs T... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
4 | 1 | 1 | Futrelle\t Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
12 | 1 | 1 | Bonnell\t Miss. Elizabeth | female | 58.0 | 0 | 0 | 113783 | 26.5500 | C103 | S |
32 | 1 | 1 | Spencer\t Mrs. William Augustus (Marie Eugenie) | female | NaN | 1 | 0 | PC 17569 | 146.5208 | B78 | C |
53 | 1 | 1 | Harper\t Mrs. Henry Sleeper (Myna Haxtun) | female | 49.0 | 1 | 0 | PC 17572 | 76.7292 | D33 | C |
df.query('SibSp > Parch')
Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|
PassengerId | |||||||||||
1 | 0 | 3 | Braund\t Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
2 | 1 | 1 | Cumings\t Mrs. John Bradley (Florence Briggs T... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
4 | 1 | 1 | Futrelle\t Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
8 | 0 | 3 | Palsson\t Master. Gosta Leonard | male | 2.0 | 3 | 1 | 349909 | 21.0750 | NaN | S |
10 | 1 | 2 | Nasser\t Mrs. Nicholas (Adele Achem) | female | 14.0 | 1 | 0 | 237736 | 30.0708 | NaN | C |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
861 | 0 | 3 | Hansen\t Mr. Claus Peter | male | 41.0 | 2 | 0 | 350026 | 14.1083 | NaN | S |
862 | 0 | 2 | Giles\t Mr. Frederick Edward | male | 21.0 | 1 | 0 | 28134 | 11.5000 | NaN | S |
864 | 0 | 3 | Sage\t Miss. Dorothy Edith "Dolly" | female | NaN | 8 | 2 | CA. 2343 | 69.5500 | NaN | S |
867 | 1 | 2 | Duran y More\t Miss. Asuncion | female | 27.0 | 1 | 0 | SC/PARIS 2149 | 13.8583 | NaN | C |
875 | 1 | 2 | Abelson\t Mrs. Samuel (Hannah Wizosky) | female | 28.0 | 1 | 0 | P/PP 3381 | 24.0000 | NaN | C |
192 rows × 11 columns
young = 18
df.query('Age < @young').shape
(113, 11)
Zadanie
Operacje na wierszach i kolumnach
df = pd.read_csv('./gapminder.csv', index_col='Country', nrows=5)
df
female_BMI | male_BMI | gdp | population | under5mortality | life_expectancy | fertility | |
---|---|---|---|---|---|---|---|
Country | |||||||
Afghanistan | 21.07402 | 20.62058 | 1311.0 | 26528741.0 | 110.4 | 52.8 | 6.20 |
Albania | 25.65726 | 26.44657 | 8644.0 | 2968026.0 | 17.9 | 76.8 | 1.76 |
Algeria | 26.36841 | 24.59620 | 12314.0 | 34811059.0 | 29.5 | 75.5 | 2.73 |
Angola | 23.48431 | 22.25083 | 7103.0 | 19842251.0 | 192.0 | 56.7 | 6.43 |
Antigua and Barbuda | 27.50545 | 25.76602 | 25736.0 | 85350.0 | 10.9 | 75.5 | 2.16 |
Iterowanie po ramce danych oznacza oznacza przejście po nazwach kolumn:
for column_name in df:
print(column_name)
female_BMI male_BMI gdp population under5mortality life_expectancy fertility
for col_name, series in df.items():
print(col_name, series)
break
female_BMI Country Afghanistan 21.07402 Albania 25.65726 Algeria 26.36841 Angola 23.48431 Antigua and Barbuda 27.50545 Name: female_BMI, dtype: float64
for idx, row in df.iterrows():
print(idx, '\n', row)
break
Afghanistan female_BMI 2.107402e+01 male_BMI 2.062058e+01 gdp 1.311000e+03 population 2.652874e+07 under5mortality 1.104000e+02 life_expectancy 5.280000e+01 fertility 6.200000e+00 Name: Afghanistan, dtype: float64
def bmi_level(bmi):
if bmi <= 18.5:
level = 'underweight'
elif bmi < 25:
level = 'normal'
elif bmi < 30:
level = 'overweight'
else:
level = 'obese'
return level
s = df['male_BMI'].map(bmi_level)
s
Country Afghanistan normal Albania overweight Algeria normal Angola normal Antigua and Barbuda overweight Name: male_BMI, dtype: object
def bmi_level(row_data):
bmi = row_data['male_BMI']
if bmi <= 18.5:
return 'underweight'
elif bmi < 25:
return 'normal'
elif bmi < 30:
return 'overweight'
return 'obese'
df.apply(bmi_level, axis=1)
Country Afghanistan normal Albania overweight Algeria normal Angola normal Antigua and Barbuda overweight dtype: object
df.transpose()
Country | Afghanistan | Albania | Algeria | Angola | Antigua and Barbuda |
---|---|---|---|---|---|
female_BMI | 2.107402e+01 | 2.565726e+01 | 2.636841e+01 | 2.348431e+01 | 27.50545 |
male_BMI | 2.062058e+01 | 2.644657e+01 | 2.459620e+01 | 2.225083e+01 | 25.76602 |
gdp | 1.311000e+03 | 8.644000e+03 | 1.231400e+04 | 7.103000e+03 | 25736.00000 |
population | 2.652874e+07 | 2.968026e+06 | 3.481106e+07 | 1.984225e+07 | 85350.00000 |
under5mortality | 1.104000e+02 | 1.790000e+01 | 2.950000e+01 | 1.920000e+02 | 10.90000 |
life_expectancy | 5.280000e+01 | 7.680000e+01 | 7.550000e+01 | 5.670000e+01 | 75.50000 |
fertility | 6.200000e+00 | 1.760000e+00 | 2.730000e+00 | 6.430000e+00 | 2.16000 |
Zadanie
Grupowanie (groupby
)
Często zdarza się, gdy potrzebujemy podzielić dane ze względu na wartości w zadanej kolumnie, a następnie obliczenie zebranie danych w każdej z grup. Do tego służy metody groupby
.
import pandas as pd
df = pd.read_csv('./nba.csv')
df.sample(5)
Name | Team | Number | Position | Age | Height | Weight | College | Salary | |
---|---|---|---|---|---|---|---|---|---|
401 | Tyus Jones | Minnesota Timberwolves | 1.0 | PG | 20.0 | 6-2 | 195.0 | Duke | 1282080.0 |
342 | Gerald Green | Miami Heat | 14.0 | SF | 30.0 | 6-7 | 205.0 | NaN | 947276.0 |
143 | DeMarcus Cousins | Sacramento Kings | 15.0 | C | 25.0 | 6-11 | 270.0 | Kentucky | 15851950.0 |
267 | P.J. Hairston | Memphis Grizzlies | 19.0 | SF | 23.0 | 6-6 | 230.0 | North Carolina | 1201440.0 |
335 | Jeremy Lin | Charlotte Hornets | 7.0 | PG | 27.0 | 6-3 | 200.0 | Harvard | 2139000.0 |
_Przykład: chcemy obliczyć średnią wypłatę dla każdej z drużyn.
df[['Team', 'Salary']].groupby('Team').mean().head()
Salary | |
---|---|
Team | |
Atlanta Hawks | 4.860197e+06 |
Boston Celtics | 4.181505e+06 |
Brooklyn Nets | 3.501898e+06 |
Charlotte Hornets | 5.222728e+06 |
Chicago Bulls | 5.785559e+06 |
Możemy też podać listę nazw kolumn. Wtedy wartości zostaną obliczone dla każdej z wytworzonych grup:
df.groupby(['Team', 'Position'])['Salary'].mean()
Team Position Atlanta Hawks C 7.585417e+06 PF 5.988067e+06 PG 4.881700e+06 SF 3.000000e+06 SG 2.607758e+06 ... Washington Wizards C 8.163476e+06 PF 5.650000e+06 PG 9.011208e+06 SF 2.789700e+06 SG 2.839248e+06 Name: Salary, Length: 149, dtype: float64
sum()
min()
max()
mean()
size()
describe()
first()
last()
count()
std()
var()
sem()
df[['Position', 'Salary']].groupby('Position').agg(['mean', 'std', 'count'])
Salary | |||
---|---|---|---|
mean | std | count | |
Position | |||
C | 5.967052e+06 | 5.787989e+06 | 78 |
PF | 4.562483e+06 | 4.800054e+06 | 97 |
PG | 5.077829e+06 | 5.051809e+06 | 88 |
SF | 4.857393e+06 | 6.011889e+06 | 84 |
SG | 4.009861e+06 | 4.491609e+06 | 99 |
def group_range(x):
return x.max() - x.min()
df[['Position', 'Salary']].groupby('Position').apply(group_range)
Salary | |
---|---|
Position | |
C | 22275967.0 |
PF | 22081286.0 |
PG | 21412973.0 |
SF | 24969112.0 |
SG | 19944278.0 |
gb = df.groupby(['Position'])
print('Liczba grup:', gb.ngroups)
print(gb.groups.keys())
print(gb.get_group('C').head())
Liczba grup: 5 dict_keys(['C', 'PF', 'PG', 'SF', 'SG']) Name Team Number Position Age Height Weight \ 7 Kelly Olynyk Boston Celtics 41.0 C 25.0 7-0 238.0 10 Jared Sullinger Boston Celtics 7.0 C 24.0 6-9 260.0 14 Tyler Zeller Boston Celtics 44.0 C 26.0 7-0 253.0 23 Brook Lopez Brooklyn Nets 11.0 C 28.0 7-0 275.0 27 Henry Sims Brooklyn Nets 14.0 C 26.0 6-10 248.0 College Salary 7 Gonzaga 2165160.0 10 Ohio State 2569260.0 14 North Carolina 2616975.0 23 Stanford 19689000.0 27 Georgetown 947276.0
df.Height.str.split('-').str[0].astype('Int64') * 2.56
0 15.36 1 15.36 2 15.36 3 15.36 4 15.36 ... 453 15.36 454 15.36 455 17.92 456 17.92 457 <NA> Name: Height, Length: 458, dtype: Float64
Pivot
Metoda pivot
pozwala na stworzenie nowej ramki danych, gdzie indeks i nazwy kolumn są wartościami początkowej ranki danych.
_Przykład: zobaczmy na poniższą ramkę danych, która zawiera informacje o jakości tłumaczenia dla pary językowej hausa-angielski. Kolumna system
zawiera nazwę systemu, kolumna metric
- nazwę metryki, zaś kolumna score
- wartość metryki. Chcemy przedstawić te dane w następujący sposób: jako klucz chcemy mieć nazwę systemu, zaś jako kolumny - metryki. Możemy wykorzystać do tego metodę pivot
, gdzie musimy podać 3 argumenty:
index
: nazwę kolumny, na podstawie której zostanie stworzony indeks;columns
: nazwa kolumny, które zawiera nazwy kolumn dla nowej ramki danych;values
: nazwa kolumny, która zawiera interesujące nas dane.
df = pd.read_csv('https://raw.githubusercontent.com/wmt-conference/wmt21-news-systems/main/scores/automatic-scores.tsv', sep='\t')
df = df[df.pair == 'ha-en']
df
pair | system | id | is_constrained | metric | score | |
---|---|---|---|---|---|---|
1214 | ha-en | NiuTrans | 382 | True | bleu-all | 16.512243 |
1215 | ha-en | NiuTrans | 382 | True | chrf-all | 44.724766 |
1216 | ha-en | NiuTrans | 382 | True | bleu-A | 16.512243 |
1217 | ha-en | NiuTrans | 382 | True | chrf-A | 44.724766 |
1218 | ha-en | Facebook-AI | 181 | False | bleu-all | 20.982704 |
1219 | ha-en | Facebook-AI | 181 | False | chrf-all | 48.653770 |
1220 | ha-en | Facebook-AI | 181 | False | bleu-A | 20.982704 |
1221 | ha-en | Facebook-AI | 181 | False | chrf-A | 48.653770 |
1222 | ha-en | TRANSSION | 336 | False | bleu-all | 18.834851 |
1223 | ha-en | TRANSSION | 336 | False | chrf-all | 47.238279 |
1224 | ha-en | TRANSSION | 336 | False | bleu-A | 18.834851 |
1225 | ha-en | TRANSSION | 336 | False | chrf-A | 47.238279 |
1226 | ha-en | AMU | 628 | True | bleu-all | 14.132845 |
1227 | ha-en | AMU | 628 | True | chrf-all | 41.256570 |
1228 | ha-en | AMU | 628 | True | bleu-A | 14.132845 |
1229 | ha-en | AMU | 628 | True | chrf-A | 41.256570 |
1230 | ha-en | P3AI | 715 | True | bleu-all | 17.793617 |
1231 | ha-en | P3AI | 715 | True | chrf-all | 46.307402 |
1232 | ha-en | P3AI | 715 | True | bleu-A | 17.793617 |
1233 | ha-en | P3AI | 715 | True | chrf-A | 46.307402 |
1234 | ha-en | Online-B | 1356 | False | bleu-all | 18.655658 |
1235 | ha-en | Online-B | 1356 | False | chrf-all | 46.658216 |
1236 | ha-en | Online-B | 1356 | False | bleu-A | 18.655658 |
1237 | ha-en | Online-B | 1356 | False | chrf-A | 46.658216 |
1238 | ha-en | TWB | 1335 | False | bleu-all | 12.326443 |
1239 | ha-en | TWB | 1335 | False | chrf-all | 40.282629 |
1240 | ha-en | TWB | 1335 | False | bleu-A | 12.326443 |
1241 | ha-en | TWB | 1335 | False | chrf-A | 40.282629 |
1242 | ha-en | ZMT | 553 | False | bleu-all | 18.837023 |
1243 | ha-en | ZMT | 553 | False | chrf-all | 47.231474 |
1244 | ha-en | ZMT | 553 | False | bleu-A | 18.837023 |
1245 | ha-en | ZMT | 553 | False | chrf-A | 47.231474 |
1246 | ha-en | Manifold | 437 | True | bleu-all | 16.943915 |
1247 | ha-en | Manifold | 437 | True | chrf-all | 45.638356 |
1248 | ha-en | Manifold | 437 | True | bleu-A | 16.943915 |
1249 | ha-en | Manifold | 437 | True | chrf-A | 45.638356 |
1250 | ha-en | Online-Y | 1374 | False | bleu-all | 13.898531 |
1251 | ha-en | Online-Y | 1374 | False | chrf-all | 44.842874 |
1252 | ha-en | Online-Y | 1374 | False | bleu-A | 13.898531 |
1253 | ha-en | Online-Y | 1374 | False | chrf-A | 44.842874 |
1254 | ha-en | HuaweiTSC | 758 | True | bleu-all | 17.492440 |
1255 | ha-en | HuaweiTSC | 758 | True | chrf-all | 46.795737 |
1256 | ha-en | HuaweiTSC | 758 | True | bleu-A | 17.492440 |
1257 | ha-en | HuaweiTSC | 758 | True | chrf-A | 46.795737 |
1258 | ha-en | MS-EgDC | 896 | True | bleu-all | 17.133350 |
1259 | ha-en | MS-EgDC | 896 | True | chrf-all | 45.266274 |
1260 | ha-en | MS-EgDC | 896 | True | bleu-A | 17.133350 |
1261 | ha-en | MS-EgDC | 896 | True | chrf-A | 45.266274 |
1262 | ha-en | GTCOM | 1298 | False | bleu-all | 17.794272 |
1263 | ha-en | GTCOM | 1298 | False | chrf-all | 46.714831 |
1264 | ha-en | GTCOM | 1298 | False | bleu-A | 17.794272 |
1265 | ha-en | GTCOM | 1298 | False | chrf-A | 46.714831 |
1266 | ha-en | UEdin | 1149 | True | bleu-all | 14.887836 |
1267 | ha-en | UEdin | 1149 | True | chrf-all | 42.247415 |
1268 | ha-en | UEdin | 1149 | True | bleu-A | 14.887836 |
1269 | ha-en | UEdin | 1149 | True | chrf-A | 42.247415 |
df.pivot(index='system', columns='metric', values='score')
metric | bleu-A | bleu-all | chrf-A | chrf-all |
---|---|---|---|---|
system | ||||
AMU | 14.132845 | 14.132845 | 41.256570 | 41.256570 |
Facebook-AI | 20.982704 | 20.982704 | 48.653770 | 48.653770 |
GTCOM | 17.794272 | 17.794272 | 46.714831 | 46.714831 |
HuaweiTSC | 17.492440 | 17.492440 | 46.795737 | 46.795737 |
MS-EgDC | 17.133350 | 17.133350 | 45.266274 | 45.266274 |
Manifold | 16.943915 | 16.943915 | 45.638356 | 45.638356 |
NiuTrans | 16.512243 | 16.512243 | 44.724766 | 44.724766 |
Online-B | 18.655658 | 18.655658 | 46.658216 | 46.658216 |
Online-Y | 13.898531 | 13.898531 | 44.842874 | 44.842874 |
P3AI | 17.793617 | 17.793617 | 46.307402 | 46.307402 |
TRANSSION | 18.834851 | 18.834851 | 47.238279 | 47.238279 |
TWB | 12.326443 | 12.326443 | 40.282629 | 40.282629 |
UEdin | 14.887836 | 14.887836 | 42.247415 | 42.247415 |
ZMT | 18.837023 | 18.837023 | 47.231474 | 47.231474 |
Zadanie
Dane tekstowe
pandas
posiada udogodnienia do pracy z wartościami tekstowymi:
- dostęp następuje przez atrybut
str
; - funkcje:
- formatujące:
lower()
,upper()
; - wyrażenia regularne:
contains()
,match()
; - inne:
split()
- formatujące:
df = pd.read_csv('./titanic_train.tsv', sep='\t', index_col='PassengerId')
df.head()
Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|
PassengerId | |||||||||||
1 | 0 | 3 | Braund\t Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
2 | 1 | 1 | Cumings\t Mrs. John Bradley (Florence Briggs T... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
3 | 1 | 3 | Heikkinen\t Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S |
4 | 1 | 1 | Futrelle\t Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
5 | 0 | 3 | Allen\t Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S |
df.Name.str.upper()
PassengerId 1 BRAUND\t MR. OWEN HARRIS 2 CUMINGS\t MRS. JOHN BRADLEY (FLORENCE BRIGGS T... 3 HEIKKINEN\t MISS. LAINA 4 FUTRELLE\t MRS. JACQUES HEATH (LILY MAY PEEL) 5 ALLEN\t MR. WILLIAM HENRY ... 887 MONTVILA\t REV. JUOZAS 888 GRAHAM\t MISS. MARGARET EDITH 889 JOHNSTON\t MISS. CATHERINE HELEN "CARRIE" 890 BEHR\t MR. KARL HOWELL 891 DOOLEY\t MR. PATRICK Name: Name, Length: 891, dtype: object
print(df.Name.head())
df.Name.str.contains('Miss|Mrs').head()
PassengerId 1 Braund\t Mr. Owen Harris 2 Cumings\t Mrs. John Bradley (Florence Briggs T... 3 Heikkinen\t Miss. Laina 4 Futrelle\t Mrs. Jacques Heath (Lily May Peel) 5 Allen\t Mr. William Henry Name: Name, dtype: object
PassengerId 1 False 2 True 3 True 4 True 5 False Name: Name, dtype: bool
df.Name.str.split('\t', expand=True)
0 | 1 | |
---|---|---|
PassengerId | ||
1 | Braund | Mr. Owen Harris |
2 | Cumings | Mrs. John Bradley (Florence Briggs Thayer) |
3 | Heikkinen | Miss. Laina |
4 | Futrelle | Mrs. Jacques Heath (Lily May Peel) |
5 | Allen | Mr. William Henry |
... | ... | ... |
887 | Montvila | Rev. Juozas |
888 | Graham | Miss. Margaret Edith |
889 | Johnston | Miss. Catherine Helen "Carrie" |
890 | Behr | Mr. Karl Howell |
891 | Dooley | Mr. Patrick |
891 rows × 2 columns
df.Name.str.split('\t')
PassengerId 1 [Braund, Mr. Owen Harris] 2 [Cumings, Mrs. John Bradley (Florence Briggs ... 3 [Heikkinen, Miss. Laina] 4 [Futrelle, Mrs. Jacques Heath (Lily May Peel)] 5 [Allen, Mr. William Henry] ... 887 [Montvila, Rev. Juozas] 888 [Graham, Miss. Margaret Edith] 889 [Johnston, Miss. Catherine Helen "Carrie"] 890 [Behr, Mr. Karl Howell] 891 [Dooley, Mr. Patrick] Name: Name, Length: 891, dtype: object
df.Name.str.split('\t').str[1]
PassengerId 1 Mr. Owen Harris 2 Mrs. John Bradley (Florence Briggs Thayer) 3 Miss. Laina 4 Mrs. Jacques Heath (Lily May Peel) 5 Mr. William Henry ... 887 Rev. Juozas 888 Miss. Margaret Edith 889 Miss. Catherine Helen "Carrie" 890 Mr. Karl Howell 891 Mr. Patrick Name: Name, Length: 891, dtype: object
df.Name.str.split('\t').str[1].str.strip().str.split(' ').str[0]
PassengerId 1 Mr. 2 Mrs. 3 Miss. 4 Mrs. 5 Mr. ... 887 Rev. 888 Miss. 889 Miss. 890 Mr. 891 Mr. Name: Name, Length: 891, dtype: object
Zadanie
Zestaw nba.csv
zawiera informaję o wysokości zawodników. Oblicz wzrost każdego z zawodników w systemie metrycznym przyjmując, że stop to 30.48
cm., a cal to 2.54
cm.