[PYTHON] 100 Sprachverarbeitung Knock 2020 Kapitel 2: UNIX-Befehle

Neulich wurde 100 Language Processing Knock 2020 veröffentlicht. Ich selbst arbeite erst seit einem Jahr an natürlicher Sprache und kenne die Details nicht, aber ich werde alle Probleme lösen und veröffentlichen, um meine technischen Fähigkeiten zu verbessern.

Alle müssen auf dem Jupyter-Notizbuch ausgeführt werden, und die Einschränkungen der Problemstellung können bequem verletzt werden. Der Quellcode ist auch auf Github. Ja.

Kapitel 1 ist hier.

Die Umgebung ist Python 3.8.2 und Ubuntu 18.04.

Ich denke, dass hier als Kommentarartikel leichter zu verstehen ist. Ich möchte, dass die Autoren Kommentarartikel bis Kapitel 10 schreiben.

Kapitel 2: UNIX-Befehle

popular-names.txt ist eine Datei, in der "Name", "Geschlecht", "Anzahl der Personen" und "Jahr" eines in den USA geborenen Babys in einem durch Tabulatoren getrennten Format gespeichert werden. Erstellen Sie ein Programm, das die folgende Verarbeitung ausführt, und führen Sie popular-names.txt als Eingabedatei aus. Führen Sie außerdem denselben Prozess mit einem UNIX-Befehl aus und überprüfen Sie das Ausführungsergebnis des Programms.

