Menu Zamknij

Porównaj styl pisarzy część 14 – Pandas

W poprzedniej części udało nam się policzyć 3-gramy i zapisać je do plików tekstowych. Przy odrobinie samozaparcia można tak zmienić formę i format plików, by dało się je zaimportować do Excela i tam prowadzić dalszą obróbkę. My zrobimy coś innego, użyjemy biblioteki Pandas, która wspiera typ danych nazywany Dataframe. W bardzo dużym uproszczeniu Dataframe to taki arkusz Excela: ma wiersze, kolumny i może mieć nazwy kolumn. Pandas to olbrzymia biblioteka Pythona, której możliwości rosną cały czas. 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ą.

Zaczniemy od zasilenia naszego Dataframe danymi, które uzyskaliśmy dzięki funkcji Counter().

from os import listdir
import re
from collections import Counter
import pandas as pd

sciezka = "F:\\python\\ids\\"
plik = "Bracia Dalcz i S-ka - Tadeusz Dolega-Mostowicz.txt"
ksiazka = open(sciezka + plik, mode="r", encoding = "utf-8")
tekst = ksiazka.read()

#przygotuj tekst do zliczania powtórzeń słów
tekst = tekst.replace("\n", " ")
tekst = tekst.lower()
tekst = re.sub("[^a-z ąćęłńóśóżź]", "", tekst)
tekst = re.sub(" +", " ", tekst)
wyrazy = tekst.split()
lista_trzech_wyrazow = []
#utwórz listę trzech kolejnych wyrazów
for indeks in range(len(wyrazy) - 2):
    trzy_wyrazy = " ".join(wyrazy[indeks:indeks + 3])
    lista_trzech_wyrazow.append(trzy_wyrazy)
#utwórz słownik zliczający liczbę powtórzeń trzech kolejnych wyrazów
liczba_trzygramow = Counter(lista_trzech_wyrazow)
#utwórz Dataframe (df) ze słownika
df = pd.DataFrame(liczba_trzygramow)
print(df)

W 4 linijce importujemy bilbiotekę Pandas. Standardem jest importowanie jej jako pd, dzięki temu w kodzie nie będziesz musiał pisać Pandas, by wykorzystać funkcje i metody tej biblioteki, wystarczy napisać pd. Nic nie stoi na przeszkodzie żeby np. zaimprować bibliotekę re jako reksio (import re as reksio) i zamiast re.sub() pisać reksio.sub(). W linijce 25 używamy funkcji DataFrame() (wielkość liter jest ważna) do zaimportowania słownika do Dataframe. Zobaczmy efekt:

======================== RESTART: F:/python38/wpis 14.py =======================
Traceback (most recent call last):
  File "F:/python38/wpis 14.py", line 26, in <module>
    df = pd.DataFrame(liczba_trzygramow)
  File "F:\python38\lib\site-packages\pandas\core\frame.py", line 435, in __init__
    mgr = init_dict(data, index, columns, dtype=dtype)
  File "F:\python38\lib\site-packages\pandas\core\internals\construction.py", line 254, in init_dict
    return arrays_to_mgr(arrays, data_names, index, columns, dtype=dtype)
  File "F:\python38\lib\site-packages\pandas\core\internals\construction.py", line 64, in arrays_to_mgr
    index = extract_index(arrays)
  File "F:\python38\lib\site-packages\pandas\core\internals\construction.py", line 355, in extract_index
    raise ValueError("If using all scalar values, you must pass an index")
ValueError: If using all scalar values, you must pass an index
>>> 

Błąd, Pandas nie poradzi sobie z naszym słownikiem ot tak, nie wszystko co chcemy może stać się Dataframe, tak jak nie każdą tabelę da się bezpośrednio wkleić do Excela. Cofnijmy się o krok i poćwiczymy na prostym słowniku:

import pandas as pd
slownik = {"kogut ma dziób":4, "kura ma jajka":2, "pisklę ma dzióbek":3}
print(slownik)

#utwórz Dataframe (df) ze słownika
dane_pandas = pd.DataFrame(slownik)
print(dane_pandas)

W 1 linijce importujemy bibliotekę pandas. W 2 linijce przygotowujemy pod zmienną slownik nasz słownik. W 3 linijce drukujemy słownik. W 6 linijce próbujemy umieścić słownik w Dataframe, co jak wiemy nie uda się. 7 linijka będzie nam potrzebna do wizualizacji Datafarame. Dataframe nie przyjmie słownika, ale sprawdźmy czy przyjmie listę, zmieńmy program:

import pandas as pd
slownik = {"kogut ma dziób":4, "kura ma jajka":2, "pisklę ma dzióbek":3}
print(list(slownik))

#utwórz Dataframe (df) ze słownika
dane_pandas = pd.DataFrame(list(slownik))
print(dane_pandas)

