07 - Biblioteka `pandas` cz. 3: ćwiczenia
Wczytanie danych i podstawowe informacje o ramce i danych
Przejdź na stronę https://www.ncbi.nlm.nih.gov/genome/browse#!/organelles/. Znajdziesz tam tabele zawierającą informację na temat sekwencji genomów plastydów i mitochondriów zdeponowanych w bazie GenBank.
Na górze kolumny znajdziesz przycisk Choose Columns
, kliknij go.
Usuń kolumny: Strain
, BioSample
oraz BioProject
.
Dodaj kolumny: Genes
i Pseudogene
.
Następnie pobierz dane (przycisk Download
) i zapisz w katalogu, w którym będziesz uruchamiać kod.
Domyślna nazwa to organelles.csv
.
Jeśli nie uda się pobrać danych z powyższej strony, możesz pobrać dane tutaj. Nie są to dane aktualne, ale są odpowiednie do wykonania ćwiczeń.
Otwórz plik w edytorze tekstu. Przyjrzyj się, jak zapisane są w nim dane:
Organism Name,Organism Groups,Size(Mb),GC%,Type,Replicons,CDS,Release Date,Genes,Pseudogene
"Aacanthocnema dobsoni","Eukaryota;Animals;Insects",0.015179,21.9382,"mitochondrion","NC_038132.1/MG989216.1",13,"2018-07-31T00:00:00Z",37,0
"Abacion magnum","Eukaryota;Animals;Other Animals",0.01516,33.4037,"mitochondrion","NC_021932.1/JX437062.1",13,"2013-08-06T00:00:00Z",35,0..
Pierwsza linia, poprzedzona znakiem #
(jeśli dane zostały pobrane ze strony NCBI) zawiera nagłówki.
W kolejnych zapisane są dane, poprzedzielane przecinkami. Jest to znany nam format zapisu danych csv
.
Ciągi znaków, które nie są zapisem liczb, są ujęte w pary cudzysłowów.
Usuń znak #
z początku pierwszego rzędu, jeśli tam się znajduje i zapisz plik.
Wczytajmy dane:
import pandas as pd
# Wczytanie danych z pliku csv
dane = pd.read_csv('organelles.csv')
Uzyskajmy kilka podstawowych informacji na temat wczytanych danych.
Zwłaszcza w przypadku dużych ramek, gdy chcemy podejrzeć ich zawartość, wykorzystujemy metodę head()
:
# Początek ramki
print(f'Początek ramki:\n{dane.head()}')
Początek ramki:
Organism Name Organism Groups Size(Mb) GC% \
0 Aacanthocnema dobsoni Eukaryota;Animals;Insects 0.015179 21.9382
1 Abacion magnum Eukaryota;Animals;Other Animals 0.015160 33.4037
2 Abalistes stellaris Eukaryota;Animals;Fishes 0.016502 44.4189
3 Abax parallelepipedus Eukaryota;Animals;Insects 0.017701 20.7446
4 Abbottina binhi Eukaryota;Animals;Fishes 0.016609 44.1387
Type Replicons CDS Release Date Genes \
0 mitochondrion NC_038132.1/MG989216.1 13 2018-07-31T00:00:00Z 37
1 mitochondrion NC_021932.1/JX437062.1 13 2013-08-06T00:00:00Z 35
2 mitochondrion NC_011943.1/AP009202.1 13 2009-01-22T00:00:00Z 13
3 mitochondrion NC_030592.1/KT876877.1 13 2016-07-12T00:00:00Z 37
4 mitochondrion NC_048988.1/MK852688.1 13 2020-06-28T00:00:00Z 37
Pseudogene
0 0
1 0
2 0
3 0
4 0
Uwaga: Wyświetlone dane, zwłaszcza liczbowe, do których przejdziemy za chwilę, będą się w mniejszym lub większym stopniu różnić od tych, które przedstawiam. Różnice wynikają z tego, że dane które pobrałeś są już inne, z pewnością znacznie większe niż te, które pobrałem tworząc tę lekcję (wiosna 2021 r.).
Można podać argument, determinujący liczbę zwracanych rzędów:
print(f'Początek ramki:\n{dane.head(2)}')
Początek ramki:
Organism Name Organism Groups Size(Mb) GC% \
0 Aacanthocnema dobsoni Eukaryota;Animals;Insects 0.015179 21.9382
1 Abacion magnum Eukaryota;Animals;Other Animals 0.015160 33.4037
Type Replicons CDS Release Date Genes \
0 mitochondrion NC_038132.1/MG989216.1 13 2018-07-31T00:00:00Z 37
1 mitochondrion NC_021932.1/JX437062.1 13 2013-08-06T00:00:00Z 35
Pseudogene
0 0
1 0
Jak widać, nazwy kolumn zostały pobrane z pierwszego rzędu pliku. Podobnie można sprawdzić, jak kończy się ramka:
# Koniec ramki
print(f'Koniec ramki:\n{dane.tail()}')
Koniec ramki:
Organism Name Organism Groups \
18807 Zygophyllum xanthoxylon Eukaryota;Plants;Land Plants
18808 Zygosaccharomyces mellis Y-12628 Eukaryota;Fungi;Ascomycetes
18809 Zygosaccharomyces parabailii ATCC 60483 Eukaryota;Fungi;Ascomycetes
18810 Zygotorulaspora mrakii NRRL Y-6702 Eukaryota;Fungi;Ascomycetes
18811 Zymoseptoria tritici Eukaryota;Fungi;Ascomycetes
Size(Mb) GC% Type Replicons CDS \
18807 0.109577 33.7717 chloroplast NC_052769.1/MT796492.1 69
18808 0.024335 20.3123 mitochondrion NC_036374.1/KU920675.1 14
18809 0.029945 26.6088 mitochondrion MT:CP019506.1 13
18810 0.037644 18.8184 mitochondrion MT:NW_023500906.1/CP058612.1 0
18811 0.043964 31.9352 mitochondrion NC_010222.1/EU090238.1 22
Release Date Genes Pseudogene
18807 2021-02-09T00:00:00Z 111 4
18808 2017-12-18T00:00:00Z 40 0
18809 2017-02-03T00:00:00Z 35 0
18810 2020-10-28T00:00:00Z 0 0
18811 2008-01-03T00:00:00Z 43 0
Sprawdźmy, jaki jest typ obiektu, w którym zostały umieszczone dane:
# Typ obiektu dane
print(f'Typ obiektu dane: {type(dane)}')
Typ obiektu dane: <class 'pandas.core.frame.DataFrame'>
Nie powinno być zaskoczeniem, że otrzymaliśmy ramkę danych. Teraz sprawdźmy rozmiary ramki:
# Rozmiar ramki
print(f'Rozmiary ramki: {dane.shape}, rzędów: {dane.shape[0]}, kolumn: {dane.shape[1]}')
Rozmiary ramki: (18812, 10), rzędów: 18812, kolumn: 10
Atrybut columns
pozwala pobrać nazwy kolumn:
# Nazwy kolumn
print(f'Kolumny: {dane.columns}')
Kolumny: Index(['Organism Name', 'Organism Groups', 'Size(Mb)', 'GC%', 'Type',
'Replicons', 'CDS', 'Release Date', 'Genes', 'Pseudogene'],
dtype='object')
Możemy też uzyskać dane na temat indeksów:
# Dane na temat indeksów
print(f'Indeksy: {dane.index}')
Indeksy: RangeIndex(start=0, stop=18812, step=1)
Typy danych przechowywanych w kolumnach można pobrać z atrybutu dtypes
:
# Typy danych w kolumnach:
print(dane.dtypes)
Organism Name object
Organism Groups object
Size(Mb) float64
GC% float64
Type object
Replicons object
CDS int64
Release Date object
Genes int64
Pseudogene int64
dtype: object
Liczebność kolumn każdego z typów pobieramy wywołując metodę value_counts()
:
# Liczebność kolumn określonych typów:
print(dane.dtypes.value_counts())
object 5
int64 3
float64 2
dtype: int64
Metoda info()
także pokazuje powyższe informacje:
# Informacje o ramce:
print(dane.info())
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 18812 entries, 0 to 18811
Data columns (total 10 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Organism Name 18812 non-null object
1 Organism Groups 18812 non-null object
2 Size(Mb) 18812 non-null float64
3 GC% 18812 non-null float64
4 Type 18812 non-null object
5 Replicons 18812 non-null object
6 CDS 18812 non-null int64
7 Release Date 18812 non-null object
8 Genes 18812 non-null int64
9 Pseudogene 18812 non-null int64
dtypes: float64(2), int64(3), object(5)
memory usage: 1.4+ MB
None
Podstawową statystykę danych przechowywanych w kolumnach możemy uzyskać używając metody describe()
:
print(dane.describe())
Size(Mb) GC% CDS Genes Pseudogene
count 18812.000000 18812.000000 18812.000000 18812.000000 18812.000000
mean 0.074621 35.933209 39.307357 64.014671 0.520785
std 0.361654 7.864528 78.848303 87.199607 1.979815
min 0.001136 8.385160 0.000000 0.000000 0.000000
25% 0.016449 31.952150 13.000000 13.000000 0.000000
50% 0.017100 37.432350 13.000000 37.000000 0.000000
75% 0.151548 41.049400 83.000000 129.000000 0.000000
max 41.196000 68.015600 9230.000000 9230.000000 81.000000
Transpozycja może poprawić czytelność wyników:
print(dane.describe().T)
count mean std min 25% 50% \
Size(Mb) 18812.0 0.074621 0.361654 0.001136 0.016449 0.01710
GC% 18812.0 35.933209 7.864528 8.385160 31.952150 37.43235
CDS 18812.0 39.307357 78.848303 0.000000 13.000000 13.00000
Genes 18812.0 64.014671 87.199607 0.000000 13.000000 37.00000
Pseudogene 18812.0 0.520785 1.979815 0.000000 0.000000 0.00000
75% max
Size(Mb) 0.151548 41.1960
GC% 41.049400 68.0156
CDS 83.000000 9230.0000
Genes 129.000000 9230.0000
Pseudogene 0.000000 81.0000
Metoda describe()
przyjmuje argumenty, które pozwalają np. pobrać dane określonego typu.
print(dane.describe(include=object).T)
count unique top freq
Organism Name 18812 18185 Plasmodium falciparum 27
Organism Groups 18812 19 Eukaryota;Plants;Land Plants 6227
Type 18812 7 mitochondrion 12312
Replicons 18812 18807 NC_016668.1/ 2
Release Date 18812 1401 2020-04-26T00:00:00Z 310
- Przy danych o wartościach typu
int64
musimy zaimportowaćnumpy
.
import numpy as np
print(dane.describe(include=np.int64).T)
count mean std min 25% 50% 75% max
CDS 18812.0 39.307357 78.848303 0.0 13.0 13.0 83.0 9230.0
Genes 18812.0 64.014671 87.199607 0.0 13.0 37.0 129.0 9230.0
Pseudogene 18812.0 0.520785 1.979815 0.0 0.0 0.0 0.0 81.0
Można podać kilka typów w formie listy, choć w podanym niżej przykładzie nie ma to większego sensu, ponieważ jak widać wyżej, dla danych liczbowych i typu object
, są prezentowane inne wyniki:
print(dane.describe(include=[object,np.int64]).T)
count unique top freq mean \
Organism Name 18812 18185 Plasmodium falciparum 27 NaN
Organism Groups 18812 19 Eukaryota;Plants;Land Plants 6227 NaN
Type 18812 7 mitochondrion 12312 NaN
Replicons 18812 18807 NC_016668.1/ 2 NaN
CDS 18812 NaN NaN NaN 39.3074
Release Date 18812 1401 2020-04-26T00:00:00Z 310 NaN
Genes 18812 NaN NaN NaN 64.0147
Pseudogene 18812 NaN NaN NaN 0.520785
std min 25% 50% 75% max
Organism Name NaN NaN NaN NaN NaN NaN
Organism Groups NaN NaN NaN NaN NaN NaN
Type NaN NaN NaN NaN NaN NaN
Replicons NaN NaN NaN NaN NaN NaN
CDS 78.8483 0 13 13 83 9230
Release Date NaN NaN NaN NaN NaN NaN
Genes 87.1996 0 13 37 129 9230
Pseudogene 1.97982 0 0 0 0 81
Jeśli potrzebujemy nadać etykiety indeksom wierszy, można to zrobić za pomocą metody set_index()
, która zwraca zmienioną kopię ramki:
kopia = dane.set_index(['Organism Name'])
print(kopia.head(3))
Organism Groups Size(Mb) GC% \
Organism Name
Aacanthocnema dobsoni Eukaryota;Animals;Insects 0.015179 21.9382
Abacion magnum Eukaryota;Animals;Other Animals 0.015160 33.4037
Abalistes stellaris Eukaryota;Animals;Fishes 0.016502 44.4189
Type Replicons CDS \
Organism Name
Aacanthocnema dobsoni mitochondrion NC_038132.1/MG989216.1 13
Abacion magnum mitochondrion NC_021932.1/JX437062.1 13
Abalistes stellaris mitochondrion NC_011943.1/AP009202.1 13
Release Date Genes Pseudogene
Organism Name
Aacanthocnema dobsoni 2018-07-31T00:00:00Z 37 0
Abacion magnum 2013-08-06T00:00:00Z 35 0
Abalistes stellaris 2009-01-22T00:00:00Z 13 0
Jak widać, wartości z kolumny Organism Name
stały się etykietami dla poszczególnych wierszy, a kolumna została usunięta.
Można to zmienić ustawiając odpowiedni parametr:
kopia = dane.set_index(['Organism Name'], drop=False )
print(kopia.head(3))
Organism Name Organism Groups \
Organism Name
Aacanthocnema dobsoni Aacanthocnema dobsoni Eukaryota;Animals;Insects
Abacion magnum Abacion magnum Eukaryota;Animals;Other Animals
Abalistes stellaris Abalistes stellaris Eukaryota;Animals;Fishes
Size(Mb) GC% Type \
Organism Name
Aacanthocnema dobsoni 0.015179 21.9382 mitochondrion
Abacion magnum 0.015160 33.4037 mitochondrion
Abalistes stellaris 0.016502 44.4189 mitochondrion
Replicons CDS Release Date \
Organism Name
Aacanthocnema dobsoni NC_038132.1/MG989216.1 13 2018-07-31T00:00:00Z
Abacion magnum NC_021932.1/JX437062.1 13 2013-08-06T00:00:00Z
Abalistes stellaris NC_011943.1/AP009202.1 13 2009-01-22T00:00:00Z
Genes Pseudogene
Organism Name
Aacanthocnema dobsoni 37 0
Abacion magnum 35 0
Abalistes stellaris 13 0
Odwrotne działanie, czyli przywrócenie kolumny z indeksu, przeprowadzamy z użyciem metody reset_index()
:
kopia = dane.set_index(['Organism Name'])
kopia_kopii = kopia.reset_index()
print(kopia_kopii.head())
Organism Name Organism Groups Size(Mb) GC% \
0 Aacanthocnema dobsoni Eukaryota;Animals;Insects 0.015179 21.9382
1 Abacion magnum Eukaryota;Animals;Other Animals 0.015160 33.4037
2 Abalistes stellaris Eukaryota;Animals;Fishes 0.016502 44.4189
3 Abax parallelepipedus Eukaryota;Animals;Insects 0.017701 20.7446
4 Abbottina binhi Eukaryota;Animals;Fishes 0.016609 44.1387
Type Replicons CDS Release Date Genes \
0 mitochondrion NC_038132.1/MG989216.1 13 2018-07-31T00:00:00Z 37
1 mitochondrion NC_021932.1/JX437062.1 13 2013-08-06T00:00:00Z 35
2 mitochondrion NC_011943.1/AP009202.1 13 2009-01-22T00:00:00Z 13
3 mitochondrion NC_030592.1/KT876877.1 13 2016-07-12T00:00:00Z 37
4 mitochondrion NC_048988.1/MK852688.1 13 2020-06-28T00:00:00Z 37
Pseudogene
0 0
1 0
2 0
3 0
4 0
Selekcja danych i dalsza analiza
Popracujmy dalej z danymi, jeśli to potrzebne importując je:
import pandas as pd
# Wczytanie danych z pliku csv
dane = pd.read_csv('organelles.csv')
Pobierzmy dane dotyczące organelli dla których zostały opublikowane genomy:
organelle = dane['Type']
print(organelle)
0 mitochondrion
1 mitochondrion
2 mitochondrion
3 mitochondrion
4 mitochondrion
...
18807 chloroplast
18808 mitochondrion
18809 mitochondrion
18810 mitochondrion
18811 mitochondrion
Name: Type, Length: 18812, dtype: object
Teraz znajdźmy wartości unikalne w kolumnie, pozwoli to sprawdzić dla jakich organelli mamy dane (albo raczej jak zostały opisane).
print(organelle.unique())
['mitochondrion' 'chloroplast' 'plastid' 'apicoplast' 'kinetoplast'
'cyanelle' 'chromatophore']
Sprawdźmy, ile jest poszczególnych wartości:
print(organelle.value_counts())
mitochondrion 12312
chloroplast 5379
plastid 1054
apicoplast 61
kinetoplast 3
chromatophore 2
cyanelle 1
Name: Type, dtype: int64
Metoda isin()
pozwala na selekcję danych na podstawie przyrównania do elementów listy.
Pobierzmy zatem dane dla plastydów i chloroplastów, aby uzyskać wszystkie dane dla plastydów (chloroplast to forma plastydu):
plastydy = dane[dane['Type'].isin(['chloroplast','plastid'])]
print(plastydy.describe())
Size(Mb) GC% CDS Genes Pseudogene
count 6433.000000 6433.000000 6433.000000 6433.000000 6433.000000
mean 0.151713 36.992838 85.896782 130.748173 1.410539
std 0.028342 2.533923 23.787675 26.311608 2.849150
min 0.011348 20.462500 0.000000 0.000000 0.000000
25% 0.149227 36.492900 83.000000 129.000000 0.000000
50% 0.155021 37.350000 85.000000 131.000000 0.000000
75% 0.159230 38.131000 87.000000 133.000000 2.000000
max 1.352310 57.664000 863.000000 912.000000 40.000000
Obiekt zwracany przez metodę isin()
to ramka danych, podobnie zresztą do obiektu zwracanego przez metodę describe()
, co zresztą możemy łatwo sprawdzić:
plastydy_stat = plastydy.describe()
print(f'Typ zwracany przez isin() : {type(plastydy)}')
print(f'Typ zwracany przez describe(): {type(plastydy_stat)}')
Typ zwracany przez isin() : <class 'pandas.core.frame.DataFrame'>)
Typ zwracany przez describe(): <class 'pandas.core.frame.DataFrame'>)
Możemy zatem łatwo pobrać wybrane wartości, korzystając ze sposobów poznanych poprzednio:
print(f"Średnia długość genomu (Mb): \
{round(plastydy_stat.loc['mean','Size(Mb)'], 2)}")
print(f"Wartość minimalna rozmiaru genomu (Mb): \
{round(plastydy_stat.loc['min','Size(Mb)'], 2)}")
print(f"Wartość maksymalna liczby genów: \
{plastydy_stat.loc['max','Genes']}")
Średnia długość genomu (Mb): 0.15
Wartość minimalna rozmiaru genomu (Mb): 0.01
Wartość maksymalna liczby genów: 912.0
Sprawdźmy, dla jakich organizmów jest w bazie najwięcej danych:
organizmy = dane['Organism Name']
print(organizmy.value_counts().head(10))
Plasmodium falciparum 27
Homo sapiens 23
Enteromyxum leei 8
Solanum lycopersicum 8
Clathrina clathrus 6
Canis lupus familiaris 5
Glycine max 4
Rhododendron simsii 4
Chenopodium quinoa 4
Gossypium raimondii 4
Name: Organism Name, dtype: int64
Jak widać, najwięcej danych mamy dla Plasmodium falciparum, jest to zarodziec sierpowaty, wywołujący malarię. Ciekawe, dla jakich organelli, ile genomów zostało zbadanych:
zarodziec_sierpowaty = dane[dane['Organism Name'] == 'Plasmodium falciparum']
print(zarodziec_sierpowaty['Type'].value_counts())
mitochondrion 14
apicoplast 13
Name: Type, dtype: int64
Sprawdźmy teraz jakie właściwie grupy organizmów mamy w naszej ramce:
print(dane['Organism Groups'].unique())
['Eukaryota;Animals;Insects' 'Eukaryota;Animals;Other Animals'
'Eukaryota;Animals;Fishes' 'Eukaryota;Plants;Land Plants'
'Eukaryota;Animals;Reptiles' 'Eukaryota;Fungi;Other Fungi'
'Eukaryota;Protists;Other Protists' 'Eukaryota;Animals;Birds'
'Eukaryota;Other;Other' 'Eukaryota;Animals;Roundworms'
'Eukaryota;Animals;Mammals' 'Eukaryota;Fungi;Ascomycetes'
'Eukaryota;Fungi;Basidiomycetes' 'Eukaryota;Animals;Flatworms'
'Eukaryota;Animals;Amphibians' 'Eukaryota;Plants;Green Algae'
'Eukaryota;Protists;Apicomplexans' 'Eukaryota;Plants;Other Plants'
'Eukaryota;Protists;Kinetoplasts']
Użyjemy teraz atrybutu str
dostępnego dla obiektów Series
.
Posiada on przypisany obiekt StringMethod
, który z kolei udostępnia metody przydatne do pracy z łańcuchami znaków.
Część z nich odpowiada tym, które poznaliśmy w pierwszej części kursu przy omawianiu pracy z łańcuchami.
Poniżej kilka przykładów:
grupy = dane['Organism Groups']
print(f'Typ: {type(grupy)}')
Typ: <class 'pandas.core.series.Series'>
print(grupy.str.upper().head())
0 EUKARYOTA;ANIMALS;INSECTS
1 EUKARYOTA;ANIMALS;OTHER ANIMALS
2 EUKARYOTA;ANIMALS;FISHES
3 EUKARYOTA;ANIMALS;INSECTS
4 EUKARYOTA;ANIMALS;FISHES
Name: Organism Groups, dtype: object
print(grupy.str.lower().head())
0 eukaryota;animals;insects
1 eukaryota;animals;other animals
2 eukaryota;animals;fishes
3 eukaryota;animals;insects
4 eukaryota;animals;fishes
Name: Organism Groups, dtype: object
print(grupy.str.replace('a','@').head())
0 Euk@ryot@;Anim@ls;Insects
1 Euk@ryot@;Anim@ls;Other Anim@ls
2 Euk@ryot@;Anim@ls;Fishes
3 Euk@ryot@;Anim@ls;Insects
4 Euk@ryot@;Anim@ls;Fishes
Name: Organism Groups, dtype: object
print(grupy.str.slice(4,8).head())
0 ryot
1 ryot
2 ryot
3 ryot
4 ryot
Name: Organism Groups, dtype: object
Metody contains()
możemy użyć do selekcji danych na podstawie fragmentów łańcuchów znaków.
Zwraca ona serię wartości boolowskich wskazujących na obecność szukanego ciągu znaków.
print(grupy.str.contains('Animals').head())
0 True
1 True
2 True
3 True
4 True
Name: Organism Groups, dtype: bool
Teraz pozostaje użyć jej do filtrowania danych:
poa = dane[dane['Organism Name'].str.contains('Poa')]
print(poa[['Organism Name', 'Type']])
Organism Name Type
13711 Poa alsodes chloroplast
13712 Poa annua plastid
13713 Poa interior plastid
13714 Poa nemoralis plastid
13715 Poa palustris plastid
13716 Poa saltuensis chloroplast
13717 Poa trivialis plastid
13718 Poa wolfii chloroplast
Gdybyśmy chcieli uzyskać dodatkową kolumnę zawierającą tylko nazwę rodzaju organizmów, na przykład w celu łatwiejszej analizy danych, możemy posłużyć się metoda split()
:
# Dzielimy ciąg znaków w kolumnie Organism Name po spacji
# a następnie pobieramu pierwszy element powstałej listy
# i wpisujemy go do kolumny Rodzaj
dane['Rodzaj'] = dane['Organism Name'].str.split(' ').str[0]
print(dane[['Organism Name', 'Rodzaj']])
Organism Name Rodzaj
0 Aacanthocnema dobsoni Aacanthocnema
1 Abacion magnum Abacion
2 Abalistes stellaris Abalistes
3 Abax parallelepipedus Abax
4 Abbottina binhi Abbottina
... ... ...
18807 Zygophyllum xanthoxylon Zygophyllum
18808 Zygosaccharomyces mellis Y-12628 Zygosaccharomyces
18809 Zygosaccharomyces parabailii ATCC 60483 Zygosaccharomyces
18810 Zygotorulaspora mrakii NRRL Y-6702 Zygotorulaspora
18811 Zymoseptoria tritici Zymoseptoria
[18812 rows x 2 columns]
Wybierzmy ponownie dane dotyczące plastydów, ale tym razem tylko dla roślin telomowych (“Land Plants”).
plastydy = dane[dane['Type'].isin(['chloroplast','plastid']) \
& dane['Organism Groups'].str.contains('Land Plants')]
print(plastydy[['Organism Name', 'Organism Groups', 'Type']].head())
Organism Name Organism Groups Type
7 Abelia chinensis Eukaryota;Plants;Land Plants chloroplast
8 Abelia sanguinea Eukaryota;Plants;Land Plants chloroplast
9 Abelia x grandiflora Eukaryota;Plants;Land Plants chloroplast
10 Abeliophyllum distichum Eukaryota;Plants;Land Plants chloroplast
11 Abelmoschus esculentus Eukaryota;Plants;Land Plants chloroplast
Jak widać, użyliśmy operatora &
(and) ale można oczywiście używać |
(or) a także odwracać wynik filtrowania:
plastydy = dane[~dane['Type'].isin(['chloroplast','plastid']) \
& ~dane['Organism Groups'].str.contains('Land Plants')]
print(plastydy[['Organism Name', 'Organism Groups', 'Type']].head())
Organism Name Organism Groups Type
0 Aacanthocnema dobsoni Eukaryota;Animals;Insects mitochondrion
1 Abacion magnum Eukaryota;Animals;Other Animals mitochondrion
2 Abalistes stellaris Eukaryota;Animals;Fishes mitochondrion
3 Abax parallelepipedus Eukaryota;Animals;Insects mitochondrion
4 Abbottina binhi Eukaryota;Animals;Fishes mitochondrion
Dane dotyczące czasu
Zaimportujmy ponownie dane (jeśli to konieczne).
import pandas as pd
# Wczytanie danych z pliku csv
dane = pd.read_csv('organelles.csv')
Sprawdźmy (ponownie) typ danych przechowywanych w każdej kolumnie:
print(dane.dtypes)
Organism Name object
Organism Groups object
Size(Mb) float64
GC% float64
Type object
Replicons object
CDS int64
Release Date object
Genes int64
Pseudogene int64
dtype: object
Jak widać, dane określające czas upublicznienia genomów są zapisywane jako typ object
.
Dane dotyczące czasu, warto jednak przechowywać używając odpowiedniego typu danych, co umożliwia dokonywanie różnych operacji uwzględniając specyficzny charakter takich danych.
Można to zrobić od razu przy imporcie danych z pliku:
import pandas as pd
# Wczytanie danych z pliku csv
dane = pd.read_csv('organelles.csv', parse_dates = ['Release Date'])
print(dane.dtypes)
Organism Name object
Organism Groups object
Size(Mb) float64
GC% float64
Type object
Replicons object
CDS int64
Release Date datetime64[ns, UTC]
Genes int64
Pseudogene int64
dtype: object
Inną opcją jest zmiana typu istniejącej kolumny:
import pandas as pd
# Wczytanie danych z pliku csv
dane = pd.read_csv('organelles.csv')
dane['Release Date'] = pd.to_datetime(dane['Release Date'])
print(dane.dtypes)
Organism Name object
Organism Groups object
Size(Mb) float64
GC% float64
Type object
Replicons object
CDS int64
Release Date datetime64[ns, UTC]
Genes int64
Pseudogene int64
dtype: object
Od razu możemy zauważyć, że zmienił się sposób wyświetlania danych w kolumnie.
print(dane['Release Date'].head(3))
0 2018-07-31 00:00:00+00:00
1 2013-08-06 00:00:00+00:00
2 2009-01-22 00:00:00+00:00
Name: Release Date, dtype: datetime64[ns, UTC]
Poszczególne składowe można uzyskać z odpowiednich atrybutów:
# Rok
print(dane['Release Date'].dt.year.head(3))
0 2018
1 2013
2 2009
Name: Release Date, dtype: int64
# Miesiąc
print(dane['Release Date'].dt.month.head(3))
0 7
1 8
2 1
Name: Release Date, dtype: int64
# Dzień
print(dane['Release Date'].dt.day.head(3))
0 31
1 6
2 22
Name: Release Date, dtype: int64
# Godzina
print(dane['Release Date'].dt.hour.head(3))
0 0
1 0
2 0
Name: Release Date, dtype: int64
Co prawda nie jest to widoczne wprost w danych, ale można także uzyskać informację, jaki dzień tygodnia odpowiada danej dacie.
Może ona zostać przedstawiona w formie cyfry (0
- poniedziałek, 1
- wtorek itd.), lub jako angielska nazwa dnia tygodnia:
# Dzień tygodnia - cyfry
print(dane['Release Date'].dt.dayofweek.head(3))
0 1
1 1
2 3
Name: Release Date, dtype: int64
# Dzień tygodnia - nazwy
print(dane['Release Date'].dt.day_name().head(3))
0 Tuesday
1 Tuesday
2 Thursday
Name: Release Date, dtype: object
Możemy teraz np. pobrać dane które ukazały się od początku 2021 r.
nowe = dane[dane['Release Date'].dt.year >= 2021].copy()
print(nowe[['Organism Name', 'Release Date']].head(5))
print('...')
print(f'Od początku 2021 ukazało się {nowe.shape[0]} genomów.')
Organism Name Release Date
12 Abelmoschus manihot 2021-03-09 00:00:00+00:00
13 Abelmoschus moschatus 2021-03-09 00:00:00+00:00
14 Abelmoschus sagittifolius 2021-03-09 00:00:00+00:00
33 Abraximorpha davidii 2021-03-26 00:00:00+00:00
43 Abutilon theophrasti 2021-03-26 00:00:00+00:00
...
Od początku 2021 ukazało się 989 genomów.
Przy okazji możemy zreindeksować ramkę.
Ustawienie parametru drop = True
nie dopuszcza do utworzenia kolumny z poprzednimi indeksami, inplace = True
modyfikuje bezpośrednio ramkę.
nowe.reset_index(drop = True, inplace = True)
print(nowe[['Organism Name', 'Release Date']])
Organism Name Release Date
0 Abelmoschus manihot 2021-03-09 00:00:00+00:00
1 Abelmoschus moschatus 2021-03-09 00:00:00+00:00
2 Abelmoschus sagittifolius 2021-03-09 00:00:00+00:00
3 Abraximorpha davidii 2021-03-26 00:00:00+00:00
4 Abutilon theophrasti 2021-03-26 00:00:00+00:00
.. ... ...
984 Zonotrichia albicollis 2021-03-08 00:00:00+00:00
985 Zoysia matrella 2021-03-26 00:00:00+00:00
986 Zyginella minuta 2021-02-09 00:00:00+00:00
987 Zygophyllum fabago 2021-02-09 00:00:00+00:00
988 Zygophyllum xanthoxylon 2021-02-09 00:00:00+00:00
[989 rows x 2 columns]
Sprawdźmy jeszcze dane dla mitochondriów:
nowe = dane[(dane['Release Date'].dt.year >= 2021) \
& (dane['Type'] == 'mitochondrion')]
nowe.reset_index(drop = True, inplace = True)
print(nowe[['Organism Name', 'Release Date', 'Type']].head(5))
print('...')
print(f'Od początku 2021 ukazało się {nowe.shape[0]} genomów mitochondriów.')
Organism Name Release Date Type
0 Abraximorpha davidii 2021-03-26 00:00:00+00:00 mitochondrion
1 Acanthisitta chloris 2021-02-17 00:00:00+00:00 mitochondrion
2 Acidiella diversa 2021-03-26 00:00:00+00:00 mitochondrion
3 Acroneuria carolinensis 2021-03-26 00:00:00+00:00 mitochondrion
4 Acropteris iphiata 2021-03-26 00:00:00+00:00 mitochondrion
...
Od początku 2021 ukazało się 557 genomów mitochondriów.
Łatwo można uzyskać bieżący czas, zostanie zwrócony obiekt typu Timestamp
, z którego można pobrać różne informacje dotyczące czasu, np:
teraz = pd.Timestamp.now()
print(f'Typ obiektu: {type(teraz)}')
print(f'Data i czas: {teraz}')
print(f'Data: {teraz.date()}')
print(f'Czas: {teraz.time()}')
print(f'Godzina: {teraz.hour}')
print(f'Dzień w roku: {teraz.dayofyear}')
print(f'Tydzień: {teraz.week}')
Typ obiektu: <class 'pandas._libs.tslibs.timestamps.Timestamp'>
Data i czas: 2021-03-31 11:18:01.491502
Data: 2021-03-31
Czas: 11:18:01.491502
Godzina: 11
Dzień w roku: 90
Tydzień: 13
Operacje grupowania groupby
Operacje groupby
są bardzo pomocne w analizie danych, umożliwiają stosunkowo łatwe łączenie, transformację oraz filtrowanie danych.
Proces ten przebiega wg. schematu: ,,dziel-zastosuj-połącz’’ (ang. split-apply-combine).
Możemy zatem wyróżnić trzy etapy:
- Dane zostają podzielone (split) na podstawie jednego lub więcej kluczy, mogą to być np. nazwy kolumny w ramce danych.
- Poszczególne części danych są przetwarzane za pomocą funkcji (apply)
- Wyniki są łączone (combine) w nowy zestaw danych.
Zobaczmy na kilku przykładach co można w ten sposób uzyskać, choć oczywiście będzie to jedynie wycinek możliwości operacji groupby
.
Jeśli to konieczne, odczytajmy dane z pliku:
import pandas as pd
dane = pd.read_csv('organelles.csv')
Teraz zastosujmy operację grouby
z użyciem nazwy kolumny Type
jako klucza grupującego:
organelle = dane.groupby('Type')
Sprawdźmy jaki typ obiektu zwróciła metoda groupby()
i spróbujmy użyć na nim funkcji print()
:
print(f'Typ obiektu:{type(organelle)}')
print(organelle)
Typ obiektu:<class 'pandas.core.groupby.generic.DataFrameGroupBy'>
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x7f6f50a64040>
Jak widać, otrzymany obiekt jest typu DataFrameGroupBy
.
Zastosowanie print()
nie wyświetliło nam żadnych danych.
Spróbujmy zatem wywołać jakąś funkcję na obiekcie:
rozmiar = organelle.size()
print(f'Typ: {type(rozmiar)}')
print(rozmiar)
Typ: <class 'pandas.core.series.Series'>
Type
apicoplast 61
chloroplast 5379
chromatophore 2
cyanelle 1
kinetoplast 3
mitochondrion 12312
plastid 1054
dtype: int64
Dzięki groupby
mogliśmy pogrupować dane wg. rodzaju organelli, metoda size()
umożliwiła policzenie liczby elementów w każdej kategorii i zwróciła obiekt Series
.
Wywołajmy teraz metodę describe()
:
opis = organelle.describe()
print(f'Typ: {type(opis)}')
print(opis)
Typ: <class 'pandas.core.frame.DataFrame'>
Size(Mb) \
count mean std min 25% 50%
Type
apicoplast 61.0 0.034207 0.007766 0.012928 0.029401 0.034242
chloroplast 5379.0 0.152199 0.026511 0.015553 0.150469 0.155099
chromatophore 2.0 0.999409 0.031410 0.977199 0.988304 0.999409
cyanelle 1.0 0.135599 NaN 0.135599 0.135599 0.135599
kinetoplast 3.0 0.030547 0.009995 0.020992 0.025355 0.029717
mitochondrion 12312.0 0.034396 0.441088 0.001136 0.015848 0.016574
plastid 1054.0 0.149232 0.036191 0.011348 0.137826 0.154570
GC% ... Genes \
75% max count mean ... 75% max
Type ...
apicoplast 0.035107 0.053268 61.0 15.739062 ... 57.0 70.0
chloroplast 0.159234 1.352310 5379.0 37.035624 ... 133.0 315.0
chromatophore 1.010515 1.021620 2.0 38.944250 ... 911.5 922.0
cyanelle 0.135599 0.135599 1.0 30.467800 ... 192.0 192.0
kinetoplast 0.035324 0.040931 3.0 21.584733 ... 11.5 23.0
mitochondrion 0.017014 41.196000 12312.0 35.483058 ... 37.0 9230.0
plastid 0.159139 0.977190 1054.0 36.774486 ... 133.0 912.0
Pseudogene
count mean std min 25% 50% 75% max
Type
apicoplast 61.0 0.229508 0.588598 0.0 0.00 0.0 0.00 3.0
chloroplast 5379.0 1.333705 2.560317 0.0 0.00 0.0 2.00 40.0
chromatophore 2.0 4.500000 4.949747 1.0 2.75 4.5 6.25 8.0
cyanelle 1.0 0.000000 NaN 0.0 0.00 0.0 0.00 0.0
kinetoplast 3.0 0.000000 0.000000 0.0 0.00 0.0 0.00 0.0
mitochondrion 12312.0 0.056855 1.054682 0.0 0.00 0.0 0.00 81.0
plastid 1054.0 1.802657 3.990129 0.0 0.00 0.0 2.00 38.0
[7 rows x 40 columns]
Otrzymaliśmy ramkę danych i opisowe statystyki dla poszczególnych organelli.
Ograniczmy wyniki dla kolumny Size(Mb)
:
print(organelle.describe()['Size(Mb)'])
count mean std min 25% 50% \
Type
apicoplast 61.0 0.034207 0.007766 0.012928 0.029401 0.034242
chloroplast 5379.0 0.152199 0.026511 0.015553 0.150469 0.155099
chromatophore 2.0 0.999409 0.031410 0.977199 0.988304 0.999409
cyanelle 1.0 0.135599 NaN 0.135599 0.135599 0.135599
kinetoplast 3.0 0.030547 0.009995 0.020992 0.025355 0.029717
mitochondrion 12312.0 0.034396 0.441088 0.001136 0.015848 0.016574
plastid 1054.0 0.149232 0.036191 0.011348 0.137826 0.154570
75% max
Type
apicoplast 0.035107 0.053268
chloroplast 0.159234 1.352310
chromatophore 1.010515 1.021620
cyanelle 0.135599 0.135599
kinetoplast 0.035324 0.040931
mitochondrion 0.017014 41.196000
plastid 0.159139 0.977190
Teraz sprawdźmy średnią dla rozmiaru genomów:
print(organelle['Size(Mb)'].mean())
Type
apicoplast 0.034207
chloroplast 0.152199
chromatophore 0.999409
cyanelle 0.135599
kinetoplast 0.030547
mitochondrion 0.034396
plastid 0.149232
Name: Size(Mb), dtype: float64
Teraz użyjemy dwu kluczy, dla kolumn: Organism Groups
oraz Type
:
organizmy_organelle = dane.groupby(['Organism Groups', 'Type'])
Uzyskajmy średnią wielkość genomu dla każdej grupy organizmów, dla każdego typu organelli:
print(organizmy_organelle['Size(Mb)'].mean())
Organism Groups Type
Eukaryota;Animals;Amphibians mitochondrion 0.017533
Eukaryota;Animals;Birds mitochondrion 0.017124
Eukaryota;Animals;Fishes mitochondrion 0.016685
Eukaryota;Animals;Flatworms mitochondrion 0.014463
Eukaryota;Animals;Insects mitochondrion 0.015746
Eukaryota;Animals;Mammals mitochondrion 0.016582
Eukaryota;Animals;Other Animals mitochondrion 0.016340
Eukaryota;Animals;Reptiles mitochondrion 0.017124
Eukaryota;Animals;Roundworms mitochondrion 0.014594
Eukaryota;Fungi;Ascomycetes mitochondrion 0.064716
Eukaryota;Fungi;Basidiomycetes mitochondrion 0.078151
Eukaryota;Fungi;Other Fungi mitochondrion 0.059099
Eukaryota;Other;Other chloroplast 0.161175
mitochondrion 0.032238
plastid 0.172766
Eukaryota;Plants;Green Algae chloroplast 0.156876
mitochondrion 0.055061
plastid 0.141459
Eukaryota;Plants;Land Plants chloroplast 0.152268
mitochondrion 0.413925
plastid 0.148032
Eukaryota;Plants;Other Plants chloroplast 0.153641
mitochondrion 0.102788
Eukaryota;Protists;Apicomplexans apicoplast 0.034207
mitochondrion 0.006191
Eukaryota;Protists;Kinetoplasts kinetoplast 0.030547
mitochondrion 0.050477
Eukaryota;Protists;Other Protists chloroplast 0.106175
chromatophore 0.999409
cyanelle 0.135599
mitochondrion 0.599552
plastid 0.142994
Name: Size(Mb), dtype: float64
Odwróćmy teraz kolejność podanych kluczy grupowania:
organizmy_organelle = dane.groupby(['Type', 'Organism Groups'])
print(organizmy_organelle['Size(Mb)'].mean())
Type Organism Groups
apicoplast Eukaryota;Protists;Apicomplexans 0.034207
chloroplast Eukaryota;Other;Other 0.161175
Eukaryota;Plants;Green Algae 0.156876
Eukaryota;Plants;Land Plants 0.152268
Eukaryota;Plants;Other Plants 0.153641
Eukaryota;Protists;Other Protists 0.106175
chromatophore Eukaryota;Protists;Other Protists 0.999409
cyanelle Eukaryota;Protists;Other Protists 0.135599
kinetoplast Eukaryota;Protists;Kinetoplasts 0.030547
mitochondrion Eukaryota;Animals;Amphibians 0.017533
Eukaryota;Animals;Birds 0.017124
Eukaryota;Animals;Fishes 0.016685
Eukaryota;Animals;Flatworms 0.014463
Eukaryota;Animals;Insects 0.015746
Eukaryota;Animals;Mammals 0.016582
Eukaryota;Animals;Other Animals 0.016340
Eukaryota;Animals;Reptiles 0.017124
Eukaryota;Animals;Roundworms 0.014594
Eukaryota;Fungi;Ascomycetes 0.064716
Eukaryota;Fungi;Basidiomycetes 0.078151
Eukaryota;Fungi;Other Fungi 0.059099
Eukaryota;Other;Other 0.032238
Eukaryota;Plants;Green Algae 0.055061
Eukaryota;Plants;Land Plants 0.413925
Eukaryota;Plants;Other Plants 0.102788
Eukaryota;Protists;Apicomplexans 0.006191
Eukaryota;Protists;Kinetoplasts 0.050477
Eukaryota;Protists;Other Protists 0.599552
plastid Eukaryota;Other;Other 0.172766
Eukaryota;Plants;Green Algae 0.141459
Eukaryota;Plants;Land Plants 0.148032
Eukaryota;Protists;Other Protists 0.142994
Name: Size(Mb), dtype: float64
W uzyskanej w ten sposób, czyli z użyciem więcej niż jednej kolumn w celu grupowania, ramce danych mamy do czynienia z indeksem hierarchicznym. Zauważ jak wyświetlają się dane w ramce;
wynik = organizmy_organelle[['Size(Mb)', 'Genes']].mean()
print(wynik.head())
Size(Mb) Genes
Type Organism Groups
apicoplast Eukaryota;Protists;Apicomplexans 0.034207 31.901639
chloroplast Eukaryota;Other;Other 0.161175 210.984848
Eukaryota;Plants;Green Algae 0.156876 107.534591
Eukaryota;Plants;Land Plants 0.152268 128.742328
Eukaryota;Plants;Other Plants 0.153641 136.700000
Size(Mb)
i Genes
są tu kolumnami, natomiast Type
oraz Organism Groups
opisują indeksy:
print(wynik.index)
MultiIndex([( 'apicoplast', 'Eukaryota;Protists;Apicomplexans'),
( 'chloroplast', 'Eukaryota;Other;Other'),
( 'chloroplast', 'Eukaryota;Plants;Green Algae'),
( 'chloroplast', 'Eukaryota;Plants;Land Plants'),
( 'chloroplast', 'Eukaryota;Plants;Other Plants'),
( 'chloroplast', 'Eukaryota;Protists;Other Protists'),
('chromatophore', 'Eukaryota;Protists;Other Protists'),
( 'cyanelle', 'Eukaryota;Protists;Other Protists'),
( 'kinetoplast', 'Eukaryota;Protists;Kinetoplasts'),
('mitochondrion', 'Eukaryota;Animals;Amphibians'),
('mitochondrion', 'Eukaryota;Animals;Birds'),
('mitochondrion', 'Eukaryota;Animals;Fishes'),
('mitochondrion', 'Eukaryota;Animals;Flatworms'),
('mitochondrion', 'Eukaryota;Animals;Insects'),
('mitochondrion', 'Eukaryota;Animals;Mammals'),
('mitochondrion', 'Eukaryota;Animals;Other Animals'),
...
( 'plastid', 'Eukaryota;Protists;Other Protists')],
names=['Type', 'Organism Groups'])
Możemy zatem odwoływać się kolejno do etykiet indeksów, używając np. loc
tak aby wybrać interesujące nas dane:
print(wynik.loc['mitochondrion'].loc[['Eukaryota;Animals;Insects', 'Eukaryota;Animals;Mammals']]\
[['Genes','Size(Mb)']])
Genes Size(Mb)
Organism Groups
Eukaryota;Animals;Insects 29.848341 0.015746
Eukaryota;Animals;Mammals 23.732194 0.016582
Oczywiście grupowanie można łączyć z odpowiednimi funkcjami pozwalającym na selekcję danych.
Przykładowo, uzyskajmy dane dla organelli w grupie organizmów ‘Land Plants’ (rośliny telomowe) i wyświetlmy wybrane kolumny statystyk dla rozmiaru genomu (Size(Mb)
).
rosliny = dane[dane['Organism Groups'].str.contains('Land Plants')]\
.groupby('Type')
print(rosliny.describe()['Size(Mb)'][['count', 'mean', 'min', 'max']])
count mean min max
Type
chloroplast 5018.0 0.152268 0.015553 0.707276
mitochondrion 260.0 0.413925 0.011640 1.999600
plastid 949.0 0.148032 0.011348 0.230012
Odczyt i zapis danych do plików w różnych formatach
Dotychczas odczytywaliśmy dane w formacie csv
(ang. comma-separated values), w którym (domyślnie) separatorem jest przecinek:
import pandas as pd
dane = pd.read_csv('organelles.csv')
Dane zostały zapisane w ramce danych.
Podczas większości operacji opisanych powyżej, dotyczących selekcji, modyfikacji, czy innych operacji na danych, także otrzymywaliśmy ramki z danymi.
Można je także zapisać do pliku csv
:
rosliny = dane[dane['Organism Groups'].str.contains('Land Plants')]\
.groupby('Type')
wynik = rosliny.describe()['Size(Mb)'][['count', 'mean', 'min', 'max']]
print(wynik)
wynik.to_csv('rosliny_ladowe_rozmiar_genomu.csv')
count mean min max
Type
chloroplast 5018.0 0.152268 0.015553 0.707276
mitochondrion 260.0 0.413925 0.011640 1.999600
plastid 949.0 0.148032 0.011348 0.230012
Możesz otworzyć plik w edytorze tekstu, lub np. w LibreOffice.
Zauważ, że etykiety indeksów zostały zapisane w oddzielnej kolumnie.
Domyślny separator można zmienić np. na tabulator, wtedy warto by jednak zmienić przedłużenie pliku na tsv
(ang. tab-separated values):
wynik.to_csv('rosliny_ladowe_rozmiar_genomu.tsv', sep = '\t')
Odczytać plik w formacie tsv
, można używając metody read_csv()
z podaniem odpowiedniej opcji, lub metody read_table()
, dla której tabulator jest separatorem domyślnym:
ramka_1 = pd.read_csv('rosliny_ladowe_rozmiar_genomu.tsv', sep = '\t')
print(ramka_1)
Type count mean min max
0 chloroplast 5018.0 0.152268 0.015553 0.707276
1 mitochondrion 260.0 0.413925 0.011640 1.999600
2 plastid 949.0 0.148032 0.011348 0.230012
ramka_2 = pd.read_table('rosliny_ladowe_rozmiar_genomu.tsv')
print(ramka_2)
Type count mean min max
0 chloroplast 5018.0 0.152268 0.015553 0.707276
1 mitochondrion 260.0 0.413925 0.011640 1.999600
2 plastid 949.0 0.148032 0.011348 0.230012
Dane można także zapisać w wielu innych formatach, np.:
# Format programu Excel
wynik.to_excel('rosliny_ladowe_rozmiar_genomu.xlsx')
# Format HTML
wynik.to_html('rosliny_ladowe_rozmiar_genomu.html')
# Format LaTeX
wynik.to_latex('rosliny_ladowe_rozmiar_genomu.latex')
# Format JSON
wynik.to_json('rosliny_ladowe_rozmiar_genomu.json')
Istnieje też możliwość odczytu wielu formatów (choć rezultaty mogą się różnić), np.:
# Format programu Excel
wynik_xlsx = pd.read_excel('rosliny_ladowe_rozmiar_genomu.xlsx')
print(f'xlsx:\n{wynik_xlsx}')
# Format HTML
wynik_html = pd.read_html('rosliny_ladowe_rozmiar_genomu.html')
print(f'html:\n{wynik_html}')
# Format JSON
wynik_json = pd.read_json('rosliny_ladowe_rozmiar_genomu.json')
print(f'json:\n{wynik_json}')
xlsx:
Type count mean min max
0 chloroplast 5018 0.152268 0.015553 0.707276
1 mitochondrion 260 0.413925 0.011640 1.999600
2 plastid 949 0.148032 0.011348 0.230012
html:
[ Unnamed: 0_level_0 count mean min \
Type Unnamed: 1_level_1 Unnamed: 2_level_1 Unnamed: 3_level_1
0 chloroplast 5018.0 0.152268 0.015553
1 mitochondrion 260.0 0.413925 0.011640
2 plastid 949.0 0.148032 0.011348
max
Unnamed: 4_level_1
0 0.707276
1 1.999600
2 0.230012 ]
json:
count mean min max
chloroplast 5018 0.152268 0.015553 0.707276
mitochondrion 260 0.413925 0.011640 1.999600
plastid 949 0.148032 0.011348 0.230012
Jeśli plik w formacie xlsx
zawiera wiele arkuszy, powinniśmy wskazać ten, który chcemy zaimportować ustawiając parametr sheet_name="Nazwa Arkusza"
. W przeciwnym razie wczytany zostanie pierwszy arkusz.
Pobierz plik pomiary.xlsx
i zapisz w miejscu, w którym uruchamiasz kod (lub zmodyfikuj ścieżkę do pliku)
Następnie wczytaj go:
# Bez ustawienia arkusza
wynik_xlsx = pd.read_excel('pomiary.xlsx')
print(f'Arkusz domyślny:\n{wynik_xlsx}')
# Z ustawieniem arkusza
wynik_xlsx = pd.read_excel('pomiary.xlsx', sheet_name = 'szerokosci')
print(f'Wskazany arkusz:\n{wynik_xlsx}')
Arkusz domyślny:
osobnik długość
0 A 12.3
1 B 22.1
2 C 14.4
3 D 11.0
4 E 19.4
5 F 17.5
6 G 12.1
7 H 15.5
Wskazany arkusz:
osobnik szerokość
0 A 4.1
1 B 7.2
2 C 4.8
3 D 3.5
4 E 6.6
5 F 5.6
6 G 4.1
7 H 5.0
Zadanie
Uzyskaj średnie liczby genów i CDS w mitochondriach dla zwierząt, grzybów i roślin, tak aby wyświetlały się w ten sposób:
Genes CDS
Grupy
Animals 25.926091 12.628505
Fungi 34.237454 15.784578
Plants 71.170270 44.562162
Zapisz wynik w pliku o formacie tsv
Przykładowe rozwiązanie
import pandas as pd
dane = pd.read_csv('http://ggoralski.pl/files/inne/organelles.csv')
#dane = pd.read_csv('organelles.csv')
# Tworzymy kolumnę dla poszczególnych grup organizmów
dane['Grupy'] = dane['Organism Groups'].str.split(';').str[1]
# Operacja groupby
wynik_1 = dane.groupby(['Type', 'Grupy'])
# Obliczamy średnie
wynik_2 = wynik_1[['Genes', 'CDS']].mean()
# Selekcja danych dla mitochondriów i grup organizmów:
wynik_3 = wynik_2.loc['mitochondrion'].loc[['Animals','Fungi','Plants']]
print(wynik_3)
wynik_3.to_csv('mitochondria.tsv', sep = '\t')