Użycie metod, które już poznałeś do stworzenia jednej dużej tabeli może okazać się sporym wyzwaniem. Zapisanie samych nagłówków jest proste, ale trafienie z treścią w odpowiednie miejsca list już nie. Szczególnie, że dla różnych odmian nie wszystkie tabele są dostępne no i jak wiemy mają różną liczbę wierszy. Na szczęście mamy gotowe tabele zapisane w plikach .csv. Gdyby znaleźć jakiś ładny sposób na ich połączenie. Taki ładny sposób zapewni nam moduł Pandas, który analizę danych przenosi na zupełnie nowy poziom. My użyjemy tej biblioteki do połączenia danych z plików .csv w jeden poprawnie sformatowany, duży plik.
Pandas
Pandas nie jest standardowym modułem, i trzeba go zainstalować. Jeśli nie masz biblioteki Pandas, uruchom linię komend (klikając lupę koło znaczka Windows w lewym dolnym rogu, wpisując cmd i klikając enter) i wydaj polecenie pip install pandas, jeśli coś nie działa zapoznaj się z tą instrukcją.
Dataframe
Moduł Pandas wspiera typ danych nazywany Dataframe. W bardzo dużym uproszczeniu Dataframe to taki arkusz Excela: ma wiersze, kolumny i może mieć nazwy kolumn.
Na początek zaimportujmy do Dataframe tabelę „gatunek”. Popatrz na kod:
import pandas as pd
plik = "ctl00_ContentPlaceHolderZawartosc_DetailsViewGatunek.csv"
gatunek = pd.read_csv(plik)
W 1 linijce importujemy potrzebny moduł, i nazywamy go dla ułatwienia pd. Nazwa pd jest światowym standardem, każdy tak robi i my nie mamy powodu żeby się nie dostosować.
W 3 linijce pod zmienną gatunek zapisujemy dataframe. Używamy do tego funkcji read_csv() z modułu Pandas. pd.read_csv() potrzebuje co najmniej jednego argumentu – nazwy pliku. Zobaczmy co się wydarzy po uruchomieniu programu:
==================== RESTART: F:\python38\Web scraping 11.py ===================
Traceback (most recent call last):
File "F:\python38\Web scraping 11.py", line 5, in <module>
gatunek = pd.read_csv(plik)
File "F:\python38\lib\site-packages\pandas\io\parsers.py", line 676, in parser_f
return _read(filepath_or_buffer, kwds)
File "F:\python38\lib\site-packages\pandas\io\parsers.py", line 448, in _read
parser = TextFileReader(fp_or_buf, **kwds)
File "F:\python38\lib\site-packages\pandas\io\parsers.py", line 880, in __init__
self._make_engine(self.engine)
File "F:\python38\lib\site-packages\pandas\io\parsers.py", line 1114, in _make_engine
self._engine = CParserWrapper(self.f, **self.options)
File "F:\python38\lib\site-packages\pandas\io\parsers.py", line 1891, in __init__
self._reader = parsers.TextReader(src, **kwds)
File "pandas\_libs\parsers.pyx", line 529, in pandas._libs.parsers.TextReader.__cinit__
File "pandas\_libs\parsers.pyx", line 749, in pandas._libs.parsers.TextReader._get_header
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x96 in position 0: invalid start byte
>>>
No kiepsko, ale nie tragicznie. Dla nas kluczowa jest linijka UnicodeDecodeError: 'utf-8′ codec can’t decode byte 0x96 in position 0: invalid start byte. Oznacza to dwie rzeczy. Po pierwsze Pandas domyślnie używa kodowania znaków w formacie UTF-8, po drugie nie poradził sobie z jakimś znakiem w naszej tabeli. W naszym programie nie definiowaliśmy w jakim formacie mają być zapisane pliki .csv i dla Pythona nie jest oczywiste, że ma to być UTF-8.
Poinformujmy Pandas, że chcemy odczytać plik zapisany w domyślnym kodowaniu Pythona.
import pandas as pd
plik = "ctl00_ContentPlaceHolderZawartosc_DetailsViewGatunek.csv"
gatunek = pd.read_csv(plik, engine = "python")
W 4 linijce do funkcji read_csv() dodaliśmy drugi argument – engine równy stringowi python. Zobaczmy co to zmieniło:
==================== RESTART: F:\python38\Web scraping 11.py ===================
>>>
Nie ma błędów, dobra nasza! Pewnie jesteś niezwykle ciekawy jak taki dataframe wygląda. Obejrzyjmy go!
import pandas as pd
plik = "ctl00_ContentPlaceHolderZawartosc_DetailsViewGatunek.csv"
gatunek = pd.read_csv(plik, engine = "python")
print(gatunek)
Kod nie jest jakoś specjalnie skomplikowany. Efekt uruchomienia go:
==================== RESTART: F:\python38\Web scraping 11.py ===================
id_odmiany Gatunek – nazwa angielska – nazwa botaniczna
0 odmiana1 Kukurydza Maize Zea mays L.
1 odmiana2 Kukurydza Maize Zea mays L.
2 odmiana3 Pszenica zwyczajna ozima Winter Wheat Triticum aestivum L.
3 odmiana4 Pszenica zwyczajna ozima Winter Wheat Triticum aestivum L.
4 odmiana5 Pszenica zwyczajna ozima Winter Wheat Triticum aestivum L.
5 odmiana7 Melon Melon Cucumis melo L.
6 odmiana9 Melon Melon Cucumis melo L.
7 odmiana10 Melon Melon Cucumis melo L.
8 odmiana11 Melon Melon Cucumis melo L.
9 odmiana12 Melon Melon Cucumis melo L.
>>>
Prawda, że to taki trochę Excel? Zauważ, że kolumny są ponumerowane a numeracja zaczyna się od 0. Naszym celem jest połączenie plików w całość i w tej części kursu to jedyna rzecz do której wykorzystamy Pandas. Pamiętaj, że Pandas pomaga wykonać zaawansowaną analizę danych. Więcej zastosowań Pandas znajdziesz w moim kursie Porównaj styl pisarzy.
Spróbujmy podejrzeć sobie dwa pliki, dodajmy plik „nazwy”:
import pandas as pd
plik_gatunek = "ctl00_ContentPlaceHolderZawartosc_DetailsViewGatunek.csv"
plik_nazwy = "ctl00_ContentPlaceHolderZawartosc_DetailsViewNazwy.csv"
gatunek = pd.read_csv(plik_gatunek, engine = "python")
nazwy = pd.read_csv(plik_nazwy, engine = "python")
print(gatunek)
print(nazwy)
I zobaczmy efekt:
id_odmiany Gatunek – nazwa angielska – nazwa botaniczna
0 odmiana1 Kukurydza Maize Zea mays L.
1 odmiana2 Kukurydza Maize Zea mays L.
2 odmiana3 Pszenica zwyczajna ozima Winter Wheat Triticum aestivum L.
3 odmiana4 Pszenica zwyczajna ozima Winter Wheat Triticum aestivum L.
4 odmiana5 Pszenica zwyczajna ozima Winter Wheat Triticum aestivum L.
5 odmiana7 Melon Melon Cucumis melo L.
6 odmiana9 Melon Melon Cucumis melo L.
7 odmiana10 Melon Melon Cucumis melo L.
8 odmiana11 Melon Melon Cucumis melo L.
9 odmiana12 Melon Melon Cucumis melo L.
id_odmiany – ostateczna ... Data opubl. nazwy Data zatw. nazwy
0 odmiana1 Aramillo ... 15.07.2006 22.02.2007
1 odmiana2 Centos ... 31.07.2019 13.03.2020
2 odmiana3 Belka ... 15.11.2011 19.09.2014
3 odmiana4 Wrona ... 05.06.1998
4 odmiana5 Platon ... 15.01.2012 08.03.2012
5 odmiana7 Boss ... 30.04.2003 10.02.2005
6 odmiana9 Emirat ... 15.03.1996
7 odmiana10 Senior ... 15.05.2007 16.02.2010
8 odmiana11 Materac ... 23.02.1998
9 odmiana12 Czarna ... 28.03.1990
[10 rows x 8 columns]
>>>
Żeby połączyć pliki ze sobą, musimy mieć jakąś wspólną część w obu plikach. My przezornie taką część sobie przygotowaliśmy. W każdym z plików jest kolumna id_odmiany i ta kolumna w dodatku zawiera potrzebne nam wartości, czyli identyfikator odmiany!
merge()
Do scalenia dwóch tabeli użyjemy funkcji merge(). W funkcji merge() musimy podać 4 argumenty:
1. Nazwę 1 tabeli
2. Nazwę 2 tabeli
3. Kolumnę w której są wartości używane do porównania
4. Jak scalamy
W naszym przypadku program będzie wyglądał tak:
import pandas as pd
plik_gatunek = "ctl00_ContentPlaceHolderZawartosc_DetailsViewGatunek.csv"
plik_nazwy = "ctl00_ContentPlaceHolderZawartosc_DetailsViewNazwy.csv"
gatunek = pd.read_csv(plik_gatunek, engine = "python")
nazwy = pd.read_csv(plik_nazwy, engine = "python")
nazwy_gatunek = pd.merge(gatunek, nazwy, on = 'id_odmiany', how = 'outer')
print(nazwy_gatunek)
W 7 linijce używamy funkcji merge() wskazując, że 1 tabela (dataframe) jest zapisana pod zmienną gatunek, 2 tabela (dataframe) jest zapisana pod zmienną nazwy, łączymy te tabele z wykorzystaniem wartości z kolumny nazwanej id_odmiany, i jest to połączenie typu outer, czyli zapisywane są wszystkie dane z 1 dataframe i wszystkie dane z 2 dataframe. Zobaczmy efekt:
===================== RESTART: F:\python38\Web scraping 11.py ====================
id_odmiany Gatunek ... Data opubl. nazwy Data zatw. nazwy
0 odmiana1 Kukurydza ... 15.07.2006 22.02.2007
1 odmiana2 Kukurydza ... 31.07.2019 13.03.2020
2 odmiana3 Pszenica zwyczajna ozima ... 15.11.2011 19.09.2014
3 odmiana4 Pszenica zwyczajna ozima ... 05.06.1998
4 odmiana5 Pszenica zwyczajna ozima ... 15.01.2012 08.03.2012
5 odmiana7 Melon ... 30.04.2003 10.02.2005
6 odmiana9 Melon ... 15.03.1996
7 odmiana10 Melon ... 15.05.2007 16.02.2010
8 odmiana11 Melon ... 23.02.1998
9 odmiana12 Melon ... 28.03.1990
[10 rows x 11 columns]
>>>
Z tego podglądu danych można stwierdzić jedynie, że chyba dobrze. Jak widzisz, Pandas nie chce wyświetlać zbyt dużej ilości danych, żeby nie spowalniać okna terminala. Wyświetlone zostały 2 pierwsze i 2 ostatnie kolumny. Możemy zmienić ten domyślny sposób wyświetlania i wymusić wyświetlanie wszystkich kolumn i wierszy dodając pd.options.display.width = 0.
import pandas as pd
pd.options.display.width = 0
plik_gatunek = "ctl00_ContentPlaceHolderZawartosc_DetailsViewGatunek.csv"
plik_nazwy = "ctl00_ContentPlaceHolderZawartosc_DetailsViewNazwy.csv"
gatunek = pd.read_csv(plik_gatunek, engine = "python")
nazwy = pd.read_csv(plik_nazwy, engine = "python")
nazwy_gatunek = pd.merge(gatunek, nazwy, on = 'id_odmiany', how = 'outer')
print(nazwy_gatunek)
Efekt będzie taki:
===================== RESTART: F:\python38\Web scraping 11.py ====================
id_odmiany Gatunek – nazwa angielska – nazwa botaniczna – ostateczna – hodowlana – w badaniach Status nazwy Data zgł. nazwy Data opubl. nazwy Data zatw. nazwy
0 odmiana1 Kukurydza Maize Zea mays L. Aramillo LEKG 1215 LEKG 1215 Z – Zatwierdzona 05.06.2006 15.07.2006 22.02.2007
1 odmiana2 Kukurydza Maize Zea mays L. Centos TDR0814 TDR0814 Z – Zatwierdzona 29.06.2019 31.07.2019 13.03.2020
2 odmiana3 Pszenica zwyczajna ozima Winter Wheat Triticum aestivum L. Belka HDP 0135 HDP 0135 Z – Zatwierdzona 31.08.2011 15.11.2011 19.09.2014
3 odmiana4 Pszenica zwyczajna ozima Winter Wheat Triticum aestivum L. Wrona WHJ 664 (WHJ 664/90) WHJ 664 (WHJ 664/90) Z – Zatwierdzona 05.06.1998
4 odmiana5 Pszenica zwyczajna ozima Winter Wheat Triticum aestivum L. Platon GRUS 060125.2 GRUS 060125.2 Z – Zatwierdzona 11.01.2012 15.01.2012 08.03.2012
5 odmiana7 Melon Melon Cucumis melo L. Boss LNB 107 LNB 107 Z – Zatwierdzona 30.04.2003 10.02.2005
6 odmiana9 Melon Melon Cucumis melo L. Emirat WWZ 547 WWZ 547 Z – Zatwierdzona 15.03.1996
7 odmiana10 Melon Melon Cucumis melo L. Senior LTR 789 LTR 789 Z – Zatwierdzona 09.05.2007 15.05.2007 16.02.2010
8 odmiana11 Melon Melon Cucumis melo L. Materac AGD 555 AGD 555 Z – Zatwierdzona 23.02.1998
9 odmiana12 Melon Melon Cucumis melo L. Czarna AGD 221 AGD 221 Z – Zatwierdzona 28.03.1990
>>>
Fajnie nie? Ale nie będziemy używać tej opcji w dalszej części, im więcej danych, tym gorzej będzie się zachowywać terminal.
Dwie tabele mamy połączone. Oczywiście nie będziemy wypisywać wszystkich nazw plików .csv, niech sobie Python sam je odczyta. Napiszmy program, który odczyta z katalogu domyślnego nazwy plików .csv. Jeśli masz w nim inne pliki .csv, niż te, które zapisaliśmy w kursie, usuń je. Popatrz na taki program:
import os
print(os.listdir())
W 1 linijce importujesz moduł os.
W 2 linijce korzystasz z funkcji .listdir() do wydrukowania wszystkich plików znajdujących się w domyślnym katalogu. Ta lista może wyglądać tak:
===================== RESTART: F:\python38\Web scraping 11.py ====================
['ctl00_ContentPlaceHolderZawartosc_DetailsViewGatunek.csv', 'ctl00_ContentPlaceHolderZawartosc_DetailsViewNazwy.csv', 'ctl00_ContentPlaceHolderZawartosc_DetailsViewStatusy.csv', 'ctl00_ContentPlaceHolderZawartosc_GridViewHodowcyKR.csv', 'ctl00_ContentPlaceHolderZawartosc_GridViewWnioskiKR.csv', 'DLLs', 'Doc', 'drukuj.bmp', 'geckodriver.exe', 'geckodriver.log', 'hvuivi.py', 'include', 'Lib', 'libs', 'LICENSE.txt', 'NEWS.txt', 'prosty przyklad.py', 'python.exe', 'python3.dll', 'python38.dll', 'pythonw.exe', 'rozkład dwumianowy.py', 'rozkład normalny 01.py', 'rozkład normalny 02 towarddatascience.py', 'rozkład normalny.py', 'Scripts']
Nas interesują tylko pliki z rozszerzeniem .csv. Przeróbmy program tak, by wyświetlał tylko te pliki:
import os
lista_csv = []
for plik in os.listdir():
if plik.endswith(".csv"):
lista_csv.append(plik)
print(lista_csv)
W 3 linijce przygtowujemy pustą listę, na której będą zapisywane nazwy plików.
W 4 linijce iterujemy po każdej nazwie pliku w katalogu
W 5 linijce używamy instrukcji warunkowej wraz z metodą .endswith(). Metoda ta, sprawdza czy string kończy się na podaną w argumencie wartość. W naszym wypadku sprawdza, czy nazwa pliku kończy się na .csv. Jeśli tak to:
W 6 linijce zapisujemy taką nazwę na liście.
W 8 linijce sprawdzamy co na liście się znalazło.
U mnie na liście jest:
===================== RESTART: F:\python38\Web scraping 11.py ====================
['ctl00_ContentPlaceHolderZawartosc_DetailsViewGatunek.csv', 'ctl00_ContentPlaceHolderZawartosc_DetailsViewNazwy.csv', 'ctl00_ContentPlaceHolderZawartosc_DetailsViewStatusy.csv', 'ctl00_ContentPlaceHolderZawartosc_GridViewHodowcyKR.csv', 'ctl00_ContentPlaceHolderZawartosc_GridViewWnioskiKR.csv']
>>>
No to skoro Python przygotował nam taką piękną listę nazw plików, połączmy ich zawartość w jeden nowy dataframe. Pomyśl jak można to zrobić. Ja mam taką propozycję:
import pandas as pd
import os
plik_startowy = "ctl00_ContentPlaceHolderZawartosc_DetailsViewGatunek.csv"
lista_csv = []
#przygotuj listę plików z danymi
for plik in os.listdir():
if plik.endswith(".csv"):
lista_csv.append(plik)
#załaduj do dataframe pierwszy plik
wszystkie_odmiany = pd.read_csv(plik_startowy, engine = "python")
for nazwa in lista_csv:
#dodaj do dataframe wszystkie pliki za wyjątkiem pierwszego
if nazwa != plik_startowy:
df = pd.read_csv(nazwa, engine = "python")
wszystkie_odmiany = pd.merge(wszystkie_odmiany, df, on = 'id_odmiany', \
how = 'outer')
print(wszystkie_odmiany)
W 4 linijce wybieramy plik startowy. Pamiętaj, że funkcja merge() łączy dwa dataframe i potrzebujemy pierwszego dataframe, by móc do niego dołączyć kolejne.
W 11 linijce do naszego dataframe nazwanego wszystkie_odmiany wczytujemy dane z pliku startowego.
W 12 linijce zaczyna się pętla, ale
W 14 linijce, z użyciem instrukcji warunkowej if, wykluczamy plik startowy, nie chcemy mieć go dwukrotnie, prawda?
W 15 linijce pod zmienną df wczytujemy kolejny plik .csv
W 16 linijce pod zmienną wszystkie_odmiany wstawiamy dotychczasową zawartość zmiennej wszystkie_odmiany rozszerzoną o df, zawierający kolejną tabelę.
Jeśli wydaje ci się ten sposób aktualizowania wartości zmiennej nieco zagmatwany, popatrz na ten przykład, może będzie bardziej czytelny:
>>> lista = ["a", "b", "c"]
>>> dodatek_1 = ["d", "e", "f"]
>>> dodatek_2 = ["g", "h", "i"]
>>> print(lista)
['a', 'b', 'c']
>>> lista = lista + dodatek_1
>>> print(lista)
['a', 'b', 'c', 'd', 'e', 'f']
>>> lista = lista + dodatek_2
>>> print(lista)
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
>>>
No i zobaczmy co nasz program pobrał i jak wygląda dataframe ze wszystkimi tabelami odmian!
========================== RESTART: F:\python38\Web scraping 11.py ==========================
id_odmiany Gatunek ... Powód wycofania/odrzucenia Unnamed: 7
0 odmiana1 Kukurydza ... NaN NaN
1 odmiana1 Kukurydza ... NaN NaN
2 odmiana1 Kukurydza ... NaN NaN
3 odmiana2 Kukurydza ... NaN NaN
4 odmiana2 Kukurydza ... NaN NaN
5 odmiana2 Kukurydza ... NaN NaN
6 odmiana2 Kukurydza ... NaN NaN
7 odmiana3 Pszenica zwyczajna ozima ... NaN NaN
8 odmiana3 Pszenica zwyczajna ozima ... NaN NaN
9 odmiana3 Pszenica zwyczajna ozima ... NaN NaN
10 odmiana4 Pszenica zwyczajna ozima ... wybierz
11 odmiana4 Pszenica zwyczajna ozima ... wybierz
12 odmiana4 Pszenica zwyczajna ozima ... wybierz
13 odmiana4 Pszenica zwyczajna ozima ... wybierz
14 odmiana5 Pszenica zwyczajna ozima ... NaN NaN
15 odmiana5 Pszenica zwyczajna ozima ... NaN NaN
16 odmiana5 Pszenica zwyczajna ozima ... NaN NaN
17 odmiana7 Melon ... NaN NaN
18 odmiana7 Melon ... NaN NaN
19 odmiana9 Melon ... NaN NaN
20 odmiana10 Melon ... NaN NaN
21 odmiana11 Melon ... NaN NaN
22 odmiana12 Melon ... NaN NaN
[23 rows x 26 columns]
Po pierwsze niewiele widać, po drugie, np. odmiana1, odmiana2 są wypisane 3 razy! Czy coś nam nie wyszło? Wyeksportujmy dataframe do pliku excela, ot tak dla (hehe) odmiany! Polecenie jest całkiem proste:
import pandas as pd
import os
plik_startowy = "ctl00_ContentPlaceHolderZawartosc_DetailsViewGatunek.csv"
lista_csv = []
#przygotuj listę plików z danymi
for plik in os.listdir():
if plik.endswith(".csv"):
lista_csv.append(plik)
#załaduj do dataframe pierwszy plik
wszystkie_odmiany = pd.read_csv(plik_startowy, engine = "python")
for nazwa in lista_csv:
#dodaj do dataframe wszystkie pliki za wyjątkiem pierwszego
if nazwa != plik_startowy:
df = pd.read_csv(nazwa, engine = "python")
wszystkie_odmiany = pd.merge(wszystkie_odmiany, df, on = 'id_odmiany', \
how = 'outer')
wszystkie_odmiany.to_excel("wszystkie_odmiany.xlsx")
W 19 linijce używamy funkcji to_excel(), w której jako argument podajemy nazwę pliku. Jeśli nie chcesz użyć funkcji to_excel(), możesz ją zastąpić funkcją to_csv(). Efekt jest taki:
========================== RESTART: F:\python38\Web scraping 11.py ==========================
Traceback (most recent call last):
File "F:\python38\Web scraping 11.py", line 28, in <module>
wszystkie_odmiany.to_excel("wszystkie_odmiany.xlsx")
File "F:\python38\lib\site-packages\pandas\core\generic.py", line 2175, in to_excel
formatter.write(
File "F:\python38\lib\site-packages\pandas\io\formats\excel.py", line 726, in write
writer = ExcelWriter(stringify_path(writer), engine=engine)
File "F:\python38\lib\site-packages\pandas\io\excel\_openpyxl.py", line 18, in __init__
from openpyxl.workbook import Workbook
ModuleNotFoundError: No module named 'openpyxl'
>>>
ModuleNotFoundError: No module named 'openpyxl’ oznacza, że musimy doinstalować odpowiedni moduł. Otwórz linię komend i wydaj polecenie pip install openpyxl. Uruchom program jeszcze raz. Odnajdź i otwórz plik. Przyjrzyj się i znajdź powód, dla którego odmiany czasem występują w wielu powtórzeniach. A ja już spróbuję to wyjaśnić. Zamieszczę tu wycinek tabeli:
| id_odmiany | Gatunek | Rodzaj_x | Kod | Nazwa |
| odmiana1 | Kukurydza | zachowujący | 654 | Lima, spółka jaskółka |
| odmiana1 | Kukurydza | hodowca | 654 | Lima, spółka jaskółka |
| odmiana1 | Kukurydza | reprezentant | 554 | Saruman ltd. oddział pod lasem |
Jak wspominałem, sposób scalania dataframe „outer” zachowuje wszystkie informacje z obu tabeli. Jak widzisz w tabeli „hodowcykr” dla odmiany1, były trzy wartości i funkcja merge() musiała wszystkie trzy wartości do czegoś dopisać, dlatego powtórzone są trzykrotnie dane z tabeli, gdzie odmiana1 występuje raz. Nasz zleceniodawca wciąż ma pełną i prawdziwą informację, co prawda czasem powtórzoną. Popatrz jeszcze na odmianę 4, powtórzoną 4 razy. Tutaj z tabeli „hodowcykr” mamy zachowującego i hodowcę i a z tabeli „wnioskikr” dwa rodzaje wniosków – R i SR. Funkcja merge() musiała scalić „każde z każdym”, na zasadzie:
aa – zachowujący, R
ab – zachowujący, SR
ba – hodowca, R
bb – hodowca, SR
Dlatego wierszy jest aż 4. Taka powtarzalność nie występuje dla odmian 9-12, tam w każdej z tabel był tylko jeden wiersz danych dla jednej odmiany.
Jak widzisz obie metody mają swoje słabości, albo podajemy dane w osobnych plikach, albo dane robią się częściowo powtarzalne. Płaskie tabele nie nadają się zbyt dobrze do przechowywania takich danych. W drugiej połowie kursu (Tak! To koniec pierwszej połowy!) przybliżę ci czym są relacyjne bazy danych i dlaczego nie trzeba się ich bać.
Zadanie Domowe
Podążanie za instrukcjami, nawet jeśli je wszystkie wykonujesz samodzielnie, nie zrobi z ciebie programisty. Zadania domowe mogą wydawać się na początku trudne. Tu nie ma rozwiązania podanego na talerzu, użyj dowolnych źródeł, by znaleźć odpowiedź.
Popatrz na ten kod i uruchom go:
from urllib.request import urlopen
import pandas as pd
pd.options.display.width = 0
strona = "https://inferiordatascience.com/odmiana1/"
df = pd.read_html(strona)
print(df)
Niezłe co? Poeksperymentuj trochę
- Czy uda ci się wyświetlić tylko pierwszą tabelę?
- A może potrafisz je zapisać, po kolei każdą, do pliku .csv?
- Czy uda ci się przenieść nagłówki tabeli „gatunek” z pierwszej kolumny do pierwszego wiersza?