W 3 i 6 linijce wymuszamy zmianę typu danych na listę funkcją list(). Zobaczmy efekt:

======================== RESTART: F:/python38/wpis 14.py =======================
['kogut ma dziób', 'kura ma jajka', 'pisklę ma dzióbek']
                   0
0     kogut ma dziób
1      kura ma jajka
2  pisklę ma dzióbek
>>> 

Jest trochę lepiej. Lista znalazła się w Dataframe, ale jak widzimy, zmiana typu danych na listę pozbawiła nas wartości, zostały same klucze. Przyjrzyj się jeszcze Dataframe, prócz elementów listy, po lewej stronie są ponumerowane wiersze (od 0 do 2) a u góry numery kolumn (0), to trochę odpowiada numeracji w Excel, tyle, że w poziomie i pionie użyte są cyfry.

Spróbujmy inaczej. Użyjmy na słowniku metody .items(), która zwraca listę par składających się z klucza i wartości:

import pandas as pd
slownik = {"kogut ma dziób":4, "kura ma jajka":2, "pisklę ma dzióbek":3}
print(slownik.items())

#utwórz Dataframe (df) ze słownika
dane_pandas = pd.DataFrame(slownik.items())
print(dane_pandas)

Zobaczmy efekt:

======================== RESTART: F:/python38/wpis 14.py =======================
dict_items([('kogut ma dziób', 4), ('kura ma jajka', 2), ('pisklę ma dzióbek', 3)])
                   0  1
0     kogut ma dziób  4
1      kura ma jajka  2
2  pisklę ma dzióbek  3
>>> 

O to nam chodziło, doszła druga kolumna z nr 1, w której znajdują się wartości. Dodajmy jeszcze nazwy kolumn poprzez parametr columns funkcji DataFrame():

import pandas as pd
slownik = {"kogut ma dziób":4, "kura ma jajka":2, "pisklę ma dzióbek":3}
print(slownik.items())

#utwórz Dataframe (df) ze słownika
dane_pandas = pd.DataFrame(slownik.items(), \
                           columns = ["trzygram", "liczba wystąpień"])
print(dane_pandas)

Parametr columns uzupełniamy listą , czyli podajemy wartości w kwadratowych nawiasach [], nazwy kolumn podajemy w kolejności ich numerowania, w naszym przypadku kolumna 0 otrzyma nazwę trzygram, kolumna 1 nazwę liczba wystąpień. Zobaczmy efekt:

======================== RESTART: F:/python38/wpis 14.py =======================
dict_items([('kogut ma dziób', 4), ('kura ma jajka', 2), ('pisklę ma dzióbek', 3)])
            trzygram  liczba wystąpień
0     kogut ma dziób                 4
1      kura ma jajka                 2
2  pisklę ma dzióbek                 3
>>> 

Wykorzystajmy te nowe umiejętności w naszym głównym programie dla jednej książki:

from os import listdir
import re
from collections import Counter
import pandas as pd

sciezka = "F:\\python\\ids\\"
plik = "Bracia Dalcz i S-ka - Tadeusz Dolega-Mostowicz.txt"
ksiazka = open(sciezka + plik, mode="r", encoding = "utf-8")
tekst = ksiazka.read()

#przygotuj tekst do zliczania powtórzeń słów
tekst = tekst.replace("\n", " ")
tekst = tekst.lower()
tekst = re.sub("[^a-z ąćęłńóśóżź]", "", tekst)
tekst = re.sub(" +", " ", tekst)
wyrazy = tekst.split()
lista_trzech_wyrazow = []
#utwórz listę trzech kolejnych wyrazów
for indeks in range(len(wyrazy) - 2):
    trzy_wyrazy = " ".join(wyrazy[indeks:indeks + 3])
    lista_trzech_wyrazow.append(trzy_wyrazy)
#utwórz słownik zliczający liczbę powtórzeń trzech kolejnych wyrazów
liczba_trzygramow = Counter(lista_trzech_wyrazow)
#utwórz Dataframe (df) ze słownika
df = pd.DataFrame(liczba_trzygramow.items(),columns = ["Trzygram","TDM Bracia"])
print(df)

I zobaczmy efekt:

========================== RESTART: F:\python38\wpis 14.py =========================
                              Trzygram  TDM Bracia
0       tadeusz dołęgamostowicz bracia           2
1         dołęgamostowicz bracia dalcz           2
2                       bracia dalcz i           7
3                          dalcz i ska           5
4                             i ska ta           1
...                                ...         ...
136997                    family cc by           1
136998                      cc by isbn           1
136999                    by isbn plik           1
137000          isbn plik wygenerowany           1
137001          plik wygenerowany dnia           1

[137002 rows x 2 columns]
>>> 

