Knock 100 language processing publié sur la page Web du laboratoire Inui-Okazaki de l'Université de Tohoku pour la formation au traitement du langage naturel et Python. Je vais contester nlp100 /). Je prévois de prendre note du code implémenté et des techniques à supprimer. Le code sera également publié sur GitHub.
Seulement ici, je pense qu'il serait bon d'insérer une petite explication des commandes UNIX ainsi que Python.
Pour les options détaillées des commandes UNIX, consultez la commande man
ou le site Web d'ITpro, et vous l'apprendrez correctement!
hightemp.txt est un fichier qui stocke l'enregistrement de la température la plus élevée au Japon dans le format délimité par des tabulations de «préfecture», «point», «℃» et «jour». Créez un programme qui effectue le traitement suivant et exécutez hightemp.txt en tant que fichier d'entrée. De plus, exécutez le même processus avec une commande UNIX et vérifiez le résultat de l'exécution du programme.
Recevez le nombre naturel N au moyen d'arguments de ligne de commande et divisez le fichier d'entrée en N ligne par ligne. Réalisez le même traitement avec la commande de fractionnement.
16.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 16.py
import sys
def split_file(filename, number_of_parts):
with open(filename) as f:
lines = f.readlines()
if len(lines) % number_of_parts != 0:
raise Exception("Undividable by N=%d" % number_of_parts)
else:
number_of_lines = len(lines) / number_of_parts
for i in range(number_of_parts):
with open("split%s.txt" % str(i), "w") as w:
w.writelines(lines[number_of_lines * i: number_of_lines * (i + 1)])
if __name__ == '__main__':
try:
split_file(sys.argv[1], int(sys.argv[2]))
except Exception as err:
print("Error:", err)
La partie délicate lors de la division en N est lorsque le nombre d'origine de lignes n'est pas divisible par N. Je pense qu'il y a différentes choses à faire quand ce n'est pas divisible, mais cette fois j'essaierai de «lever» «Erreur».
Pour la gestion normale des exceptions
try:
#Traitement susceptible de provoquer une erreur
# ex) a = 10/0 (division zéro, ZeroDivisionError)
except [Nom de l'erreur]:
#Que faire lorsqu'une erreur se produit
# ex) print("Unable to divide by 0")Et
# except [Une erreur] as err:Si vous écrivez, le contenu de l'erreur est stocké dans e
finally:
#Traitement qui doit être effectué indépendamment de l'occurrence d'une erreur
Il peut être décrit sous la forme de. Cela fonctionne même si vous ne spécifiez pas le type d'erreur détecté dans la partie sauf, mais il est recommandé de le spécifier autant que possible. En effet, il devient un foyer de bogues car il récupère toutes les erreurs et permet de fonctionner (de force).
De plus, cette fois, je suis «élevé» par moi-même. Si je fais de mon mieux, je peux implémenter mes propres exceptions, mais je ne comprends toujours pas la classe Python, alors j'ai décidé d'utiliser l'exception existante cette fois.
Pour générer ʻError, écrivez
raise Exception ("Error message") . Ensuite, ʻError
est généré de force à cet endroit.
Cette fois, une erreur est générée lorsque le nombre de lignes du fichier n'est pas divisible par le nombre naturel «N».
if name == 'main':
J'ai aussi vu pour la première fois la description ʻif name == '__ main__': ʻet c'est devenu "?".
En écrivant ceci, lorsque ce programme est appelé directement, cette instruction ʻif sera exécutée. Inversement, s'il est appelé indirectement depuis un autre programme par ʻimport
etc., l'intérieur de l'instruction ʻif` n'est pas exécuté.
Dans l'article de Qiita, cette description a été fondamentalement omise, mais en raison de la gestion des exceptions, elle sera décrite ensemble cette fois.
//Lorsqu'il est divisé en trois, 24 ÷ 3=Un fichier est généré toutes les 8 lignes
$ split -l 8 hightemp.txt
$ ls
xaa xab xac hightemp.txt
$ cat xaa
Préfecture de Kochi Egawasaki 41 2013-08-12
(Omis...)
40 Katsunuma, préfecture de Yamanashi.5 2013-08-10
$ cat xab
40 Koshiya, Préfecture de Saitama.4 2007-08-16
(Omis...)
40 Sakata, préfecture de Yamagata.1 1978-08-03
$ cat xac
Mino 40, préfecture de Gifu 2007-08-16
(Omis...)
Préfecture d'Aichi Nagoya 39.9 1942-08-02
À l'origine, split
spécifie le nombre de lignes à fractionner, il semble donc difficile de spécifier directement N split. Je ne pouvais pas penser à une technique de division sur la ligne de commande, alors j'ai demandé à la personne d'entrée de calculer «24 ÷ N» et de spécifier l'option.
Recherchez le type de chaîne de caractères dans la première colonne (un ensemble de chaînes de caractères différentes). Utilisez les commandes sort et uniq pour confirmation.
17.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 17.py
import sys
filename = sys.argv[1]
prefectures = set()
with open(filename) as f:
line = f.readline()
while line:
prefectures.add(line.split()[0])
line = f.readline()
for pref in prefectures:
print(pref)
set
est un ensemble qui ne permet pas la duplication, donc cette fois il est parfait.
$ cut -f 1 hightemp.txt | sort | uniq
Préfecture de Chiba
Saitama
Préfecture d'Osaka
(Omis...)
Préfecture de Shizuoka
Préfecture de Kochi
Préfecture de Wakayama
Vous avez dit que vous utilisiez «sort» et «uniq », mais j'ai aussi utilisé« cut »parce que c'était un obstacle.
Intuitivement, je pense que cela ne peut être fait qu'avec ʻuniq, mais comme ʻuniq
fonctionne en supposant qu'il est trié, sort
est indispensable.
Disposez chaque ligne dans l'ordre inverse des nombres de la troisième colonne (Remarque: réorganisez le contenu de chaque ligne sans les changer). Utilisez la commande sort pour confirmation (ce problème ne doit pas nécessairement correspondre au résultat de l'exécution de la commande).
18.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 18.py
import sys
with open(sys.argv[1]) as f:
lines = f.readlines()
for line in sorted(lines, key=lambda x: x.split()[2], reverse=True):
print line,
L'affichage de tri dans la dernière instruction for
était précédemment traité au chapitre 1. A cette époque, je l'ai utilisé sans explication, mais cette fois je vais l'expliquer ici.
lambda
Il est facile de trier une chaîne spécifique de nombres, mais cette fois, nous devons trier par le nombre qui existe au milieu de la chaîne. Par conséquent, les critères de tri sont spécifiés à l'aide de la fonction anonyme «lambda». Il semble difficile d'entendre une fonction anonyme ou «lambda», mais c'est presque la même chose que les fonctions qui sont apparues jusqu'à présent, sauf qu'elles sont regroupées en une seule ligne.
#Calculer 3 fois 2
#Définition de la fonction par def
def double(x):
return x * 3
print double(2) # 6
#Définition de fonction par lambda
double = lambda x: x * 3
print double(2) #6
Dans cette implémentation, la fonction qui renvoie la troisième colonne de la chaîne de caractères reçue comme argument est exprimée par «lambda». Vous pouvez écrire rapidement des fonctions ad hoc, c'est donc très pratique si vous pouvez bien les utiliser.
sorted()
Comme son nom l'indique, c'est une fonction qui trie la liste. La liste reçue en argument est triée directement au lieu de la valeur de retour, soyez donc prudent lors de sa manipulation.
Vous pouvez basculer entre l'ordre croissant et décroissant avec «key» pour trier et «reverse».
$ sort -r -k 3 hightemp.txt
Préfecture de Kochi Egawasaki 41 2013-08-12
Préfecture de Gifu Tajimi 40.9 2007-08-16
40 Kumagai, Préfecture de Saitama.9 2007-08-16
(Omis...)
Toyonaka 39, Osaka.9 1994-08-08
Otsuki, Yamanashi 39.9 1990-07-19
39 Tsuruoka, Préfecture de Yamagata.9 1978-08-03
Préfecture d'Aichi Nagoya 39.9 1942-08-02
-r
spécifie l'ordre décroissant et -k 3
spécifie la troisième ligne.
Trouvez la fréquence d'apparition de la première colonne de chaque ligne, et affichez-les par ordre décroissant. Utilisez les commandes cut, uniq et sort pour confirmation.
19.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 19.py
import sys
from collections import defaultdict
filename = sys.argv[1]
prefectures = defaultdict(int)
with open(filename) as f:
line = f.readline()
while line:
prefectures[line.split()[0]] += 1
line = f.readline()
for k, v in sorted(prefectures.items(), key=lambda x: x[1], reverse=True):
print(k)
defaultdict
Le problème lorsque vous travaillez avec un dictionnaire est que vous ne pouvez pas écrire quelque chose comme dict [key] + = 1
pour une clé qui n'existe pas encore car la valeur initiale n'existe pas.
C'est «defaultdict» qui résout ce problème, et il est possible de déclarer des variables sous forme de définition de valeurs initiales.
Puisque nous avons spécifié ʻint` cette fois, la valeur initiale est 0, mais vous pouvez également définir une valeur initiale avec une forme plus compliquée. C'est très utile.
$ cut -f 1 hightemp.txt | sort | uniq -c | sort -r | cut -c 6-
Préfecture de Gunma
Préfecture de Yamanashi
Préfecture de Yamagata
(Omis...)
Préfecture de Kochi
Préfecture d'Ehime
Préfecture d'Osaka
--cut -f 1
Découpe la première colonne (nom de la préfecture)
--sort
Si vous ne triez pas, ʻuniq ne fonctionnera pas correctement, alors triez-le. --ʻUniq -c
Supprime les doublons et génère une ligne unique avec le nombre d'occurrences avant la suppression.
--sort -r
Puisqu'il s'agit du "plus grand nombre d'occurrences", il trie par ordre décroissant en fonction du nombre d'occurrences.
--cut -c 6-
Comme des espaces et des chaînes de caractères supplémentaires sont inclus au début de la ligne de résultat de sortie, le 6ème et les suivants sont affichés et les espaces sont supprimés.
C'est également une combinaison de commandes déjà apparues.
Passez au chapitre 3.
Recommended Posts