Bitte laden Sie den erforderlichen Datensatz von [hier] herunter (https://nlp100.github.io/ja/ch02.html).

Die heruntergeladene Datei wird unter "Daten" abgelegt.

10. Zählen der Anzahl der Zeilen

Zählen Sie die Anzahl der Zeilen. Verwenden Sie zur Bestätigung den Befehl wc.

Code


with open('data/popular-names.txt') as f:
    print(len(list(f)))

Ausgabe


2780

Finden Sie einfach die Länge des Dateiobjekts. Da das Dateiobjekt ein Iterator ist, muss es aufgelistet werden. Wenn die Eingabe eine ausreichend große Datei ist, passt sie möglicherweise nicht in den Speicher. In einem solchen Fall können Sie sie jedoch einfach mit der for-Anweisung drehen und zählen.

Code


wc -l < data/popular-names.txt

Ausgabe


2780

Ermitteln Sie die Anzahl der Zeilen, indem Sie die Option l im Befehl wc angeben. Wenn Sie einen Dateinamen angeben, werden verschiedene Extras angezeigt. Geben Sie ihn daher über die Standardeingabe an.

11. Ersetzen Sie die Registerkarten durch Leerzeichen

Ersetzen Sie jede Registerkarte durch ein Leerzeichen. Verwenden Sie zur Bestätigung den Befehl sed, den Befehl tr oder den Befehl expand.

Code


with open('data/popular-names.txt') as f:
    for line in f:
        line = line.strip()
        line = line.replace('\t', ' ')
        print(line)

Ausgabe(Erste 10 Zeilen)


Mary F 7065 1880
Anna F 2604 1880
Emma F 2003 1880
Elizabeth F 1939 1880
Minnie F 1746 1880
Margaret F 1578 1880
Ida F 1472 1880
Alice F 1414 1880
Bertha F 1320 1880
Sarah F 1288 1880

Jede Zeichenfolge, die durch Drehen des Dateiobjekts als Iterator erhalten wird, hat am Ende ein Zeilenvorschubzeichen. Entfernen Sie sie daher mit "strip" ("rstrip (" \ n ")" kann vorzuziehen sein). Ersetzen Sie einfach die Tabulatoren durch Leerzeichen und geben Sie sie aus.

Es gibt auch eine Methode zum Drucken (line, end = ''), ohne das Zeilenvorschubzeichen mit 'strip' zu entfernen.

Code


awk '{gsub("\t", " ", $0); print $0}' data/popular-names.txt
perl -pe 's/\t/ /g' data/popular-names.txt
sed 's/\t/ /g'  data/popular-names.txt
expand -t 1 data/popular-names.txt
tr '\t' ' ' < data/popular-names.txt

Die Ausgabe ist die gleiche wie die von Python, daher werde ich sie weglassen. (Gleiches gilt danach)

Ich kann mich nicht an viele UNIX-Befehle erinnern.

12. Speichern Sie die erste Spalte in col1.txt und die zweite Spalte in col2.txt

Speichern Sie nur die erste Spalte jeder Zeile als col1.txt und die zweite Spalte als col2.txt. Verwenden Sie zur Bestätigung den Befehl cut.

Code


with open('data/popular-names.txt') as f, \
        open('result/col1.txt', 'w') as g, \
        open('result/col2.txt', 'w') as h:
    for line in f:
        line = line.strip()
        pref, city, _, _  = line.split('\t')
        print(pref, file=g)
        print(city, file=h)

Ich habe es gehorsam geschrieben.

Ergebnis(col1.Die ersten 10 Zeilen von txt)


Mary
Anna
Emma
Elizabeth
Minnie
Margaret
Ida
Alice
Bertha
Sarah

Ergebnis(col2.Die ersten 10 Zeilen von txt)


F
F
F
F
F
F
F
F
F
F

Code


cut -f 1 data/popular-names.txt > col1.txt
cut -f 2 data/popular-names.txt > col2.txt

Mit dem Befehl cut ist das ganz einfach. Sie können auch "awk" {print $ 1} "verwenden.

13. Führen Sie col1.txt und col2.txt zusammen

Kombinieren Sie die in 12 erstellten Spalten col1.txt und col2.txt, um eine Textdatei zu erstellen, in der die erste und die zweite Spalte der Originaldatei tabulatorgetrennt angeordnet sind. Verwenden Sie zur Bestätigung den Befehl Einfügen.

Alles, was Sie tun müssen, ist, die beiden Dateien getrennt zu öffnen. Da dies jedoch eine große Sache ist, verwenden Sie contextlib.ExitStack, um es zu implementieren, damit Sie eine beliebige Anzahl von Dateien verarbeiten können. Für Kontextmanager → https://docs.python.org/ja/3/library/stdtypes.html#typecontextmanager

Code


from contextlib import ExitStack

Code


files = ['result/col1.txt', 'result/col2.txt']
with ExitStack() as stack:
    files = [stack.enter_context(open(filename)) for filename in files]
    for lines in zip(*files):
        x = [line.strip() for line in lines]
        x = '\t'.join(x)
        print(x)

Ergebnis(Erste 10 Zeilen)


Mary	F
Anna	F
Emma	F
Elizabeth	F
Minnie	F
Margaret	F
Ida	F
Alice	F
Bertha	F
Sarah	F

Code


paste result/col1.txt result/col2.txt

Mit dem Befehl Einfügen ist das ganz einfach.

14. Geben Sie N Zeilen von Anfang an aus

Empfangen Sie die natürliche Zahl N beispielsweise über ein Befehlszeilenargument und zeigen Sie nur die ersten N Zeilen der Eingabe an. Verwenden Sie zur Bestätigung den Befehl head.

Persönlich möchte ich Standardeingabe- und Befehlszeilenargumente mit "argparse" und "fileinput" erhalten, aber dieses Mal möchte ich den gesamten Code auf dem Jupyter-Notizbuch ausführen können, daher verwende ich Befehlszeilenargumente nicht. (Ich fühle Freundlichkeit zu "etc." in der Problemstellung)

Code


N = 5
with open('data/popular-names.txt') as f:
    lst = range(N)
    for _, line in zip(lst, f):
        print(line, end='')

Ausgabe


Mary	F	7065	1880
Anna	F	2604	1880
Emma	F	2003	1880
Elizabeth	F	1939	1880
Minnie	F	1746	1880

Sie können dasselbe mit dem Befehl head tun.

Code


head -n 5 data/popular-names.txt

15. Geben Sie die letzten N Zeilen aus

Empfangen Sie die natürliche Zahl N beispielsweise über ein Befehlszeilenargument und zeigen Sie nur die letzten N Zeilen der Eingabe an. Verwenden Sie zur Bestätigung den Befehl tail.

Ich denke, es ist in Ordnung, alle Standardeingaben in die Liste aufzunehmen und die letzten 5 Elemente zu extrahieren, aber wenn es sich um eine große Datei handelt, passt sie möglicherweise nicht in den Speicher, sodass ich die Warteschlange verwenden werde.

Code


from collections import deque

Code


N = 5
queue = deque([], 5)
with open('data/popular-names.txt') as f:
    for line in f:
        queue.append(line)
for line in queue:
    print(line, end='')

Ausgabe


Benjamin	M	13381	2018
Elijah	M	12886	2018
Lucas	M	12585	2018
Mason	M	12435	2018
Logan	M	12352	2018

Sie können dasselbe mit dem Befehl tail tun.

Code


tail -n 5 data/popular-names.txt

16. Teilen Sie die Datei in N.

Empfangen Sie die natürliche Zahl N mithilfe von Befehlszeilenargumenten und teilen Sie die Eingabedatei zeilenweise in N. Erzielen Sie die gleiche Verarbeitung mit dem Befehl split.

Ich denke, das liegt daran, dass es nicht viele Situationen gibt, in denen eine Datei zeilenweise in N Zeilen unterteilt wird, aber abhängig von der Implementierung des Befehls split gibt es möglicherweise keine N Unterteilungen in einer Zeile. Es kann sich um eine GNU-Erweiterung handeln.

Code(5 Abteilungen)


split -d -nl/5 data/popular-names.txt result/shell5.

Ergebnis(Überprüfen Sie die Anzahl der Zeilen mit wc)


  587  2348 11007 result/shell5.00
  554  2216 11010 result/shell5.01
  556  2224 11006 result/shell5.02
  540  2160 11007 result/shell5.03
  543  2172 10996 result/shell5.04
 2780 11120 55026 total

Ich habe es auch in Python implementiert, damit es sich genauso verhält wie der Code für diese GNU-Erweiterung (https://github.com/coreutils/coreutils/blob/master/src/split.c).

Code


def split_string_list(N, lst):
    chunk_size = sum([len(x) for x in lst]) // N
    chunk_ends = [chunk_size * (n + 1) - 1 for n in range(N)]
    
    i = 0
    acc = 0
    out = []
    for chunk_end in chunk_ends:
        tmp = []
        while acc < chunk_end:
            tmp.append(lst[i])
            acc += len(lst[i])
            i += 1
        out.append(tmp)
    return out

def split_file(N, filepath, outprefix):
    with open(filepath) as f:
        lst = list(f)
    lst = split_string_list(N, lst)
    for i, lines in enumerate(lst):
        idx = str(i).zfill(2) #Unterlassung
        with open(outprefix + idx, 'w') as f:
            f.write(''.join(lines))

split_file(5, 'data/popular-names.txt', 'result/python5.')

Zählen Sie zuerst die Gesamtzahl der Zeichen und bestimmen Sie die Schnittposition (chunk_ends), damit die Anzahl der Zeichen so einheitlich wie möglich ist. Dann dauert es eine Zeile, bis jedes Element von chunk_ends überschritten wird, und wenn es überschritten wird, wird es in eine Datei ausgegeben.

Ergebnis(Überprüfen Sie die Anzahl der Zeilen mit wc)


  587  2348 11007 result/python5.00
  554  2216 11010 result/python5.01
  556  2224 11006 result/python5.02
  540  2160 11007 result/python5.03
  543  2172 10996 result/python5.04
 2780 11120 55026 total

Ergebnis


diff result/python5.00 result/shell5.00
diff result/python5.01 result/shell5.01
diff result/python5.02 result/shell5.02
diff result/python5.03 result/shell5.03
diff result/python5.04 result/shell5.04

Ich habe das gleiche Ergebnis erzielt.

17. Unterschied in der Zeichenfolge in der ersten Spalte

Suchen Sie den Typ der Zeichenfolge in der ersten Spalte (eine Reihe verschiedener Zeichenfolgen). Verwenden Sie zur Bestätigung die Befehle cut, sort und uniq.

Code


names = set()
with open('data/popular-names.txt') as f:
    for line in f:
        name = line.split('\t')[0]
        names.add(name)
names = sorted(names)

for name in names:
    print(name)

Ergebnis(Erste 10 Zeilen)


Abigail
Aiden
Alexander
Alexis
Alice
Amanda
Amelia
Amy
Andrew
Angela

Die erste Spalte wird der Reihe in der Reihenfolge hinzugefügt, sortiert und ausgegeben. (* Die Version von Python ist 3.8.2.)

Code


cut -f 1 data/popular-names.txt | sort -s | uniq 

Nehmen Sie nur die erste Spalte und sortieren Sie, um Duplikate zu entfernen. Wenn Sie vergessen, die Sortierung einzugeben, ist dies seltsam. Zusätzlich wird die Option s hinzugefügt, um eine stabile Sortierung nach Python zu gewährleisten.

18. Sortieren Sie jede Zeile in absteigender Reihenfolge der Zahlen in der dritten Spalte

Ordnen Sie jede Zeile in umgekehrter Reihenfolge der Zahlen in der dritten Spalte an (Hinweis: Ordnen Sie den Inhalt jeder Zeile neu an, ohne ihn zu ändern). Verwenden Sie den Befehl sort zur Bestätigung (dieses Problem muss nicht mit dem Ergebnis der Ausführung des Befehls übereinstimmen).

Code


with open('data/popular-names.txt') as f:
    lst = [line.strip() for line in f]
lst.sort(key = lambda x : -int(x.split('\t')[2]))
    
for line in lst[:10]:
    print(line)

Ausgabe(Erste 10 Zeilen)


Linda	F	99689	1947
Linda	F	96211	1948
James	M	94757	1947
Michael	M	92704	1957
Robert	M	91640	1947
Linda	F	91016	1949
Michael	M	90656	1956
Michael	M	90517	1958
James	M	88584	1948
Michael	M	88528	1954

Durch Angabe des Schlüssels der Funktion "Sortieren" können Sie die Kriterien für das Sortieren angeben.

Code


sort -nrsk 3 data/popular-names.txt

Sie können dies nur mit dem Befehl sort tun. Es ist einfach.

19. Ermitteln Sie die Häufigkeit des Auftretens der Zeichenfolge in der ersten Spalte jeder Zeile und ordnen Sie sie in absteigender Reihenfolge der Häufigkeit des Auftretens an.

Ermitteln Sie die Häufigkeit des Auftretens der ersten Spalte jeder Zeile und zeigen Sie sie in absteigender Reihenfolge an. Verwenden Sie zur Bestätigung die Befehle cut, uniq und sort.

Verwenden Sie collection.Counter.

Code


from collections import Counter

Code


cnt = Counter()
with open('data/popular-names.txt') as f:
    for line in f:
        name = line.split('\t')[0]
        cnt.update([name])
        
lst = cnt.most_common()
lst.sort(key=lambda x:(-x[1], x[0]))

for name, num in lst[:10]:
    print(name)

Ausgabe


James
William
John
Robert
Mary
Charles
Michael
Elizabeth
Joseph
Margaret

Übergeben Sie die Liste entweder unverändert an das Objekt "Counter" oder übergeben Sie sie nach und nach mit "update ()". most_common () ordnet sie in absteigender Reihenfolge an.

Code


cut -f 1 data/popular-names.txt | sort | uniq -c | sort -nrsk1 | awk '{print $2}'

Wenn Sie die Option "-c" hinzufügen, wenn Sie "uniq" nehmen, wird gezählt, wie viele es gibt. Zum Schluss sortieren Sie nach Zahlen, um das gewünschte Ergebnis zu erhalten.

Weiter ist Kapitel 3

Sprachverarbeitung 100 Schläge 2020 Kapitel 3: Reguläre Ausdrücke

Recommended Posts

100 Sprachverarbeitung Knock 2020 Kapitel 2: UNIX-Befehle
100 Sprachverarbeitung Knock UNIX-Befehle in Kapitel 2
[Sprachverarbeitung 100 Schläge 2020] Kapitel 2: UNIX-Befehle
100 Sprachverarbeitung Knock 2020 Kapitel 1
100 Sprachverarbeitung Knock Kapitel 1
100 Sprachverarbeitung Knock 2020 Kapitel 3
100 Sprachverarbeitung Knock 2020 Kapitel 2
100 Sprachverarbeitung Knock Kapitel 1 (Python)
100 Sprachverarbeitung Knock Kapitel 2 (Python)
Ich habe versucht, die Version 2020 mit 100 Sprachverarbeitung zu lösen [Kapitel 2: UNIX-Befehle 10-14]
Ich habe versucht, die Version 2020 mit 100 Sprachverarbeitung zu lösen [Kapitel 2: UNIX-Befehle 15-19]
100 Sprachverarbeitung Knock 2015 Kapitel 5 Abhängigkeitsanalyse (40-49)
100 Sprachverarbeitungsklopfen mit Python (Kapitel 1)
100 Sprachverarbeitung Knock Kapitel 1 in Python
100 Sprachverarbeitung Knock 2020 Kapitel 4: Morphologische Analyse
100 Sprachverarbeitung Knock 2020 Kapitel 9: RNN, CNN
100 Sprachverarbeitungsklopfen (2020): 28
Ich habe versucht, 100 Sprachverarbeitung klopfen 2020: Kapitel 3
100 Sprachverarbeitungsklopfen mit Python (Kapitel 3)
100 Sprachverarbeitungsklopfen: Kapitel 1 Vorbereitungsbewegung
100 Sprachverarbeitung Knock 2020 Kapitel 6: Maschinelles Lernen
100 Sprachverarbeitung Knock Kapitel 4: Morphologische Analyse
100 Sprachverarbeitung Knock 2020 Kapitel 10: Maschinelle Übersetzung (90-98)
100 Sprachverarbeitung Knock: Kapitel 2 UNIX-Befehlsgrundlagen (mit Pandas)
100 Sprachverarbeitung Knock 2020 Kapitel 5: Abhängigkeitsanalyse
100 Sprachverarbeitung Knock 2020 Kapitel 7: Word Vector
100 Sprachverarbeitung Knock 2020 Kapitel 8: Neuronales Netz
100 Sprachverarbeitungsklopfen (2020): 38
Ich habe versucht, 100 Sprachverarbeitung klopfen 2020: Kapitel 1
100 Sprachverarbeitung klopfen 00 ~ 02
100 Sprachverarbeitung Knock 2020 Kapitel 1: Vorbereitende Bewegung
100 Sprachverarbeitung Knock Kapitel 1 von Python
100 Sprachverarbeitung Knock 2020 Kapitel 3: Reguläre Ausdrücke
100 Language Processing Knock 2015 Kapitel 4 Morphologische Analyse (30-39)
Ich habe versucht, 100 Sprachverarbeitung zu klopfen 2020: Kapitel 2
Ich habe versucht, 100 Sprachverarbeitung zu klopfen 2020: Kapitel 4
100 Klicks in der Verarbeitung natürlicher Sprache Kapitel 2 Grundlagen des UNIX-Befehls (zweite Hälfte)
100 Klicks in der Verarbeitung natürlicher Sprache Kapitel 2 Grundlagen des UNIX-Befehls (erste Hälfte)
Ich habe mit GiNZA v3.1 Kapitel 4 100 Sprachverarbeitungsklopfen 2020 durchgeführt
100 Sprachverarbeitungsklopfen mit Python (Kapitel 2, Teil 2)
100 Sprachverarbeitungsklopfen mit Python (Kapitel 2, Teil 1)
[Programmierer-Neuling "100 Sprachverarbeitung klopfen 2020"] Lösen Sie Kapitel 1
100 Sprachverarbeitung klopfen 2020 [00 ~ 39 Antwort]
100 Sprachverarbeitung klopfen 2020 [00-79 Antwort]
100 Sprachverarbeitung klopfen 2020 [00 ~ 69 Antwort]
100 Amateur-Sprachverarbeitungsklopfen: 17
100 Sprachverarbeitung klopfen 2020 [00 ~ 49 Antwort]
100 Sprachverarbeitung Knock-52: Stemming
100 Sprachverarbeitungsklopfen ~ Kapitel 1
100 Amateur-Sprachverarbeitungsklopfen: 07
100 Sprachverarbeitung klopft Kapitel 2 (10 ~ 19)
100 Amateur-Sprachverarbeitungsklopfen: 09
100 Amateur-Sprachverarbeitungsklopfen: 47
100 Sprachverarbeitung Knock-53: Tokenisierung
100 Amateur-Sprachverarbeitungsklopfen: 97
100 Sprachverarbeitung klopfen 2020 [00 ~ 59 Antwort]
100 Amateur-Sprachverarbeitungsklopfen: 67
100 Sprachverarbeitung Klopfen Sie auf reguläre Ausdrücke, die Sie in Kapitel 3 gelernt haben
100 Sprachverarbeitungsklopfen mit Python 2015
100 Sprachverarbeitung Knock-51: Wortausschnitt
100 Sprachverarbeitung Knock-58: Extraktion von Taple