Pandas jest na tyle przyjemną biblioteką, że nie zamorduje ci terminala drukowaniem wszystkich danych, jak widzisz z 137 002 wierszy wydrukował 5 pierwszych i 5 ostatnich. Dane dobrze jeszcze posortować, do tego służy funkcja sort_values(). Dodajmy ją do naszego programu:

from os import listdir
import re
from collections import Counter
import pandas as pd

sciezka = "F:\\python\\ids\\"
plik = "Bracia Dalcz i S-ka - Tadeusz Dolega-Mostowicz.txt"
ksiazka = open(sciezka + plik, mode="r", encoding = "utf-8")
tekst = ksiazka.read()

#przygotuj tekst do zliczania powtórzeń słów
tekst = tekst.replace("\n", " ")
tekst = tekst.lower()
tekst = re.sub("[^a-z ąćęłńóśóżź]", "", tekst)
tekst = re.sub(" +", " ", tekst)
wyrazy = tekst.split()
lista_trzech_wyrazow = []
#utwórz listę trzech kolejnych wyrazów
for indeks in range(len(wyrazy) - 2):
    trzy_wyrazy = " ".join(wyrazy[indeks:indeks + 3])
    lista_trzech_wyrazow.append(trzy_wyrazy)
#utwórz słownik zliczający liczbę powtórzeń trzech kolejnych wyrazów
liczba_trzygramow = Counter(lista_trzech_wyrazow)
#utwórz Dataframe (df) ze słownika
df = pd.DataFrame(liczba_trzygramow.items(),columns = ["Trzygram","TDM Bracia"])
print(df)
#posortuj od najliczniej występującego trzygramu
df = df.sort_values(by = "TDM Bracia", ascending = False)
print(df)

w 28 linijce podajemy argumenty funkcji sort_values(), pierwszy argument by = służy wskazaniu której kolumny do sortowania chcesz użyć, my nazwaliśmy kolumny dlatego podajemy jej nazwę. Podajemy też drugi argument, chcemy żeby w pierwszym wierszu Dataframe była największa wartość, a potem malała w kolejnych wierszach, czyli sortujemy malejąco. sort_values() ma domyślnie sortowanie rosnąco, dlatego musimy to zmienić podając argument ascending równy False. Zobaczmy efekt:

========================== RESTART: F:\python38\wpis 14.py =========================
                              Trzygram  TDM Bracia
0       tadeusz dołęgamostowicz bracia           2
1         dołęgamostowicz bracia dalcz           2
2                       bracia dalcz i           7
3                          dalcz i ska           5
4                             i ska ta           1
...                                ...         ...
136997                    family cc by           1
136998                      cc by isbn           1
136999                    by isbn plik           1
137000          isbn plik wygenerowany           1
137001          plik wygenerowany dnia           1

[137002 rows x 2 columns]
                      Trzygram  TDM Bracia
1479            w każdym razie          55
5833              w ten sposób          40
5596               w ogóle nie          18
34019         w gruncie rzeczy          17
6899             ze względu na          17
...                        ...         ...
47031       wskaże kilka spraw           1
47030           i wskaże kilka           1
47029         zadanie i wskaże           1
47028             mi zadanie i           1
137001  plik wygenerowany dnia           1

[137002 rows x 2 columns]
>>> 

W naszym przypadku nie interesuje nas, co jest na końcu Dataframe, ale chętnie obejrzymy więcej niż 5 pierwszych wierszy. W Dataframe możemy użyć funkcji head(), której argumentem jest liczba wierszy do wyświetlenia. Zmieńmy 29 linijkę kodu:

from os import listdir
import re
from collections import Counter
import pandas as pd

sciezka = "F:\\python\\ids\\"
plik = "Bracia Dalcz i S-ka - Tadeusz Dolega-Mostowicz.txt"
ksiazka = open(sciezka + plik, mode="r", encoding = "utf-8")
tekst = ksiazka.read()

#przygotuj tekst do zliczania powtórzeń słów
tekst = tekst.replace("\n", " ")
tekst = tekst.lower()
tekst = re.sub("[^a-z ąćęłńóśóżź]", "", tekst)
tekst = re.sub(" +", " ", tekst)
wyrazy = tekst.split()
lista_trzech_wyrazow = []
#utwórz listę trzech kolejnych wyrazów
for indeks in range(len(wyrazy) - 2):
    trzy_wyrazy = " ".join(wyrazy[indeks:indeks + 3])
    lista_trzech_wyrazow.append(trzy_wyrazy)
#utwórz słownik zliczający liczbę powtórzeń trzech kolejnych wyrazów
liczba_trzygramow = Counter(lista_trzech_wyrazow)
#utwórz Dataframe (df) ze słownika
df = pd.DataFrame(liczba_trzygramow.items(),columns = ["Trzygram","TDM Bracia"])
print(df)
#posortuj od najliczniej występującego trzygramu
df = df.sort_values(by = "TDM Bracia", ascending = False)
print(df.head(10))

I zobaczmy efekt:

========================== RESTART: F:\python38\wpis 14.py =========================
                              Trzygram  TDM Bracia
0       tadeusz dołęgamostowicz bracia           2
1         dołęgamostowicz bracia dalcz           2
2                       bracia dalcz i           7
3                          dalcz i ska           5
4                             i ska ta           1
...                                ...         ...
136997                    family cc by           1
136998                      cc by isbn           1
136999                    by isbn plik           1
137000          isbn plik wygenerowany           1
137001          plik wygenerowany dnia           1

[137002 rows x 2 columns]
               Trzygram  TDM Bracia
1479     w każdym razie          55
5833       w ten sposób          40
5596        w ogóle nie          18
34019  w gruncie rzeczy          17
6899      ze względu na          17
26064        na myśl że          16
34971          o tym że          15
8993      w stosunku do          15
5834      ten sposób że          14
22992         się z nim          14
>>> 

Fantastycznie! Zróbmy to samo dla wszystkich książek z katalogu:

from os import listdir
import re
from collections import Counter
import pandas as pd

sciezka = "F:\\python\\ids\\"
pliki = listdir(sciezka)

#dla każdego pliu w katalogu
for plik in pliki:
    #otwórz plik
    ksiazka = open(sciezka + plik, mode="r", encoding = "utf-8")
    tekst = ksiazka.read()
    #usuń kłopotliwe przypisek T. D. M. i przypisy
    if plik == "Pamietnik pani Hanki - Tadeusz Dolega-Mostowicz.txt":
        tekst = tekst.replace("(Przypisek T. D. M.)","")
    elif plik == "Dziecko salonu - Janusz Korczak.txt" or \
         plik == "Kiedy znow bede maly - Janusz Korczak.txt" or \
         plik == "Bankructwo malego Dzeka - Janusz Korczak.txt":
        tekst = tekst.split("Przypisy:")[0]
    #przygotuj tekst do zliczania powtórzeń słów
    tekst = tekst.replace("\n", " ")
    tekst = tekst.lower()
    tekst = re.sub("[^a-z ąćęłńóśóżź]", "", tekst)
    tekst = re.sub(" +", " ", tekst)
    wyrazy = tekst.split()
    lista_trzech_wyrazow = []
    #utwórz listę trzech kolejnych wyrazów
    for indeks in range(len(wyrazy) - 2):
        trzy_wyrazy = " ".join(wyrazy[indeks:indeks + 3])
        lista_trzech_wyrazow.append(trzy_wyrazy)
    #utwórz słownik zliczający liczbę powtórzeń trzech kolejnych wyrazów
    liczba_trzygramow = Counter(lista_trzech_wyrazow)
    #utwórz Dataframe (df) ze słownika
    df = pd.DataFrame(liczba_trzygramow.items(),columns = ["Trzygram","TDM Bracia"])
    #posortuj od najliczniej występującego trzygramu
    df = df.sort_values(by = "TDM Bracia", ascending = False)
    print(df.head(10))

I zobaczmy efekt:

======================== RESTART: F:\python38\wpis 14.py =======================
                  Trzygram  TDM Bracia
3415   pani powiedziała że          11
6376            że się nie           8
6761          żeby się nie           8
33596            bo nie ma           7
19972      z mister taftem           7
2501          ale dżek nie           7
6803          to znaczy że           7
39081      bank dla dzieci           7
10163      do mister tafta           7
3947       na przyszły rok           7
               Trzygram  TDM Bracia
1479     w każdym razie          55
5833       w ten sposób          40
5596        w ogóle nie          18
34019  w gruncie rzeczy          17
6899      ze względu na          17
26064        na myśl że          16
34971          o tym że          15
8993      w stosunku do          15
5834      ten sposób że          14
22992         się z nim          14
              Trzygram  TDM Bracia
2719    w każdym razie          30
711        w związku z          12
20962         o tem że          10
8289   spojrzał na nią          10
8516      w ten sposób           9
11279      od czasu do           9
11280   czasu do czasu           9
11510       na myśl że           9
943       bądź co bądź           8
16334     z całej siły           8
              Trzygram  TDM Bracia
5274    w każdym razie          20
18308   okazało się że          12
301       w ten sposób          12
4133          o tem że          12
16694    w stosunku do          11
641     zwrócił się do          11
516        i po chwili          11
366         raz po raz          11
3330         się z nią          10
4727   spojrzał na nią          10
              Trzygram  TDM Bracia
1696      w tej chwili          13
14253       ja wiem że           8
7526   po raz pierwszy           8
10562        się z nim           7
2717          co to za           7
2480    nic więcej nie           7
17209    jak gdyby nie           7
9263      zdaje mi się           6
215     niech pan kupi           6
1417    w stronę wisły           6
                  Trzygram  TDM Bracia
3107            co to jest          17
2879           ja nie chcę          13
38766           od izby do           9
38765          idę od izby           9
38767         izby do izby           9
33               mi się że           8
26807  ciastkami na guziku           8
26806       z ciastkami na           8
749         rozumie się że           7
1728              ha ha ha           6
               Trzygram  TDM Bracia
295          nie wie co           9
1607           co to za           9
1944         mu się nie           8
4327          że nie ma           7
6701       co się stało           7
5873       zdaje się że           6
7950        oparł się o           5
1508        nie bój się           5
9999      pyta się mama           5
12643  dziwi się kajtuś           5
                     Trzygram  TDM Bracia
8614  kochany panie nikodemie          23
3510              che che che          18
304                raz po raz          15
5628               mu na myśl          15
596             że pan prezes          14
3019           w każdym razie          14
5629               na myśl że          14
8232            się z miejsca          13
3829       na wszelki wypadek          12
5627           przyszło mu na          12
                  Trzygram  TDM Bracia
606           nie wiem czy          18
3759           nie wiem co          13
6044          się zdaje że          12
1009          sam nie wiem          11
696               a ja się          10
6188   kiedy byłem dorosły          10
4931              a on się           9
1036          żeby się nie           8
13406            i nic nie           8
3231          w tej chwili           8
                Trzygram  TDM Bracia
2206   do przekonania że          13
2783      w każdym razie          11
15278     okazało się że          10
22035       co się stało          10
8980           się z tym           9
1186      przyszło mu na           9
6586           mi się że           9
1187          mu na myśl           9
4527         od czasu do           8
4528      czasu do czasu           8
                       Trzygram  TDM Bracia
483        wasza królewska mość          27
44457           dziś popr forma          22
1196   waszej królewskiej mości          18
70            na bezludną wyspę          18
2723        na bezludnej wyspie          16
5868             nie wie maciuś          10
13473           pyta się maciuś          10
9133                   co to za          10
44730               forma os lp           8
4163                  i nic nie           8
              Trzygram  TDM Bracia
2257    w każdym razie          40
2899          o tym że          28
5358    okazało się że          22
4711     wydaje mi się          22
2672  spojrzał na mnie          22
6488      w ten sposób          20
7494        na myśl że          20
1327        się ze mną          19
2742       się nad tym          18
1451         mi się że          17
>>> 

Jest nieźle, chociaż tytuł drugiej kolumny powinien oddawać tytuł książki. Można to zmienić na wiele sposobów, np. zamiast podanej nazwy kolumny możemy użyć nazwy pliku (przy okazji skrócimy wyświetlanie do 5 wierszy Dataframe):

from os import listdir
import re
from collections import Counter
import pandas as pd

sciezka = "F:\\python\\ids\\"
pliki = listdir(sciezka)

#dla każdego pliu w katalogu
for plik in pliki:
    #otwórz plik
    ksiazka = open(sciezka + plik, mode="r", encoding = "utf-8")
    tekst = ksiazka.read()
    #usuń kłopotliwe przypisek T. D. M. i przypisy
    if plik == "Pamietnik pani Hanki - Tadeusz Dolega-Mostowicz.txt":
        tekst = tekst.replace("(Przypisek T. D. M.)","")
    elif plik == "Dziecko salonu - Janusz Korczak.txt" or \
         plik == "Kiedy znow bede maly - Janusz Korczak.txt" or \
         plik == "Bankructwo malego Dzeka - Janusz Korczak.txt":
        tekst = tekst.split("Przypisy:")[0]
    #przygotuj tekst do zliczania powtórzeń słów
    tekst = tekst.replace("\n", " ")
    tekst = tekst.lower()
    tekst = re.sub("[^a-z ąćęłńóśóżź]", "", tekst)
    tekst = re.sub(" +", " ", tekst)
    wyrazy = tekst.split()
    lista_trzech_wyrazow = []
    #utwórz listę trzech kolejnych wyrazów
    for indeks in range(len(wyrazy) - 2):
        trzy_wyrazy = " ".join(wyrazy[indeks:indeks + 3])
        lista_trzech_wyrazow.append(trzy_wyrazy)
    #utwórz słownik zliczający liczbę powtórzeń trzech kolejnych wyrazów
    liczba_trzygramow = Counter(lista_trzech_wyrazow)
    #utwórz Dataframe (df) ze słownika
    df = pd.DataFrame(liczba_trzygramow.items(),columns = ["Trzygram",plik])
    #posortuj od najliczniej występującego trzygramu
    df = df.sort_values(by = plik, ascending = False)
    print(df.head(5))

W 35 i 37 linijce zamiast ustalonej na sztywno nazwy odwołujemy się do wartości zmiennej plik. Efekt:

======================== RESTART: F:\python38\wpis 14.py =======================
                  Trzygram  Bankructwo malego Dzeka - Janusz Korczak.txt
3415   pani powiedziała że                                            11
6376            że się nie                                             8
6761          żeby się nie                                             8
33596            bo nie ma                                             7
19972      z mister taftem                                             7
               Trzygram  Bracia Dalcz i S-ka - Tadeusz Dolega-Mostowicz.txt
1479     w każdym razie                                                 55 
5833       w ten sposób                                                 40 
5596        w ogóle nie                                                 18 
34019  w gruncie rzeczy                                                 17 
6899      ze względu na                                                 17 
              Trzygram  Dr. Murek zredukowany - Tadeusz Dolega-Mostowicz.txt
2719    w każdym razie                                                 30   
711        w związku z                                                 12   
20962         o tem że                                                 10   
8289   spojrzał na nią                                                 10   
8516      w ten sposób                                                  9   
             Trzygram  Drugie zycie doktora Murka - Tadeusz Dolega-Mostowicz.txt
5274   w każdym razie                                                 20        
18308  okazało się że                                                 12        
301      w ten sposób                                                 12        
4133         o tem że                                                 12        
16694   w stosunku do                                                 11        
              Trzygram  Dzieci ulicy - Janusz Korczak.txt
1696      w tej chwili                                 13
14253       ja wiem że                                  8
7526   po raz pierwszy                                  8
10562        się z nim                                  7
2717          co to za                                  7
           Trzygram  Dziecko salonu - Janusz Korczak.txt
3107     co to jest                                   17
2879    ja nie chcę                                   13
38766    od izby do                                    9
38765   idę od izby                                    9
38767  izby do izby                                    9
          Trzygram  Kajtus Czarodziej - Janusz Korczak.txt
295     nie wie co                                       9
1607      co to za                                       9
1944    mu się nie                                       8
4327     że nie ma                                       7
6701  co się stało                                       7
                     Trzygram  Kariera Nikodema Dyzmy - Tadeusz Dolega-Mostowicz.txt
8614  kochany panie nikodemie                                                 23    
3510              che che che                                                 18    
304                raz po raz                                                 15    
5628               mu na myśl                                                 15    
596             że pan prezes                                                 14    
          Trzygram  Kiedy znow bede maly - Janusz Korczak.txt
606   nie wiem czy                                         18
3759   nie wiem co                                         13
6044  się zdaje że                                         12
1009  sam nie wiem                                         11
696       a ja się                                         10
                Trzygram  Kiwony - Tadeusz Dolega-Mostowicz.txt
2206   do przekonania że                                     13
2783      w każdym razie                                     11
15278     okazało się że                                     10
22035       co się stało                                     10
8980           się z tym                                      9
                       Trzygram  Krol Macius na wyspie bezludnej - Janusz Korczak.txt
483        wasza królewska mość                                                 27   
44457           dziś popr forma                                                 22   
1196   waszej królewskiej mości                                                 18   
70            na bezludną wyspę                                                 18   
2723        na bezludnej wyspie                                                 16   
              Trzygram  Pamietnik pani Hanki - Tadeusz Dolega-Mostowicz.txt
2257    w każdym razie                                                 40  
2899          o tym że                                                 28  
5358    okazało się że                                                 22  
4711     wydaje mi się                                                 22  
2672  spojrzał na mnie                                                 22  
>>> 

Teraz wiadomo, co przedstawia każdy z Dataframe, ale nazwy kolumny są trochę za długie. Może uda nam się je poprawić. Dobrze by mieć na początku inicjały autora, a potem tytuł. Mamy już cały wachlarz umiejętności pozwalający na taką zmianę. Ja bym zrobił to tak. Popatrz, możesz wyświetlić listę z nazwami plików:

from os import listdir

sciezka = "F:\\python\\ids\\"
pliki = listdir(sciezka)
print(pliki)

Lista wygląda tak:

======================== RESTART: F:\python38\wpis 14.py =======================
['Bankructwo malego Dzeka - Janusz Korczak.txt', 'Bracia Dalcz i S-ka - Tadeusz Dolega-Mostowicz.txt', 'Dr. Murek zredukowany - Tadeusz Dolega-Mostowicz.txt', 'Drugie zycie doktora Murka - Tadeusz Dolega-Mostowicz.txt', 'Dzieci ulicy - Janusz Korczak.txt', 'Dziecko salonu - Janusz Korczak.txt', 'Kajtus Czarodziej - Janusz Korczak.txt', 'Kariera Nikodema Dyzmy - Tadeusz Dolega-Mostowicz.txt', 'Kiedy znow bede maly - Janusz Korczak.txt', 'Kiwony - Tadeusz Dolega-Mostowicz.txt', 'Krol Macius na wyspie bezludnej - Janusz Korczak.txt', 'Pamietnik pani Hanki - Tadeusz Dolega-Mostowicz.txt']

Cały pomysł opiera się na już posiadanych danych jakie mamy w elementach listy. Pomyśl chwilę, wybierz własną metodę i sprawdź, czy uda ci się utworzyć listę inicjałów i tytułów. Potem zerknij na mój sposób:

from os import listdir

sciezka = "F:\\python\\ids\\"
pliki = listdir(sciezka)
tytuly = []
print(pliki)
for plik in pliki:
    if plik.find("Tadeusz Dolega-Mostowicz") > -1:
        autor = "TDM"
        tytul = plik.split(" - Tadeusz Dolega-Mostowicz")[0]
    else:
        autor = "JK"
        tytul = plik.split(" - Janusz Korczak")[0]
    tytuly.append(f"{autor} {tytul}")

print(tytuly)

Co zrobiłem? W 5 linijce stworzyłem pustą listę, w której znajdą się skrócone tytuły. W 8 linijce dla każdego elementu listy używam metody .find(), w jej argumencie podajesz tekst do znalezienia. Metoda zwraca liczbę wskazującą pierwszy indeks podanego do wyszukania ciągu znaków, jeśli szukanego tekstu nie ma w stringu metoda zwraca wartość -1. Czyli 8 linijkę można przeczytać tak Jeśli w elemencie listy występuje „Tadeusz Dolega-Mostowicz” (wartość .find() większa od -1) to: . W 9 linijce pod zmienną autor podstawiam inicjały, a pod zmienną tytul fragment stringa znajdujący się przed ” – Tadeusz Dolega-Mostowicz” oznaczającym autora. W 11 linijce zaczyna się warunek, gdy metoda .find() zwróci wartość mniejszą niż 0. W tym wypadku autorem staje się JK, a tytuł jest fragmentem stringa, w którym występuje ciąg ” – Janusz Korczak”. W 14 linijce łączymy zmienną autor i tytuł, by uzyskać zakładany efekt. Zobaczmy go:

======================== RESTART: F:\python38\wpis 14.py =======================
['JK Bankructwo malego Dzeka', 'TDM Bracia Dalcz i S-ka', 'TDM Dr. Murek zredukowany', 'TDM Drugie zycie doktora Murka', 'JK Dzieci ulicy', 'JK Dziecko salonu', 'JK Kajtus Czarodziej', 'TDM Kariera Nikodema Dyzmy', 'JK Kiedy znow bede maly', 'TDM Kiwony', 'JK Krol Macius na wyspie bezludnej', 'TDM Pamietnik pani Hanki']
>>> 

Można jeszcze naszą pętlę uładnić:

from os import listdir

sciezka = "F:\\python\\ids\\"
pliki = listdir(sciezka)
autortytul = []
for plik in pliki:
    if plik.find("Tadeusz Dolega-Mostowicz") > -1:
        autortytul.append(f"TDM {plik.split(' - Tadeusz Dolega-Mostowicz')[0]}")
    else:
        autortytul.append(f"JK {plik.split(' - Janusz Korczak')[0]}")

print(autortytul)

W powyższym kodzie pozbywamy się zmiennych autor i tytul. Zamiast nich używamy fstring, co oszczędza nam 4 linijki i dwie zmienne. Zauważ konieczność zastosowania w metodzie .split() pojedynczych cudzysłowów. Efekt działania:

======================== RESTART: F:\python38\wpis 14.py =======================
['JK Bankructwo malego Dzeka', 'TDM Bracia Dalcz i S-ka', 'TDM Dr. Murek zredukowany', 'TDM Drugie zycie doktora Murka', 'JK Dzieci ulicy', 'JK Dziecko salonu', 'JK Kajtus Czarodziej', 'TDM Kariera Nikodema Dyzmy', 'JK Kiedy znow bede maly', 'TDM Kiwony', 'JK Krol Macius na wyspie bezludnej', 'TDM Pamietnik pani Hanki']
>>> 

Wszystko działa, możemy użyć tego kodu w głównym programie:

from os import listdir
import re
from collections import Counter
import pandas as pd

sciezka = "F:\\python\\ids\\"
pliki = listdir(sciezka)
#dla każdego pliu w katalogu
for plik in pliki:
    #otwórz plik
    ksiazka = open(sciezka + plik, mode="r", encoding = "utf-8")
    tekst = ksiazka.read()
    #usuń kłopotliwe przypisek T. D. M. i przypisy
    if plik == "Pamietnik pani Hanki - Tadeusz Dolega-Mostowicz.txt":
        tekst = tekst.replace("(Przypisek T. D. M.)","")
    elif plik == "Dziecko salonu - Janusz Korczak.txt" or \
         plik == "Kiedy znow bede maly - Janusz Korczak.txt" or \
         plik == "Bankructwo malego Dzeka - Janusz Korczak.txt":
        tekst = tekst.split("Przypisy:")[0]
    #przygotuj tekst do zliczania powtórzeń słów
    tekst = tekst.replace("\n", " ")
    tekst = tekst.lower()
    tekst = re.sub("[^a-z ąćęłńóśóżź]", "", tekst)
    tekst = re.sub(" +", " ", tekst)
    wyrazy = tekst.split()
    lista_trzech_wyrazow = []
    #utwórz listę trzech kolejnych wyrazów
    for indeks in range(len(wyrazy) - 2):
        trzy_wyrazy = " ".join(wyrazy[indeks:indeks + 3])
        lista_trzech_wyrazow.append(trzy_wyrazy)
    #utwórz słownik zliczający liczbę powtórzeń trzech kolejnych wyrazów
    liczba_trzygramow = Counter(lista_trzech_wyrazow)
    #nadaj tytuł kolumnie zliaczania równy inicjałom i tytułowi książki
    if plik.find("Tadeusz Dolega-Mostowicz") > -1:
        autortytul = (f"TDM {plik.split(' - Tadeusz Dolega-Mostowicz')[0]}")
    else:
        autortytul = (f"JK {plik.split(' - Janusz Korczak')[0]}")
    #utwórz Dataframe (df) ze słownika
    df = pd.DataFrame(liczba_trzygramow.items(),columns = ["Trzygram",autortytul])
    #posortuj od najliczniej występującego trzygramu
    df = df.sort_values(by = autortytul, ascending = False)
    print(df.head(5))

Nadawanie tytułów zaczyna się w 34 linijce, oczywiście nie musimy tworzyć żadnego słownika w naszym przypadku, odpowiedni tytuł generowany jest na bieżąco ze zmiennej plik. Zobaczmy efekt:

======================== RESTART: F:\python38\wpis 14.py =======================
                  Trzygram  JK Bankructwo malego Dzeka
3415   pani powiedziała że                          11
6376            że się nie                           8
6761          żeby się nie                           8
33596            bo nie ma                           7
19972      z mister taftem                           7
               Trzygram  TDM Bracia Dalcz i S-ka
1479     w każdym razie                       55
5833       w ten sposób                       40
5596        w ogóle nie                       18
34019  w gruncie rzeczy                       17
6899      ze względu na                       17
              Trzygram  TDM Dr. Murek zredukowany
2719    w każdym razie                         30
711        w związku z                         12
20962         o tem że                         10
8289   spojrzał na nią                         10
8516      w ten sposób                          9
             Trzygram  TDM Drugie zycie doktora Murka
5274   w każdym razie                              20
18308  okazało się że                              12
301      w ten sposób                              12
4133         o tem że                              12
16694   w stosunku do                              11
              Trzygram  JK Dzieci ulicy
1696      w tej chwili               13
14253       ja wiem że                8
7526   po raz pierwszy                8
10562        się z nim                7
2717          co to za                7
           Trzygram  JK Dziecko salonu
3107     co to jest                 17
2879    ja nie chcę                 13
38766    od izby do                  9
38765   idę od izby                  9
38767  izby do izby                  9
          Trzygram  JK Kajtus Czarodziej
295     nie wie co                     9
1607      co to za                     9
1944    mu się nie                     8
4327     że nie ma                     7
6701  co się stało                     7
                     Trzygram  TDM Kariera Nikodema Dyzmy
8614  kochany panie nikodemie                          23
3510              che che che                          18
304                raz po raz                          15
5628               mu na myśl                          15
596             że pan prezes                          14
          Trzygram  JK Kiedy znow bede maly
606   nie wiem czy                       18
3759   nie wiem co                       13
6044  się zdaje że                       12
1009  sam nie wiem                       11
696       a ja się                       10
                Trzygram  TDM Kiwony
2206   do przekonania że          13
2783      w każdym razie          11
15278     okazało się że          10
22035       co się stało          10
8980           się z tym           9
                       Trzygram  JK Krol Macius na wyspie bezludnej
483        wasza królewska mość                                  27
44457           dziś popr forma                                  22
1196   waszej królewskiej mości                                  18
70            na bezludną wyspę                                  18
2723        na bezludnej wyspie                                  16
              Trzygram  TDM Pamietnik pani Hanki
2257    w każdym razie                        40
2899          o tym że                        28
5358    okazało się że                        22
4711     wydaje mi się                        22
2672  spojrzał na mnie                        22

>>> 

Świetnie! W następnej części spróbujemy zaoszczędzić czas i procesor.

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ź. To był bardzo długi rozdział, zadania są delikatne.

  1. Wyświetl typy danych naszego Dataframe, zmień typ danych liczby 3-gramów na string, jaki typ danych się wyświetli teraz?
  2. Znajdź sposób na zmianę nazw kolumn.
0 0 votes
Ocena artykułu

0 komentarzy
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
0
Chcesz podzielić się komentarzem?x