Sei sulla pagina 1di 605

Pagina 1

Testo originale
Contribuisci a una traduzione migliore

Pagina 2

tory

foto
Python per
® programmatori

arning Pat

fers & Dea

hlights

ttings

Supporto

Disconnessione

Pagina 3

Playlist
®
Deitel Developer Series
storia

Python per programmatori


opiche

guadagnando Pat
Paul Deitel
Harvey Deitel
ffers & Dea

ighlights

ettings

Supporto

Disconnessione

Pagina 4

Playlist

storia

Molte delle denominazioni utilizzate da produttori e venditori per distinguere i propri


opiche
i prodotti sono rivendicati come marchi. Dove appaiono queste designazioni in questo libro, e
l'editore era a conoscenza di una rivendicazione di marchio, le denominazioni sono state stampate
guadagnando Pat
lettere maiuscole iniziali o in tutte le maiuscole.

ffers & Dea


Gli autori e l'editore hanno curato la preparazione di questo libro, ma fanno no
garanzia espressa o implicita di qualsiasi tipo e non si assume alcuna responsabilità per errori o
ighlights
omissioni. Non si assume alcuna responsabilità per danni incidentali o consequenziali in
collegamento con o derivante dall'uso delle informazioni o dei programmi contenuti
ettings
qui.

Supporto
Per informazioni sull'acquisto di questo titolo in grandi quantità o per vendite speciali
opportunità
Disconnessione (che possono includere versioni elettroniche; design di copertine personalizzate; e
contenuti specifici per la tua attività, obiettivi di formazione, obiettivi di marketing o branding
interessi), contatta il nostro reparto vendite aziendale al numero orpsales@pearsoned.com
o (800) 3823419.

Per richieste di informazioni sulle vendite governative, contattare


overnmentsales@pearsoned.com .

Per domande sulle vendite al di fuori degli Stati Uniti, contattare ntlcs@pearson.com .

Visitateci sul Web: informit.com

Numero di controllo della Library of Congress: 2019933267

Copyright © 2019 Pearson Education, Inc.

Tutti i diritti riservati. Questa pubblicazione è protetta da copyright e l'autorizzazione deve esserlo
ottenuto dall'editore prima di qualsiasi riproduzione vietata, archiviazione in un recupero
sistema, o trasmissione in qualsiasi forma o con qualsiasi mezzo, elettronico, meccanico,
fotocopiatura, registrazione o altro. Per informazioni sui permessi, richiedere
moduli e i contatti appropriati all'interno di Pearson Education Global Rights &
Dipartimento permessi, visita ww.pearsoned.com/permissions/ .

gc
io
w
Pagina 5
eitel e il bug doublethumbsup sono marchi registrati di Deitel e
Associates, Inc.

Logo Python per gentile concessione di Python Software Foundation.

Cover design di Paul Deitel, Harvey Deitel e Chuti Prasertsith


Cover art di Agsandrew / Shutterstock

ISBN13: 9780135224335
ISBN10: 0135224330

1 19
D
Pagina 6

le liste

ory
reface
1

" C'è dell'oro in quelle colline thar!"


ics

1
Fonte sconosciuta, spesso attribuita erroneamente a Mark Twain.
rning Pat

Benvenuto in Python per programmatori ! In questo libro imparerai a fare pratica con la maggior parte di oggi
rs & Dea
tecnologie di elaborazione avvincenti e all'avanguardia e programmerai in Python, uno dei
le lingue più popolari al mondo e quelle in più rapida crescita tra loro.
hlights

Gli sviluppatori spesso scoprono rapidamente che gli piace Python. Apprezzano la sua forza espressiva,
ings
leggibilità, concisione e interattività. A loro piace il mondo del software opensource
sviluppo che sta generando una base in rapida crescita di software riutilizzabile per un enorme
Supporto
gamma di aree di applicazione.

Disconnessione
Per molti decenni sono state in atto alcune tendenze potenti. L'hardware del computer è rapidamente
sta diventando più veloce, più economico e più piccolo. La larghezza di banda di Internet è aumentata rapidamente
e più economico. E il software per computer di qualità è diventato sempre più abbondante ed essenzialmente
libero o quasi gratuito attraverso il movimento “open source”. Presto, l '"Internet of Things" lo farà
connettere decine di miliardi di dispositivi di ogni tipo immaginabile. Questi genereranno enormi
volumi di dati a velocità e quantità in rapido aumento.

Nel calcolo di oggi, le ultime innovazioni sono “interamente circa i dati” - i dati della scienza, dei dati
analisi, grandi dati , relazionali dati basi (SQL), e NoSQL e NewSQL dati basi, ognuna delle
che affrontiamo insieme a un trattamento innovativo della programmazione Python.

LAVORI CHE RICHIEDONO COMPETENZE DI DATA SCIENCE


Nel 2011, il McKinsey Global Institute ha prodotto il rapporto "Big data: The next frontier for
innovazione, concorrenza e produttività. " In esso, hanno detto, "Gli Stati Uniti da soli devono affrontare un
carenza di 140.000-190.000 persone con capacità analitiche profonde e 1,5 milioni
. . 2
manager e analisti per analizzare i big data e prendere decisioni in base ai risultati ".
Questo continua ad essere il caso. Il "LinkedIn Workforce Report" dell'agosto 2018 afferma che gli Stati Uniti
3
States ha una carenza di oltre 150.000 persone con competenze di data science . Un rapporto del 2017 da
IBM, Burning Glass Technologies e BusinessHigher Education Forum, lo afferma da
Nel 2020 negli Stati Uniti ci saranno centinaia di migliaia di nuovi posti di lavoro che richiedono dati
4
abilità scientifiche.

ttps: //www.mckinsey.com/~/media/McKinsey/Business%20Functions/McKinsey%20Digital/Our%20I attrazioni / Bi


pagina 3).

3
ttps: //economicgraph.linkedin.com/resources/linkedinworkforce
eportaugust2018 .

4
ttps: //www.burningglass.com/wp

ontent / uploads / The_Quant_Crunch.pdf (pagina 3).

ARCHITETTURA MODULARE
L'architettura modulare del libro (vedere il grafico del sommario sul file
copertina interna del libro) ci aiuta a soddisfare le diverse esigenze di diversi pubblici professionisti.

hapters 1 - 0 copre la programmazione Python. Ciascuno di questi capitoli include una breve introduzione a
Sezione di Data Science che introduce l'intelligenza artificiale, le statistiche descrittive di base,
misure di tendenza centrale e dispersione, simulazione, visualizzazione statica e dinamica,
lavorare con file CSV, panda per l'esplorazione dei dati e il data wrangling, serie temporali e

P c(1C
hrn
implementare la regressione lineare. Questi ti aiutano a prepararti per la scienza dei dati, l'IA, i big data e il cloud Pagina 7
casi di studio in hapters 11 - 6 , che offrono opportunità per utilizzare il mondo reale
set di dati in studi di casi completi.

Dopo aver coperto Python hapters 1 - 5 e alcune parti chiave di hapters 6 - 7 , sarete in grado di

gestire porzioni significative dei casi di studio in hapters 11 - 6 . Il capitolo


La sezione Dipendenze "di questa Prefazione aiuterà i formatori a pianificare i loro corsi professionali in
contesto dell'architettura unica del libro.

hapters 11 - 6 sono caricati con esempi interessanti, potenti e contemporanei. Presentano le mani
sull'implementazione di casi di studio su argomenti come l'elaborazione del linguaggio naturale, i dati
estrazione di Twitter, elaborazione cognitiva con Watson di IBM, macchina supervisionata
apprendimento con classificazione e regressione, apprendimento automatico senza supervisione con
clustering, deep learning con reti neurali convoluzionali, deep learning
con reti neurali ricorrenti, big data con Hadoop, Spark e NoSQL
database, Internet of Things e altro ancora. Lungo la strada, acquisirai un ampio
alfabetizzazione dei termini e dei concetti della scienza dei dati, che vanno da brevi definizioni all'utilizzo di concetti
in programmi piccoli, medi e grandi. Sfogliare l'indice dettagliato del libro e
Index ti darà un'idea dell'ampiezza della copertura.

CARATTERISTICHE PRINCIPALI

KIS (Keep It Simple), KIS (Keep it Small), KIT (Keep it Topical)

Sii semplice: in ogni aspetto del libro ci impegniamo per la semplicità e la chiarezza. Per
Ad esempio, quando presentiamo l'elaborazione del linguaggio naturale, usiamo il semplice e intuitivo
Libreria TextBlob piuttosto che il più complesso NLTK. Nel nostro apprendimento profondo
presentazione, preferiamo Keras a TensorFlow. In generale, quando più biblioteche potrebbero
essere utilizzato per eseguire compiti simili, usiamo quello più semplice.

Mantenerlo piccolo: la maggior parte dei 538 esempi del libro sono piccoli, spesso solo poche righe di

codice, con feedback IPython interattivo immediato. Includiamo anche 40 script più grandi
e studi di casi approfonditi.

Attualità: leggiamo decine di libri recenti di programmazione e scienza dei dati Python,
e sfogliato, letto o guardato circa 15.000 articoli correnti, documenti di ricerca, bianchi
documenti, video, post di blog, post di forum e documenti. Questo ci ha permesso di farlo
"Prendi il polso" di Python, informatica, scienza dei dati, intelligenza artificiale, big data e cloud
comunità.

Feedback immediato: esplorazione, scoperta e sperimentazione con IPython

Il modo ideale per imparare da questo libro è leggerlo ed eseguire gli esempi di codice in parallelo.
In tutto il libro, utilizziamo l'interprete IPython, che fornisce un amichevole,
modalità interattiva di feedback immediato per esplorare, scoprire e
sperimentare con Python e le sue vaste librerie.

La maggior parte del codice è presentata in piccole sessioni IPython interattive. Per ogni codice
snippet che scrivi, IPython lo legge immediatamente, lo valuta e stampa i risultati. Questo
il feedback istantaneo mantiene la tua attenzione, aumenta l'apprendimento, facilita la prototipazione rapida
e accelera il processo di sviluppo del software.

I nostri libri sottolineano sempre l'approccio livecode, concentrandosi sul completo, funzionante
programmi con ingressi e uscite live. La "magia" di IPython è che trasforma anche frammenti
in codice che "prende vita" quando si immette ogni riga. Questo promuove l'apprendimento e
incoraggia la sperimentazione.

Fondamenti di programmazione Python

Innanzitutto, questo libro fornisce una ricca copertura di Python.

Discutiamo i modelli di programmazione di Python: programmazione procedurale, funzionale

1
C
S
programmazione del tipo e programmazione orientata agli oggetti. Pagina 8

Usiamo le migliori pratiche, sottolineando l'idioma corrente.

La programmazione in stile funzionale viene utilizzata in tutto il libro come appropriato. Un grafico
nel il capitolo 4 elenca la maggior parte delle capacità di programmazione in stile funzionale chiave di Python e il
capitoli in cui inizialmente trattiamo la maggior parte di essi.

538 Esempi di codici

Con 538 riceverai un'introduzione coinvolgente, stimolante e divertente a Python


esempi del mondo reale che vanno dai singoli frammenti al computer sostanziale
scienza, scienza dei dati, intelligenza artificiale e casi di studio sui big data.

Attaccherai attività significative con AI, big data e tecnologie cloud come naturale
elaborazione del linguaggio, data mining Twitter, machine learning, deep learning,
Hadoop, MapReduce, Spark, IBM Watson, librerie di data science chiave (NumPy,
panda, SciPy, NLTK, TextBlob, spaCy, Textatistic, Tweepy, Scikitlearn,
Keras), librerie di visualizzazione chiave (Matplotlib, Seaborn, Folium) e altro ancora.

Evita la matematica pesante a favore delle spiegazioni in inglese

Catturiamo l'essenza concettuale della matematica e la mettiamo al lavoro nel nostro


esempi. Lo facciamo utilizzando librerie come statistiche, NumPy, SciPy, panda e
molti altri, che nascondono la complessità matematica. Quindi, è semplice per te
ottenere molti dei vantaggi delle tecniche matematiche come la regressione lineare senza
dover conoscere la matematica dietro di loro. Nell'apprendimento automatico e nel profondo
esempi di apprendimento, ci concentriamo sulla creazione di oggetti che fanno i conti per te "dietro il
scene. "

Visualizzazioni

67 visualizzazioni statiche, dinamiche, animate e interattive (grafici, grafici,


immagini, animazioni, ecc.) aiutano a comprendere i concetti.

Piuttosto che includere una trattazione della programmazione grafica di basso livello, ci concentriamo su quello alto
visualizzazioni di livello prodotte da Matplotlib, Seaborn, pandas e Folium (per
mappe interattive).

Usiamo le visualizzazioni come strumento pedagogico. Ad esempio, facciamo la legge del grande
i numeri "prendono vita" in una simulazione dinamica del dierolling e in un grafico a barre. Come la
numero di tiri aumenta, vedrai gradualmente la percentuale di ogni faccia sul totale dei tiri
avvicinarsi al 16,667% (1/6) e le dimensioni delle barre che rappresentano le percentuali si equalizzano.

Le visualizzazioni sono fondamentali nei big data per l'esplorazione e la comunicazione dei dati
risultati di ricerca riproducibili, in cui gli elementi di dati possono essere milioni,
5
miliardi o più. Un detto comune è che un'immagine vale più di mille parole —In grande
dati, una visualizzazione potrebbe valere miliardi, trilioni o anche più elementi in un database.
Le visualizzazioni consentono di "volare a 40.000 piedi sopra i dati" per vederli "in grande" e verso
conoscere i tuoi dati. Le statistiche descrittive aiutano ma possono essere fuorvianti. Per esempio,
6
Il quartetto di Anscombe dimostra attraverso visualizzazioni significativamente differenti
i set di dati possono avere statistiche descrittive quasi identiche .

ttps: //en.wikipedia.org/wiki/A_picture_is_worth_a_thousand_words .

6
ttps: //en.wikipedia.org/wiki/Anscombe%27s_quartet .

Mostriamo il codice di visualizzazione e animazione in modo che tu possa implementare il tuo. Anche noi
fornire le animazioni nei file codice sorgente e come Jupyter Notebook, così puoi
personalizzare comodamente il codice ei parametri di animazione, rieseguire le animazioni
e vedere gli effetti dei cambiamenti.

Esperienze di dati

S
C
h
Esperienze di dati
Le nostre sezioni Intro to Data Science e casi di studio in hapters 11 - 6 fornire ricchi Pagina 9
esperienze di dati.

Lavorerai con molti set di dati e origini dati del mondo reale. C'è un enorme
varietà di set di dati aperti gratuiti disponibili online con cui sperimentare. Alcuni dei
i siti a cui facciamo riferimento elencano centinaia o migliaia di set di dati.

Molte librerie che utilizzerai vengono fornite in bundle con set di dati popolari per la sperimentazione.

Imparerai i passaggi necessari per ottenere i dati e prepararli per l'analisi, analizzare quei dati
utilizzando molte tecniche, sintonizza i tuoi modelli e comunica i risultati in modo efficace,
soprattutto attraverso la visualizzazione.

GitHub

GitHub è un luogo eccellente per trovare codice opensource da incorporare nel tuo file
progetti (e per contribuire con il tuo codice alla comunità opensource). È anche cruciale
elemento dell'arsenale dello sviluppatore di software con strumenti di controllo della versione che aiutano i team di
gli sviluppatori gestiscono progetti opensource (e privati).

Utilizzerai una straordinaria gamma di Python e data science gratuiti e opensource


biblioteche e offerte gratuite, gratuite e freemium di software e servizi cloud.
Molte delle librerie sono ospitate su GitHub.

Cloud Computing pratico

Gran parte dell'analisi dei big data avviene nel cloud, dove è facile scalare dinamicamente il file
quantità di hardware e software di cui hanno bisogno le applicazioni. Lavorerai con vari cloud
servizi basati (alcuni direttamente e alcuni indirettamente), inclusi Twitter, Google
Translate, IBM Watson, Microsoft Azure, OpenMapQuest, geopy, Dweet.io e
PubNub.

• Ti invitiamo a utilizzare servizi cloud gratuiti, di prova gratuiti o freemium. Preferiamo quelli che
non hai bisogno di una carta di credito perché non vuoi rischiare di incappare accidentalmente in bollette elevate.
Se decidi di utilizzare un servizio che richiede una carta di credito, assicurati che il livello
che stai utilizzando gratuitamente non passerà automaticamente a un livello a pagamento.

Database, Big Data e Infrastruttura Big Data

Secondo IBM (novembre 2016), il 90% dei dati mondiali è stato creato negli ultimi due anni.
7
Le prove indicano che la velocità di creazione dei dati sta rapidamente accelerando.

ttps: //public.dhe.ibm.com/common/ssi/ecm/wr/en/wrl12345usen/watson
il coinvolgimento del clientewatsonmarketingwrotherpaperandreports

rl12345usen20170719.pdf .

Secondo un articolo di AnalyticsWeek di marzo 2016 , entro cinque anni ce ne saranno più di 50
miliardi di dispositivi connessi a Internet e entro il 2020 produrremo 1,7 megabyte di
8
nuovi dati ogni secondo per ogni persona sul pianeta !

8
ttps: //analyticsweek.com/content/bigdatafacts/ .

Includiamo un trattamento di database relazionali e SQL con SQLite.

I database sono infrastrutture critiche per big data per l'archiviazione e la manipolazione di file
enormi quantità di dati che elaborerai. I database relazionali elaborano dati strutturati -
non sono orientati ai dati non strutturati e semistrutturati nelle applicazioni big data.
Quindi, con l'evoluzione dei big data, sono stati creati database NoSQL e NewSQL per gestirli
dati in modo efficiente. Includiamo una panoramica di NoSQL e NewSQL e un caso di studio pratico
con un database di documenti JSON MongoDB. MongoDB è il NoSQL più popolare
Banca dati.

Discutiamo di infrastrutture hardware e software per big data in capitolo 16 , " ig

1w
C
hB
ata: Hadoop, Spark, NoSQL e IoT (Internet of Things). " Pagina 10

Casi di studio sull'intelligenza artificiale

In caso di studio hapters 11 - 5 , presentiamo argomenti di intelligenza artificiale, tra cui


elaborazione del linguaggio naturale, estrazione di dati da Twitter per eseguire il sentiment
analisi, cognitive computing con IBM Watson, macchina supervisionata
learning, machine learning non supervisionato e deep learning. capitolo 16 regali
l'infrastruttura hardware e software per big data che consente agli scienziati informatici e
data scientist per implementare soluzioni all'avanguardia basate su IA.

Raccolte incorporate: elenchi, tuple, set, dizionari

Ci sono poche ragioni oggi per la maggior parte degli sviluppatori di applicazioni per creare dati personalizzati

strutture. Il libro presenta una ricca trattazione in due capitoli del builtin di Python
strutture di dati - elenchi, tuple, dizionari e set - con cui la maggior parte dei dati
compiti di strutturazione possono essere realizzati.

Programmazione orientata agli array con NumPy Arrays e Panda


Serie / DataFrames

Ci concentriamo anche su tre strutture di dati chiave dalle librerie opensource: array NumPy,
pandas Series e panda DataFrames. Questi sono ampiamente utilizzati nella scienza dei dati,

informatica, intelligenza artificiale e big data. NumPy offre fino a due ordini
di magnitudo maggiori prestazioni rispetto agli elenchi Python incorporati.

Includiamo in nel capitolo 7 una ricca trattazione degli array NumPy. Molte biblioteche, come

panda, sono costruiti su NumPy. Le sezioni Intro to Data Science in hapters 7 - 9

introdurre panda Series e DataFrames, che insieme agli array NumPy sono quindi

utilizzato in tutti i capitoli rimanenti.

Elaborazione di file e serializzazione

il capitolo 9 presenta l'elaborazione dei file di testo, quindi mostra come serializzare gli oggetti
utilizzando il popolare formato JSON (JavaScript Object Notation). Viene utilizzato JSON
frequentemente nei capitoli della scienza dei dati.

Molte librerie di data science forniscono funzionalità integrate di elaborazione dei file per il caricamento
set di dati nei tuoi programmi Python. Oltre ai file di testo semplice, elaboriamo i file nel formato
popolare formato CSV (valori separati da virgole) che utilizza lo standard Python
Modulo csv della libreria e funzionalità della libreria di data science pandas.

Programmazione basata su oggetti

Sottolineiamo l'utilizzo dell'enorme numero di classi preziose offerte dall'opensource di Python


community è stato impacchettato in librerie di classi standard del settore. Ti concentrerai sulla conoscenza
quali librerie ci sono, scegliere quelle che ti serviranno per le tue app, creare oggetti
dalle classi esistenti (di solito in una o due righe di codice) e facendole “saltare, ballare

e canta. " Questo oggetto base di programmazione consente di creare impressionante


applicazioni in modo rapido e conciso, il che è una parte significativa del fascino di Python.

Con questo approccio, sarai in grado di utilizzare l'apprendimento automatico, il deep learning e altre AI
tecnologie per risolvere rapidamente un'ampia gamma di problemi intriganti, compresi quelli cognitivi
sfide informatiche come il riconoscimento vocale e la visione artificiale.

Programmazione orientata agli oggetti

Lo sviluppo di classi personalizzate è un'abilità di programmazione orientata agli oggetti cruciale, insieme
con ereditarietà, polimorfismo e dattilografia. Ne discutiamo in capitolo 10 .

il capitolo 10 include una discussione sui test unitari con doctest e una scheda divertente
simulazione di mescolamento e scambio.

1D
C
hapters 11 - 6 richiedono solo poche semplici definizioni di classi personalizzate. In Python, Pagina 11
probabilmente utilizzerai più un approccio di programmazione basato su oggetti rispetto a un oggetto fullout
programmazione orientata.

Riproducibilità

Nelle scienze in generale, e nella scienza dei dati in particolare, è necessario riprodurre il file
risultati di esperimenti e studi e per comunicare tali risultati in modo efficace. Jupyter
I taccuini sono un mezzo preferito per farlo.
Discutiamo della riproducibilità in tutto il libro nel contesto della programmazione
tecniche e software come Jupyter Notebooks e Docker.

Prestazione

Usiamo lo strumento di profilazione% timeit in diversi esempi per confrontare le prestazioni di


approcci diversi per eseguire le stesse attività. Altre prestazioni correlate
le discussioni includono espressioni del generatore, array NumPy e elenchi Python, prestazioni di
modelli di machine learning e deeplearning e Hadoop e Spark distribuiti
prestazioni di calcolo.

Big Data e parallelismo

In questo libro, invece di scrivere il tuo codice di parallelizzazione, lascerai che le librerie apprezzino
Keras in esecuzione su TensorFlow e strumenti per big data come Hadoop e Spark parallelizzano
operazioni per te. In questa era di big data / intelligenza artificiale, i requisiti di elaborazione sono enormi
le applicazioni dati richiedono di sfruttare il vero parallelismo fornito dal multicore
processori, unità di elaborazione grafica (GPU), unità di elaborazione tensoriale (TPU)
ed enormi cluster di computer nel cloud. Alcune attività di big data potrebbero avere
migliaia di processori che lavorano in parallelo per analizzare enormi quantità di dati
rapidamente.

CAPITOLO DIPENDENZE
Se sei un formatore che pianifica il tuo programma per un corso di formazione professionale o uno sviluppatore
decidendo quali capitoli leggere, questa sezione ti aiuterà a prendere le decisioni migliori. per favore
leggete l'indice a colori di una pagina sulla copertina interna del libro: questo lo farà
familiarizzare rapidamente con l'architettura unica del libro. Insegnare o leggere i capitoli
in ordine è più semplice. Tuttavia, gran parte del contenuto delle sezioni Intro to Data Science in

estremità di hapters 1 - 0 e gli studi di casi in hapters 11 - 6 richiede solo hapters 1 - 5

e piccole porzioni di hapters 6 - 0 come discusso di seguito.

Parte 1: Guida introduttiva ai concetti fondamentali di Python

Ti consigliamo di leggere tutti i capitoli in ordine:

il capitolo 1 , Introduzione a computer e Python, introduce concetti che giacciono


le basi per la programmazione Python in hapters 2 - 0 e i big data,
intelligenza artificiale e casi di studio basati su cloud in hapters 11 - 6 . Anche il capitolo
include testdrive dell'interprete IPython e Jupyter Notebook.

il capitolo 2 , Introduzione alla programmazione Python, presenta la programmazione Python


fondamenti con esempi di codice che illustrano le caratteristiche chiave del linguaggio.

il capitolo 3 , Dichiarazioni di controllo, presenta le istruzioni di controllo di Python e


introduce l'elaborazione di base dell'elenco.

il capitolo 4 , Funzioni, introduce funzioni personalizzate, presenta la simulazione


tecniche con generazione di numeri casuali e introduce la tupla
fondamenti.

il capitolo 5 , Sequenze: elenchi e tuple, presenta l'elenco e la tupla incorporati di Python


collezioni in modo più dettagliato e inizia a introdurre la programmazione in stile funzionale.

arte 2: strutture dati, stringhe e file Python


P
1
C
arte 2: strutture dati, stringhe e file Python Pagina 12

Quanto segue riepiloga le dipendenze tra i capitoli per Python hapters 6 - 9 e

presume che tu abbia letto hapters 1 - 5 .

capitolo 6 , Dizionari e set: la sezione Introduzione alla scienza dei dati in questo capitolo è
non dipende dal contenuto del capitolo.

capitolo 7 , Programmazione ArrayOriented con NumPy: Introduzione alla scienza dei dati
la sezione richiede dizionari ( capitolo 6 ) e array ( capitolo 7 ).

capitolo 8 , Stringhe: uno sguardo più approfondito: la sezione Intro to Data Science richiede raw
stringhe ed espressioni regolari ( ezioni 8.11 - .12 ) e le serie pandas e

Caratteristiche di DataFrame da sezione 7.14 Introduzione alla scienza dei dati.

capitolo 9 , File ed eccezioni: per la serializzazione JSON, è utile capire


fondamenti del dizionario ( sezione 6.2 ). Inoltre, la sezione Introduzione alla scienza dei dati richiede l'estensione
funzione builtin open e l'istruzione with ( sezione 9.3 ) e panda DataFrame

caratteristiche da sezione 7.14 Introduzione alla scienza dei dati.

Parte 3: argomenti di fascia alta di Python

Quanto segue riepiloga le dipendenze tra i capitoli per Python capitolo 10 e assume

che hai letto hapters 1 - 5 .

capitolo 10 , Programmazione ObjectOriented: sezione Introduzione alla scienza dei dati


richiede le funzionalità DataFrame dei panda da Intro a Data Science ezione 7.14 . Formatori

volendo coprire solo le classi e gli oggetti possono presentare ezioni 10.1 - 0.6 . Formatori
volendo trattare argomenti più avanzati come ereditarietà, polimorfismo e anatra
digitando, può presentare ezioni 10.7 - 0.9 . ezioni 10.10 - 0,15 forniscono ulteriori
prospettive avanzate.
Parte 4: Case study su AI, cloud e Big Data

Il seguente riepilogo delle dipendenze tra capitoli per hapters 11 - 6 lo presume

hai letto hapters 1 - 5 . La maggior partehapters 11 - 6 richiedono anche i fondamenti del dizionario

a partire dal
ezione 6.2 .

il capitolo 11 , Natural Language Processing (NLP), utilizza le funzionalità DataFrame di panda


a partire sezione
dal 7.14 Introduzione alla scienza dei dati.

il capitolo 12 , Data mining Twitter, utilizza le funzionalità DataFrame di panda da ezione


.14 's Intro to Data Science, string method join ( ezione 8.9 ), fondamenti di JSON
( sezione 9.5 ), TextBlob ( sezione 11.2 ) e Word cloud ( sezione 11.3 ). Diversi esempi

richiedono la definizione di una classe tramite ereditarietà


capitolo
( 10 ).

il capitolo 13 , IBM Watson e Cognitive Computing, utilizza la funzione incorporata open

e l'istruzione with ( sezione 9.3 ).

capitolo 14 , Machine Learning: classificazione, regressione e clustering, utilizza


Fondamenti di array NumPy e metodo unico ( capitolo 7 ), panda DataFrame
caratteristiche da Sezione 7.14 Introduzione a Data Science e sottotrame delle funzioni Matplotlib
( sezione 10.6 ).

il capitolo 15 , Deep Learning, richiede i fondamenti dell'array NumPy ( capitolo 7 ), stringa


metodo join ( ection 8.9 ), concetti generali di machine learning da capitolo 14 e

caratteristiche da Caso di studio del capitolo 14 : Classificazione con kNearest Neighbors e


Set di dati cifre.

capitolo 16 , ig Data: Hadoop, Spark, NoSQL e IoT , utilizza la divisione del metodo di stringa
( sezione 6.2.7 ), Matplotlib FuncAnimation da Sezione 6.4 , Introduzione alla scienza dei dati,
pandas Series e funzionalità DataFrame da ection 7.14 's Intro to Data Science, string

71P
8 C
B
S
ethod join ( ezione 8.9 ), il modulo json ( sezione 9.5 ), parole di arresto NLTK ( ezione Pagina 13
1.2.13 ) e da capitolo 12 , autenticazione Twitter, classe StreamListener di Tweepy
per i tweet in streaming e le librerie di geopy e folium. Alcuni esempi richiedono
definire una classe tramite ereditarietà ( capitolo 10 ), ma puoi semplicemente imitare la classe
definizioni che forniamo senza leggere capitolo 10 .

TACCUINI JUPYTER
Per tua comodità, forniamo gli esempi di codice del libro in codice sorgente Python (.py)
file da utilizzare con l'interprete IPython da riga di comando e come notebook Jupyter
(.ipynb) file che puoi caricare nel tuo browser web ed eseguire.

Jupyter Notebooks è un progetto opensource gratuito che ti consente di combinare testo,


funzionalità di codifica grafica, audio, video e interattiva per l'immissione, la modifica, l'esecuzione,
debug e modifica del codice rapidamente e comodamente in un browser web. Secondo il
articolo, "Che cos'è Jupyter?":

Jupyter è diventato uno standard per la ricerca scientifica e l'analisi dei dati. Pacchetti
calcolo e argomentazione insieme, permettendoti di costruire "narrazioni computazionali" e questo
9

semplifica il problema della distribuzione di software funzionante a colleghi e collaboratori.

9
TTP: //www.oreilly.com/ideas/whatisjupyter .

Nella nostra esperienza, è un meraviglioso ambiente di apprendimento e uno strumento di prototipazione rapida. Per
per questo motivo, utilizziamo i notebook Jupyter piuttosto che un IDE tradizionale, come Eclipse,
Visual Studio, PyCharm o Spyder. Accademici e professionisti utilizzano già Jupyter
ampiamente per condividere i risultati della ricerca. Il supporto per Jupyter Notebooks viene fornito tramite
0
meccanismi di comunità opensource tradizionali ( vedere "Ottenere l'aiuto di Jupyter" più avanti in questo
Prefazione). Vedere la sezione Prima di iniziare che segue questa Prefazione per l'installazione del software
dettagli e vedere i testdrive in sezione 1.5 per informazioni sull'esecuzione degli esempi del libro.

0
ttps: //jupyter.org/community .

Collaborazione e condivisione dei risultati

Lavorare in team e comunicare i risultati della ricerca sono entrambi importanti per gli sviluppatori in
o passare a posizioni di analisi dei dati nell'industria, nel governo o nel mondo accademico:

I taccuini che crei sono facili da condividere tra i membri del team semplicemente copiandoli
i file o tramite GitHub.

I risultati della ricerca, inclusi codice e approfondimenti, possono essere condivisi come pagine web statiche tramite strumenti
come nbviewer ( ttps: //nbviewer.jupyter.org ) e GitHub, entrambi automaticamente
rendere i taccuini come pagine web.

Riproducibilità: una custodia robusta per i notebook Jupyter

Nella scienza dei dati e nelle scienze in generale, dovrebbero esserci esperimenti e studi
riproducibile. Questo è stato scritto nella letteratura per molti anni, incluso

La pubblicazione di informatica del 1992 di Donald Knuth: Literate Programming .

1
Knuth, D., "Literate Programming" (PDF), The Computer Journal , British Computer
Società, 1992.

L'articolo “LanguageAgnostic Reproducible Data Analysis Using Literate


La programmazione ",2 che dice," Lir (computer alfabetizzato e riproducibile) si basa sull'idea
di programmazione alfabetizzata come proposto da Donald Knuth. "

2
ttp: //journals.plos.org/plosone/article?

d = 10.1371 / journal.pone.0164023 .

In sostanza, la riproducibilità cattura l'ambiente completo utilizzato per produrre risultati—


hardware, software, comunicazioni, algoritmi (soprattutto codice), dati e dati

11m
1C
S
h
io
rovenance (origine e lignaggio). Pagina 14

DOCKER
Nel Nel capitolo 16 , utilizzeremo Docker, uno strumento per impacchettare il software in contenitori che raggruppano
tutto il necessario per eseguire quel software in modo conveniente, riproducibile e portabile
piattaforme. Alcuni pacchetti software in cui utilizziamo il capitolo 16 richiede una configurazione complicata e
configurazione. Per molti di questi, puoi scaricare container Docker preesistenti gratuiti.

Questi consentono di evitare problemi di installazione complessi ed eseguire il software localmente sul tuo
computer desktop o notebook, rendendo Docker un ottimo modo per aiutarti a iniziare con il nuovo
tecnologie rapide e convenienti.

Docker aiuta anche con la riproducibilità. Puoi creare contenitori Docker personalizzati che siano
configurato con le versioni di ogni software e di ogni libreria che hai usato nel tuo file
studia. Ciò consentirebbe ad altri sviluppatori di ricreare l'ambiente che hai utilizzato, quindi
riproduci il tuo lavoro e ti aiuterà a riprodurre i tuoi risultati. Nel nel capitolo 16 , utilizzerai
Docker per scaricare ed eseguire un contenitore preconfigurato per il codice e l'esecuzione di grandi dimensioni
applicazioni Data Spark che utilizzano Jupyter Notebook.

CARATTERISTICHE SPECIALI: IBM WATSON ANALYTICS AND


COMPUTAZIONE COGNITIVA
All'inizio della nostra ricerca per questo libro, abbiamo riconosciuto l'interesse in rapida crescita per IBM
Watson. Abbiamo esaminato i servizi della concorrenza e abbiamo riscontrato che "nessuna carta di credito richiesta" di Watson

politica per i suoi "livelli gratuiti" per essere tra i più amichevoli per i nostri lettori.

IBM Watson è una piattaforma di elaborazione cognitiva utilizzata in un'ampia gamma di


scenari del mondo reale. I sistemi di elaborazione cognitiva simulano il riconoscimento dei pattern e
capacità decisionali del cervello umano di "apprendere" man mano che consumano di più
4
3,, 5
dati. Includiamo un significativo trattamento manuale con Watson. Usiamo il Watson gratuito
Developer Cloud: Python SDK, che fornisce API che ti consentono di interagire con
I servizi di Watson a livello di programmazione. Watson è divertente da usare e un'ottima piattaforma per la locazione
i tuoi succhi creativi fluiscono. Dimostrerai o utilizzerai le seguenti API Watson: conversazione,
Scoperta, traduttore di lingue, classificatore di lingue naturali, linguaggio naturale
Comprensione, Approfondimenti sulla personalità, Da parola a testo, Da testo a voce, Tono
Analizzatore e riconoscimento visivo.

3
TTP: //whatis.techtarget.com/definition/cognitivecomputing .

4
ttps: //en.wikipedia.org/wiki/Cognitive_computing .

5
ttps: //www.forbes.com/sites/bernardmarr/2016/03/23/whateveryone

houldknowaboutcognitivecomputing .

Servizi di livello Lite di Watson e un interessante case study di Watson

IBM incoraggia l'apprendimento e la sperimentazione fornendo livelli lite gratuiti per molti dei suoi
6 7
API. Nel nel capitolo 13 , proverai demo di molti servizi Watson. Quindi, utilizzerai lite
livelli dei servizi Text to Speech, Speech to Text e Translate di Watson per implementare a
App di traduzione "assistente del viaggiatore". Farai una domanda in inglese, quindi l'app
trascriverà il tuo discorso in testo inglese, tradurrà il testo in spagnolo e parlerà il
Testo spagnolo. Successivamente, pronuncerai una risposta in spagnolo (nel caso in cui non parli spagnolo, noi
fornire un file audio che puoi utilizzare). Quindi, l'app trascriverà rapidamente il discorso in spagnolo
testo, traduci il testo in inglese e pronuncia la risposta in inglese. Roba forte!

6
Controllare sempre i termini più recenti sul sito Web di IBM, poiché i termini e i servizi potrebbero cambiare.

7
ttps: //console.bluemix.net/catalog/ .

APPROCCIO DIDATTICO
Python for Programmers contiene una ricca raccolta di esempi tratti da molti campi.
Lavorerai su interessanti esempi del mondo reale utilizzando set di dati del mondo reale. Il libro
si concentra sui principi di una buona ingegneria del software e sottolinea il programma

p
C
11h
S
chiarezza. Pagina 15

Utilizzo dei caratteri per enfatizzare

Mettiamo in grassetto i termini chiave e il riferimento alla pagina dell'indice per ciascuna occorrenza di definizione
testo per un riferimento più facile. Ci riferiamo ai componenti sullo schermo con il carattere grassetto Helvetica (per
esempio, il menu File) e utilizzare il carattere Lucida per il codice Python (ad esempio, x = 5).

Colorazione sintassi

Per la leggibilità, la sintassi colora tutto il codice. Le nostre convenzioni per la colorazione della sintassi sono le seguenti:
i commenti vengono visualizzati in verde

le parole chiave vengono visualizzate in blu scuro

le costanti e i valori letterali vengono visualizzati in azzurro


gli errori vengono visualizzati in rosso

tutto il resto del codice appare in nero

538 Esempi di codici

I 538 esempi del libro contengono circa 4000 righe di codice. Questo è relativamente
piccola quantità per un libro di queste dimensioni ed è dovuta al fatto che Python è un tale espressivo
linguaggio. Inoltre, il nostro stile di codifica consiste nell'usare potenti librerie di classi per svolgere la maggior parte del lavoro
ove possibile.

160 Tabelle / Illustrazioni / Visualizzazioni

Includiamo numerose tabelle, disegni al tratto e visualizzazioni statiche, dinamiche e interattive.

Saggezza di programmazione

Noi integriamo nelle discussioni la programmazione saggezza gli autori congiunta nove
decenni di esperienza nella programmazione e nell'insegnamento, tra cui:

Buone pratiche di programmazione e idiomi Python preferiti che ti aiutano a produrre


programmi più chiari, più comprensibili e più manutenibili.

Errori di programmazione comuni per ridurre la probabilità che tu li faccia.

Suggerimenti per la prevenzione degli errori con suggerimenti per esporre i bug e rimuoverli da
i tuoi programmi. Molti di questi suggerimenti descrivono le tecniche per prevenire la ricezione di bug
nei tuoi programmi in primo luogo.

Suggerimenti sulle prestazioni che evidenziano le opportunità per rendere i tuoi programmi più veloci o
ridurre al minimo la quantità di memoria che occupano.

Osservazioni di ingegneria del software che evidenziano problemi di architettura e progettazione per
corretta costruzione del software, soprattutto per sistemi più grandi.

SOFTWARE UTILIZZATO NEL LIBRO


Il software che utilizziamo è disponibile per Windows, macOS e Linux ed è scaricabile gratuitamente
da Internet. Abbiamo scritto gli esempi del libro usando Anaconda Python gratuito

distribuzione. Include la maggior parte delle librerie Python, di visualizzazione e di scienza dei dati
need, così come l'interprete IPython, Jupyter Notebooks e Spyder, considerato uno dei
i migliori IDE per la scienza dei dati di Python. Usiamo solo IPython e Jupyter Notebook per il programma
sviluppo nel libro. La sezione Prima di iniziare che segue questa prefazione discute
l'installazione di Anaconda e alcuni altri elementi necessari per lavorare con i nostri esempi.

DOCUMENTAZIONE IN PITONE
Troverai la seguente documentazione particolarmente utile durante la lettura del libro:

Riferimento al linguaggio Python:

ttps: //docs.python.org/3/reference/index.html

h
La libreria standard Python: Pagina 16

ttps: //docs.python.org/3/library/index.html

Elenco della documentazione di Python:

ttps: //docs.python.org/3/

RISPOSTA ALLE VOSTRE DOMANDE


I popolari forum online di Python e di programmazione generale includono:

pythonforum.io

ttps: //www.dreamincode.net/forums/forum/29python/

StackOverflow.com

Inoltre, molti fornitori forniscono forum per i loro strumenti e librerie. Molte delle biblioteche che farai
l'uso in questo libro sono gestiti e mantenuti su github.com. Alcuni manutentori di librerie

fornire supporto tramite la scheda Problemi nella pagina GitHub di una determinata libreria. Se non riesci a trovare
una risposta alle tue domande online, consulta la nostra pagina web per il libro all'indirizzo

8
ttp: //www.deitel.com

8
Il nostro sito web sta subendo un importante aggiornamento. Se non trovi qualcosa di cui hai bisogno, per favore
scrivici direttamente a eitel@deitel.com .

COME OTTENERE AIUTO JUPYTER


Il supporto di Jupyter Notebooks viene fornito tramite:

Progetto Jupyter Google Group:


ttps: //groups.google.com/forum/#! forum / jupyter

Chat room in tempo reale di Jupyter:

ttps: //gitter.im/jupyter/jupyter

GitHub

ttps: //github.com/jupyter/help

StackOverflow:

ttps: //stackoverflow.com/questions/tagged/jupyter

Gruppo Google Jupyter for Education (per insegnanti che insegnano con Jupyter):

ttps: //groups.google.com/forum/#! forum / jupytereducation

SUPPLEMENTI
Per ottenere il massimo dalla presentazione, è necessario eseguire ogni esempio di codice in parallelo

con la lettura della discussione corrispondente nel libro. Sulla pagina web del libro all'indirizzo

ttp: //www.deitel.com

noi forniamo:

Codice sorgente Python scaricabile (file .py) e notebook Jupyter (.ipynb


file) per gli esempi di codice del libro.

Video introduttivi che mostrano come utilizzare gli esempi di codice con IPython e
Quaderni Jupyter. Introduciamo questi strumenti anche in ezione 1.5 .

h1
dS
Post del blog e aggiornamenti dei libri. Pagina 17

Per le istruzioni per il download, vedere la sezione Prima di iniziare che segue questa prefazione.

RIMANERE IN CONTATTO CON GLI AUTORI


Per risposte a domande o per segnalare un errore, inviaci una mail a

eitel@deitel.com

o interagisci con noi tramite i social media:

®
Facebook ( ttp: //www.deitel.com/deitelfan )

®
Twitter (@deitel)

®
LinkedIn ( TTP: //linkedin.com/company/deitel&associates )

®
Youtube ( ttp: //youtube.com/DeitelTV )

RICONOSCIMENTI
Ringraziamo Barbara Deitel per le lunghe ore dedicate alla ricerca in Internet su questo progetto.
Siamo fortunati ad aver lavorato con il team dedicato di professionisti dell'editoria di
Pearson. Apprezziamo gli sforzi e il tutoraggio di 25 anni del nostro amico e collega Mark
L. Taub, Vicepresidente del Pearson IT Professional Group. Mark e il suo team pubblicano il nostro
libri professionali, prodotti video LiveLessons e percorsi di apprendimento nel servizio Safari
( ttps: //learning.oreilly.com/ ). Sponsorizzano anche la nostra formazione online dal vivo di Safari

seminari. Julie Nahil ha diretto la produzione del libro. Abbiamo selezionato la copertina e Chuti
Prasertsith ha disegnato la copertina.

Desideriamo riconoscere gli sforzi dei nostri revisori. Patricia Byron Kimball e Meghan
Jacoby ha reclutato i revisori e ha gestito il processo di revisione. Aderendo a un programma serrato,

i revisori hanno esaminato il nostro lavoro, fornendo innumerevoli suggerimenti per migliorare il
accuratezza, completezza e tempestività della presentazione.

Revisori

Revisori di libri

Daniel Chen, Data Scientist, Lander


Analytics
Daniel Chen, Data Scientist, Lander
Garrett Dancik, professore associato di Analytics
Informatica / Bioinformatica,
Eastern Connecticut State University Garrett Dancik, professore associato di
Informatica / Bioinformatica,
Pranshu Gupta, professore assistente, Eastern Connecticut State University
Informatica, DeSales University
Dr. Marsha Davis, presidente del dipartimento di
David Koop, assistente professore, Data Scienze matematiche, orientale
CoDirettore del programma scientifico, UMass Connecticut State University
Dartmouth
Roland DePratti, Professore a contratto di
Ramon Mata Toledo, professore, Informatica, Connecticut orientale
Informatica, James Madison Università Statale
Università
Shyamal Mitra, docente senior,
Shyamal Mitra, docente senior, Informatica, Università del Texas a
Informatica, Università del Texas Austin
ad Austin
Mark Pauley, ricercatore senior,
Alison Sanchez, assistente professore in Bioinformatica, Scuola di Interdisciplinarità

dh
Economia, Università di San Diego Informatica, Università del Nebraska a Pagina 18
Omaha
José Antonio González Seco, IT

Consulente Sean Raleigh, professore associato di


Matematica, cattedra di scienza dei dati,
Jamie Whitacre, dati indipendenti Westminster College
Consulente scientifico
Alison Sanchez, assistente professore in
Elizabeth Wickes, docente, School of Economia, Università di San Diego
Scienze dell'informazione, Università di
Illinois Dr. Harvey Siy, Professore Associato di
Informatica, Scienza dell'informazione
Revisori delle proposte
and Technology, University of Nebraska at
Omaha
Dott.ssa Irene Bruno, Professore Associato in
il Dipartimento dell'informazione
Jamie Whitacre, dati indipendenti
Scienze e tecnologia, George Consulente scientifico
Mason University

Lance Bryant, Professore Associato,


Dipartimento di Matematica,
Shippensburg University

Mentre leggi il libro, apprezzeremmo i tuoi commenti, critiche, correzioni e


suggerimenti per un miglioramento. Si prega di inviare tutta la corrispondenza a:

eitel@deitel.com

Risponderemo prontamente.

Benvenuto di nuovo nell'entusiasmante mondo opensource della programmazione Python. Ci auguriamo che tu
goditi questo sguardo allo sviluppo di applicazioni informatiche all'avanguardia con Python, IPython,
Notebook Jupyter, data science, AI, big data e cloud. Vi auguriamo grande successo!

Paul e Harvey Deitel

RIGUARDO AGLI AUTORI


Paul J. Deitel, CEO e Chief Technical Officer di Deitel & Associates, Inc., è un MIT
laureato con 38 anni di esperienza in informatica. Paul è uno dei più famosi al mondo
formatori esperti di linguaggi di programmazione, avendo tenuto corsi professionali su software

sviluppatori dal 1992. Ha tenuto centinaia di corsi di programmazione a clienti del settore
a livello internazionale, inclusi Cisco, IBM, Siemens, Sun Microsystems (ora Oracle), Dell,

Fidelity, NASA presso il Kennedy Space Center, National Severe Storm Laboratory, White
Sands Missile Range, Rogue Wave Software, Boeing, Nortel Networks, Puma, iRobot e
molti altri. Lui e il suo coautore, il dottor Harvey M. Deitel, sono i bestseller al mondo
linguaggio di programmazione libri di testo / libri professionali / autori di video.

Dr. Harvey M. Deitel, Presidente e Chief Strategy Officer di Deitel & Associates, Inc., ha
58 anni di esperienza nell'informatica. Il dottor Deitel ha conseguito la laurea in ingegneria elettrica e la laurea magistrale

Ingegneria del MIT e un dottorato di ricerca. in matematica alla Boston University, ha studiato
computer in ciascuno di questi programmi prima che venissero scorporati dai programmi di informatica. Lui

ha una vasta esperienza di insegnamento universitario, compreso il guadagno di ruolo e il servizio come
Presidente del Dipartimento di Informatica al Boston College prima di fondare Deitel &
Associates, Inc., nel 1991 con suo figlio Paul. Le pubblicazioni dei Deitels hanno guadagnato

riconoscimento internazionale, con più di 100 traduzioni pubblicate in giapponese, tedesco,


Russo, spagnolo, francese, polacco, italiano, cinese semplificato, cinese tradizionale, coreano,

Portoghese, greco, urdu e turco. Il Dr. Deitel ha fornito centinaia di programmi


corsi per clienti accademici, aziendali, governativi e militari.

®
INFORMAZIONI SU DEITEL & ASSOCIATES, INC.

d
eitel & Associates, Inc., fondata da Paul Deitel e Harvey Deitel, è un'azienda internazionale Pagina 19
autore riconosciuto e organizzazione di formazione aziendale, specializzata in informatica

linguaggi di programmazione, tecnologia a oggetti, sviluppo di app mobili e Internet e web


tecnologia software. I clienti della formazione dell'azienda includono alcuni dei più grandi al mondo

aziende, agenzie governative, filiali delle istituzioni militari e accademiche. Il


L'azienda offre corsi di formazione con istruttore erogati presso i siti dei clienti in tutto il mondo su major
linguaggi di programmazione.

Attraverso la sua partnership editoriale di 44 anni con Pearson / Prentice Hall, Deitel & Associates,
Inc., pubblica libri di testo di programmazione all'avanguardia e libri professionali in formato cartaceo ed elettronico
formati di libri, corsi video LiveLessons (disponibili per l'acquisto all'indirizzo

ttps: //www.informit.com ), Percorsi di apprendimento e seminari di formazione online dal vivo in


Servizio Safari ( ttps: //learning.oreilly.com ) e multimediale interattivo Revel ™
corsi.

Per contattare Deitel & Associates, Inc. e gli autori, o per richiedere una proposta in loco,
formazione istruita, scrivere a:

eitel@deitel.com

Per ulteriori informazioni sulla formazione aziendale in loco Deitel, visitare

ttp: //www.deitel.com/training

Le persone che desiderano acquistare libri Deitel possono farlo all'indirizzo

ttps: //www.amazon.com

Gli ordini all'ingrosso da parte di aziende, governo, istituzioni militari e accademiche dovrebbero
essere posizionato direttamente con Pearson. Per maggiori informazioni visita

ttps: //www.informit.com/store/sales.aspx

hD
d
Pagina 20

Prima di iniziare
storia

Questa sezione contiene informazioni da esaminare prima di utilizzare questo libro. Pubblicheremo
opiche
aggiornamenti su: http://www.deitel.com .

guadagnando Pat

CONVENZIONI DI FONT E NOMINA


ffers & Dea
Mostriamo codice e comandi Python e nomi di file e cartelle in un sansserif

font e
ighlights componenti sullo schermo, come i nomi dei menu, in un carattere sansserif in grassetto.
Usiamo il corsivo per l'enfasi e il grassetto occasionalmente per l'enfasi forte.
ettings

OTTENERE GLI ESEMPI DI CODICE


Supporto
Puoi scaricare
Disconnessione il file examples.zip contenente gli esempi del libro dal nostro
Pagina web di Python per programmatori all'indirizzo:

http://www.deitel.com

Fare clic sul collegamento Scarica esempi per salvare il file sul computer locale. La maggior parte degli errori web
i browser posizionano il file nella cartella Download del tuo account utente. Quando il download
completa, individualo sul tuo sistema ed estrai la sua cartella di esempi nel tuo utente

cartella Documenti dell'account:

Windows: C: \ Users \ YourAccount \ Documents \ examples

macOS o Linux: ~ / Documents / examples

La maggior parte dei sistemi operativi dispone di uno strumento di estrazione integrato. Puoi anche utilizzare uno strumento di archiviazione
come 7Zip ( www.7zip.org ) o WinZip ( www.winzip.com ).

STRUTTURA DELLA CARTELLA ESEMPI


In questo libro eseguirai tre tipi di esempi:

Pagina 21
Singoli frammenti di codice nell'ambiente interattivo IPython.

Applicazioni complete, note come script.

Notebook Jupyter: un comodo ambiente interattivo basato sul browser Web in formato
che puoi scrivere ed eseguire codice e mescolare il codice con testo, immagini e
video.

Dimostriamo ciascuno in sezione 1.5 dei test drive.

La cartella degli esempi contiene una sottocartella per capitolo. Questi sono chiamati ch ##,

dove ## è il numero di capitolo a due cifre da 01 a 16, ad esempio ch01. Eccetto per
hapters 13 , 5 e 6 , la cartella di ogni capitolo contiene i seguenti elementi:

snippets_ipynb: una cartella contenente i file Jupyter Notebook del capitolo.

snippets_py: una cartella contenente i file di codice sorgente Python in cui ogni codice
lo snippet che presentiamo è separato dal successivo da una riga vuota. Puoi copiare e
incolla questi frammenti in IPython o nei nuovi notebook Jupyter che crei.

File di script e relativi file di supporto.

il capitolo 13 contiene un'applicazione. hapters 15 e 6 spiegare dove trovare i file


è necessario rispettivamente nelle cartelle ch15 e ch16.

INSTALLAZIONE DI ANACONDA
Con questo libro usiamo la distribuzione Python di Anaconda, facile da installare. Viene fornito con
quasi tutto ciò di cui hai bisogno per lavorare con i nostri esempi, inclusi:

l'interprete IPython,

la maggior parte delle librerie Python e di data science che utilizziamo,

un server Jupyter Notebooks locale in modo da poter caricare ed eseguire i nostri notebook e
vari altri pacchetti software, come Spyder Integrated Development
Ambiente (IDE): in questo libro utilizziamo solo IPython e Jupyter Notebook.

Scarica il programma di installazione di Python 3.x Anaconda per Windows, macOS o Linux da:

1
C
S
Pagina 22
ttps: //www.anaconda.com/download/

Al termine del download, esegui il programma di installazione e segui le istruzioni sullo schermo.
Per assicurarti che Anaconda funzioni correttamente, non spostare i suoi file dopo averlo installato.

AGGIORNAMENTO ANACONDA
Quindi, assicurati che Anaconda sia aggiornato. Apri una finestra della riga di comando sul tuo
sistema come segue:

Su macOS, apri un Terminale dalla sottocartella Utilità della cartella Applicazioni.

Su Windows, apri il prompt di Anaconda dal menu di avvio. Quando lo fai


per aggiornare Anaconda (come farai qui) o per installare nuovi pacchetti (discusso
momentaneamente), eseguire il Prompt Anaconda come amministratore di diritto
facendo clic su, quindi selezionando Altro> Esegui come amministratore. (Se non riesci a trovare il file
Prompt di Anaconda nel menu di avvio, cercalo semplicemente nel Tipo qui a
campo di ricerca nella parte inferiore dello schermo.)

Su Linux, apri il terminale o la shell del tuo sistema (questo varia a seconda della distribuzione Linux).

Nella finestra della riga di comando del tuo sistema, esegui i seguenti comandi per aggiornare
Pacchetti installati di Anaconda alle loro ultime versioni:

1. conda aggiornamento conda

2. conda aggiorna tutto

GESTORI DI PACCHETTI
Il comando conda usato sopra richiama il gestore di pacchetti conda, uno dei

due gestori di pacchetti Python chiave che userete in questo libro. L'altro è pip . Pacchi
contenere i file necessari per installare una determinata libreria o strumento Python. Attraverso il libro,
userete conda per installare pacchetti aggiuntivi, a meno che quei pacchetti non siano disponibili

tramite conda, nel qual caso utilizzerai pip. Alcune persone preferiscono usare esclusivamente pip
poiché attualmente supporta più pacchetti. In caso di problemi durante l'installazione di un pacchetto
con conda, prova invece pip.

INSTALLAZIONE DEL CODICE STATICO DEL PROSPETTORE


STRUMENTO DI ANALISI
h
Pagina 23
Potresti voler analizzare il tuo codice Python usando lo strumento di analisi Prospector, che
controlla il tuo codice per errori comuni e ti aiuta a migliorarlo. Per installare Prospector
e le librerie Python che utilizza, esegui il seguente comando nella riga di comando
finestra:

pip install prospector


INSTALLAZIONE DI JUPYTER-MATPLOTLIB
Implementiamo diverse animazioni utilizzando una libreria di visualizzazione chiamata Matplotlib. Usare
in Jupyter Notebooks, è necessario installare uno strumento chiamato ipympl. Nel Terminal,

Prompt dei comandi di Anaconda o shell che hai aperto in precedenza, esegui quanto segue
1
comandi uno alla volta:

1
TTP: //github.com/matplotlib/jupytermatplotlib .

conda install c condaforge ipympl


conda installa nodejs
jupyter labextension installa @ jupyterwidgets / jupyterlabmanager
jupyter labextension installa jupytermatplotlib

INSTALLAZIONE DEGLI ALTRI PACCHETTI


Anaconda viene fornito con circa 300 popolari pacchetti Python e data science per
tu, come NumPy, Matplotlib, panda, Regex, BeautifulSoup, richieste, Bokeh, SciPy,
SciKitLearn, Seaborn, Spacy, sqlite, statsmodels e molti altri. Il numero di
i pacchetti aggiuntivi che dovrai installare in tutto il libro saranno piccoli e lo faremo
fornire le istruzioni di installazione secondo necessità. Man mano che scopri nuovi pacchetti, il loro file
la documentazione spiegherà come installarli.

OTTIENI UN ACCOUNT SVILUPPATORE TWITTER


Se intendi utilizzare il nostro capitolo "Data mining Twitter" e qualsiasi esempio basato su Twitter
nei capitoli successivi, richiedere un account sviluppatore Twitter. Twitter ora richiede
registrazione per l'accesso alle proprie API. Per candidarsi, compilare e inviare la domanda a

ttps: //developer.twitter.com/en/applyforaccess

Twitter esamina ogni applicazione. Al momento della stesura di questo articolo, sviluppatore personale
gli account venivano approvati immediatamente e le richieste di account aziendali

h
Y
Pagina 24
da diversi giorni a diverse settimane. L'approvazione non è garantita.

CONNESSIONE A INTERNET RICHIESTA IN ALCUNI


CAPITOLI
Durante l'utilizzo di questo libro, avrai bisogno di una connessione Internet per installare vari altri
Librerie Python. In alcuni capitoli ti registrerai per gli account con cloudbased
servizi, principalmente per utilizzare i loro livelli gratuiti. Alcuni servizi richiedono carte di credito per verificare il tuo
identità. In alcuni casi, utilizzerai servizi non gratuiti. In questi casi, prendi
vantaggio dei crediti monetari forniti dai fornitori in modo da poter provare i loro servizi
senza incorrere in spese. Attenzione: alcuni servizi basati su cloud comportano dei costi
una volta impostati. Quando completi i nostri casi di studio utilizzando tale
servizi, assicurati di eliminare prontamente le risorse che hai assegnato.

LEGGERE DIFFERENZE NELLE USCITE DI PROGRAMMA


Quando esegui i nostri esempi, potresti notare alcune differenze tra i risultati
mostriamo e i tuoi risultati:

A causa delle differenze nel modo in cui i calcoli vengono eseguiti con i numeri in virgola mobile
(come –123,45, 7,5 o 0,0236937) nei sistemi operativi, potresti vedere minori
variazioni nelle uscite, specialmente nelle cifre a destra del punto decimale.

Quando mostriamo gli output che appaiono in finestre separate, ritagliamo le finestre su
rimuovere i loro bordi.

RISPOSTA ALLE VOSTRE DOMANDE


I forum online ti consentono di interagire con altri programmatori Python e ottenere il tuo
Risposte alle domande di Python. I popolari forum Python e di programmazione generale includono:

pythonforum.io

StackOverflow.com

ttps: //www.dreamincode.net/forums/forum/29python/

Inoltre, molti fornitori forniscono forum per i loro strumenti e librerie. La maggior parte delle biblioteche
che userete in questo libro sono gestiti e mantenuti su github.com. Qualche libreria
i manutentori forniscono supporto tramite la scheda Problemi nella pagina GitHub di una data libreria.

ht
Pagina 25
Se non riesci a trovare una risposta alle tue domande online, consulta la nostra pagina web per il
prenotare a

2
ttp: //www.deitel.com

2
Il nostro sito web sta subendo un importante aggiornamento. Se non trovi qualcosa di cui hai bisogno,
scrivici direttamente a eitel@deitel.com .

Ora sei pronto per iniziare a leggere Python per programmatori . Ci auguriamo che ti piaccia
libro!
io
dh
Pagina 26

storia 1. Introduzione a computer e Python


Obiettivi
opiche

In questo capitolo potrai:


guadagnando Pat

Scopri gli entusiasmanti sviluppi recenti nell'informatica.


ffers & Dea

Rivedi le basi della programmazione orientata agli oggetti.


ighlights

Comprendi i punti di forza di Python.


ettings

Scopri le principali librerie Python e datascience che utilizzerai in questo libro.


Supporto
Testdrive la modalità interattiva dell'interprete IPython per l'esecuzione del codice Python.
Disconnessione

Esegui uno script Python che anima un grafico a barre.

Creare e testare un notebook Jupyter basato sul browser Web per l'esecuzione di codice Python.

Scopri quanto sono grandi i "big data" e quanto velocemente stanno diventando ancora più grandi.

Leggi un case study di bigdata su una popolare app di navigazione mobile.

Essere introdotto all'intelligenza artificiale, all'incrocio tra informatica e dati

scienza.

Contorno

.1 Introduzione

.2 Una rapida rassegna delle nozioni di base sulla tecnologia degli oggetti

.3 Python

.4 Sono le biblioteche!

.4.1 Libreria standard Python

.4.2 Librerie DataScience

.5 TestDrives: utilizzo di IPython e Jupyter Notebook


Pagina 27

.5.1 Utilizzo della modalità interattiva IPython come calcolatrice

.5.2 Esecuzione di un programma Python utilizzando l'interprete IPython

.5.3 Scrittura ed esecuzione di codice in un notebook Jupyter


.6 Cloud e Internet of Things

.6.1 Il Cloud

.6.2 Internet delle cose

.7 Quanto sono grandi i Big Data?

.7.1 Analisi dei Big Data

.7.2 Scienza dei dati e Big Data fanno la differenza: casi d'uso

.8 Case Study: un'applicazione mobile BigData

.9 Introduzione alla scienza dei dati: intelligenza artificiale: all'intersezione tra CS e scienza dei dati

.10 WrapUp

1.1 INTRODUZIONE
Benvenuti in Python, uno dei linguaggi di programmazione per computer più utilizzati al mondo

e, secondo l' indice PYPL (Popolarità dei linguaggi di programmazione) , il


1
più popolare.

1
ttps: //pypl.github.io/PYPL.html (a partire da gennaio 2019).

Qui, introduciamo terminologia e concetti che gettano le basi per Python

programmazione in cui imparerai hapters 2 - 0 e i bigdata, intelligenza artificiale e cloud


case study basati su cui presentiamo hapters 11 - 6.

Esamineremo la terminologia e i concetti della programmazione orientata agli oggetti . Imparerai perché
Python è diventato così popolare. Introdurremo la libreria standard Python e vari
librerie di dati che ti aiutano a evitare di "reinventare la ruota". Utilizzerai queste librerie per
creare oggetti software con cui interagire per eseguire compiti significativi con modesto

numero di istruzioni.

Successivamente, lavorerai attraverso tre testdrive che mostrano come eseguire il codice Python:

1h
C

Nel primo, utilizzerai IPython per eseguire le istruzioni Python in modo interattivo e
Pagina 28

vedere subito i risultati.

Nel secondo, eseguirai una sostanziale applicazione Python che mostrerà un file
grafico a barre animato che riassume i tiri di un dado a sei facce man mano che si verificano. Vedrai " aw
f Large Numbers ”in azione. Nel nel capitolo 6 , costruirai questa applicazione con l' estensione
Libreria di visualizzazione Matplotlib.

Nell'ultimo, introdurremo i notebook Jupyter utilizzando JupyterLab, un web interattivo


strumento basato su browser in cui è possibile scrivere ed eseguire comodamente istruzioni Python.
I taccuini Jupyter ti consentono di includere testo, immagini, audio, video, animazioni e
codice.

In passato, la maggior parte delle applicazioni per computer venivano eseguite su computer autonomi (ovvero non collegati in rete
insieme). Le candidature odierne possono essere scritte con lo scopo di comunicare tra i
miliardi di computer nel mondo tramite Internet. Presenteremo il cloud e Internet di

Things (IoT), ponendo le basi per le applicazioni contemporanee in cui svilupperai


hapters 11 - 6.

Imparerai quanto sono grandi i "big data" e quanto velocemente stanno diventando ancora più grandi. Successivamente, lo faremo

presentare un caso di studio bigdata sull'app di navigazione mobile Waze, che utilizza molti file
tecnologie per fornire indicazioni stradali dinamiche che ti portino a destinazione il più rapidamente possibile
e nel modo più sicuro possibile. Mentre esaminiamo queste tecnologie, menzioneremo dove lo farai
usane molti in questo libro. Il capitolo si chiude con la nostra prima sezione Intro to Data Science
in cui discutiamo un'intersezione chiave tra informatica e scienza dei dati: artificiale
intelligenza.

1.2 UNA RAPIDA REVISIONE DEI BASI DELLA TECNOLOGIA DEGLI OGGETTI
Poiché le richieste di software nuovo e più potente sono in aumento, la creazione di software rapidamente,
correttamente ed economicamente è importante. Vengono gli oggetti , o più precisamente, gli oggetti delle classi
da, sono componenti software essenzialmente riutilizzabili . Ci sono oggetti data, oggetti tempo,
oggetti audio, oggetti video, oggetti automobili, oggetti persone, ecc. Quasi ogni nome può essere
ragionevolmente rappresentato come un oggetto software in termini di attributi (ad esempio, nome, colore e dimensione)
e comportamenti (ad esempio, calcolare, muoversi e comunicare). Gruppi di sviluppo software

può utilizzare un approccio di progettazione e implementazione modulare e orientato agli oggetti per essere molto di più
produttivi rispetto alle precedenti tecniche popolari come la "programmazione strutturata". Oggetto

i programmi orientati sono spesso più facili da capire, correggere e modificare.

Automobile come oggetto

Per aiutarti a capire gli oggetti e il loro contenuto, iniziamo con una semplice analogia. Supponiamo
vuoi guidare una macchina e farla andare più veloce premendo il suo pedale dell'acceleratore . Cosa deve

accadere prima che tu possa farlo? Ebbene, prima che tu possa guidare un'auto, qualcuno deve progettarla . UN
tipicamente inizia come disegni tecnici, simili ai progetti che descrivono il

1
oC
L
Pagina 29
segno di una casa. Questi disegni includono il progetto per un pedale dell'acceleratore. Il pedale
nasconde al guidatore i complessi meccanismi che rendono l'auto più veloce, proprio come il freno
il pedale “nasconde” i meccanismi che rallentano l'auto, e il volante “nasconde” il

meccanismi che fanno girare l'auto. Ciò consente alle persone con poca o nessuna conoscenza di come
i motori, i meccanismi dei freni e dello sterzo funzionano per guidare facilmente un'auto.

Proprio come non puoi cucinare i pasti nel progetto di una cucina, non puoi guidare una macchina

disegni tecnici. Prima di poter guidare un'auto, deve essere costruita dall'ingegneria
disegni che lo descrivono. Un'auto completa ha un vero pedale dell'acceleratore per farlo andare

più veloce, ma anche questo non è abbastanza: l'auto non accelera da sola (si spera!), quindi il
il conducente deve premere il pedale per accelerare l'auto.

Metodi e classi
Usiamo il nostro esempio di macchina per introdurre alcuni concetti chiave di programmazione orientata agli oggetti.
L'esecuzione di un'attività in un programma richiede un metodo . Il metodo ospita il programma

dichiarazioni che svolgono i suoi compiti. Il metodo nasconde queste istruzioni all'utente, proprio come
il pedale dell'acceleratore di un'auto nasconde al guidatore i meccanismi per far partire l'auto

Più veloce. In Python, un'unità di programma chiamata classe ospita l'insieme di metodi che eseguono il
compiti della classe. Ad esempio, una classe che rappresenta un conto bancario potrebbe contenere un metodo

al deposito di denaro su un conto, un altro per ritirare denaro da un conto e un terzo a


chiedi qual è il saldo del conto. Una classe è simile nel concetto all'ingegneria di un'auto
disegni, che ospitano il design di un pedale dell'acceleratore, volante e così via.

Istanziazione
Proprio come qualcuno deve costruire un'auto dai suoi disegni tecnici prima che tu possa guidare un'auto,
devi costruire un oggetto di una classe prima che un programma possa eseguire i compiti che la classe svolge

metodi definiscono. Il processo per eseguire questa operazione è chiamato istanziazione . Si fa quindi riferimento a un oggetto
come istanza della sua classe.

Riutilizzo
Proprio come i disegni tecnici di un'auto possono essere riutilizzati molte volte per costruire molte auto, puoi farlo

riutilizzare una classe molte volte per costruire molti oggetti. Riutilizzo delle classi esistenti durante la creazione di nuove
lezioni e programmi consentono di risparmiare tempo e fatica. Il riutilizzo ti aiuta anche a creare file più affidabili e

sistemi efficaci perché le classi e i componenti esistenti spesso sono stati sottoposti a numerosi interventi
test , debug e ottimizzazione delle prestazioni . Proprio come la nozione di parti intercambiabili era

cruciali per la rivoluzione industriale, le classi riutilizzabili sono fondamentali per la rivoluzione del software
che è stato stimolato dalla tecnologia degli oggetti.

In Python, in genere utilizzerai un approccio buildingblock per creare i tuoi programmi. Evitare
reinventando la ruota, utilizzerai i pezzi esistenti di alta qualità ove possibile. Questo software

il riutilizzo è un vantaggio chiave della programmazione orientata agli oggetti.

Messaggi e chiamate al metodo

Quando guidi una macchina, premendo il suo pedale del gas invia un messaggio all'auto per eseguire un compito—
Pagina 30

cioè andare più veloce. Allo stesso modo, invii messaggi a un oggetto . Ogni messaggio è implementato
come una chiamata al metodo che indica a un metodo dell'oggetto di eseguire il suo compito. Ad esempio, un programma

potrebbe chiamare il metodo di deposito di un oggetto conto bancario per aumentare il saldo del conto.

Attributi e variabili di istanza

Un'auto, oltre ad avere la capacità di svolgere compiti, ha anche attributi , come il suo colore, il suo
numero di porte, quantità di benzina nel serbatoio, velocità attuale e record di miglia totali

guidato (cioè, la sua lettura del contachilometri). Come le sue capacità, gli attributi dell'auto sono rappresentati come
parte del suo design nei suoi diagrammi ingegneristici (che, ad esempio, includono un contachilometri e un

indicatore livello carburante). Mentre guidi un'auto reale, questi attributi vengono trasportati insieme all'auto. Ogni
l'auto mantiene i propri attributi. Ad esempio, ogni macchina sa quanto gas c'è nel proprio gas

serbatoio, ma non quanto c'è nei serbatoi di altre auto.

Un oggetto, allo stesso modo, ha attributi che porta con sé quando viene utilizzato in un programma. Questi

gli attributi sono specificati come parte della classe dell'oggetto. Ad esempio, un oggetto conto bancario ha un'estensione
attributo saldo che rappresenta la quantità di denaro nel conto. Ogni conto in banca

l'oggetto conosce il saldo del conto che rappresenta, ma non i saldi dell'altro
conti in banca. Gli attributi sono specificati dalle variabili di istanza della classe . Una classe

(e i suoi oggetti) attributi e metodi sono intimamente correlati, quindi le classi racchiudono insieme i loro
attributi e metodi.

Eredità
Una nuova classe di oggetti può essere creata comodamente per ereditarietà , la nuova classe (chiamata

sottoclasse ) inizia con le caratteristiche di una classe esistente (chiamata superclasse ),


possibilmente personalizzandoli e aggiungendo caratteristiche proprie uniche. Nella nostra analogia con l'auto,

un oggetto della classe "decappottabile" è certamente un oggetto della classe più generale "automobile",
ma più specificamente , il tetto può essere alzato o abbassato.

Analisi e progettazione orientata agli oggetti (OOAD)


Presto scriverai programmi in Python. Come creerai il codice per i tuoi programmi?

Forse, come molti programmatori, accenderai semplicemente il computer e inizierai a digitare. Questo
l'approccio può funzionare per piccoli programmi (come quelli che presentiamo nei primi capitoli del

book), ma se ti venisse chiesto di creare un sistema software per controllare migliaia di file
sportelli automatici per una grande banca? O supponiamo che ti sia stato chiesto di lavorare in una squadra

di 1.000 sviluppatori di software che costruiscono la prossima generazione del controllo del traffico aereo degli Stati Uniti
sistema? Per progetti così grandi e complessi, non dovresti semplicemente sederti e iniziare a scrivere
programmi.

Per creare le migliori soluzioni, è necessario seguire un processo di analisi dettagliato per la determinazione

i requisiti del progetto (ovvero definire cosa dovrebbe fare il sistema), quindi
sviluppare un design che li soddisfi (cioè, specificando come il sistema dovrebbe farlo). Idealmente,
dovrai seguire questo processo e rivedere attentamente il progetto (e far esaminare il tuo progetto

y altri professionisti del software) prima di scrivere qualsiasi codice. Se questo processo comporta l'analisi
Pagina 31

e progettando il sistema da un punto di vista orientato agli oggetti , si chiama oggetto


processo orientato all'analisi e alla progettazione (OOAD) . Linguaggi come Python sono oggetti
orientate. Programmazione in tale linguaggio, chiamato programmazione orientata agli oggetti (OOP) ,
consente di implementare un progetto orientato agli oggetti come sistema funzionante.
1.3 PITONE
Python è un linguaggio di scripting orientato agli oggetti che è stato rilasciato pubblicamente nel 1991. Lo era

sviluppato da Guido van Rossum del National Research Institute for Mathematics e
Informatica ad Amsterdam.

Python è diventato rapidamente uno dei linguaggi di programmazione più popolari al mondo. Nevica
2
particolarmente popolare per l'informatica educativa e scientifica , e recentemente ha superato il
4
3, ,5
linguaggio di programmazione R come il linguaggio di programmazione datascience più popolare.
7
6, ,
Ecco alcuni motivi per cui Python è popolare e tutti dovrebbero considerare di impararlo:
8

2
TTP: //www.oreilly.com/ideas/5thingstowatchinpythonin2017 .

3
ttps: //www.kdnuggets.com/2017/08/pythonovertakesrleader

nalyticsdatascience.html .

4
ttps: //www.rbloggers.com/datasciencejobreport2017rpasses

asbutpythonleavesthembothbehind / .

5
TTP: //www.oreilly.com/ideas/5thingstowatchinpythonin2017 .

6
TTP: //dbader.org/blog/whylearnpython .

7
ttps: //simpleprogrammer.com/2017/01/18/7reasonswhyyoushould

guadagnapython / .

8
TTP: //www.oreilly.com/ideas/5thingstowatchinpythonin2017 .

È open source, gratuito e ampiamente disponibile con una massiccia comunità opensource.

È più facile da imparare rispetto a linguaggi come C, C ++, C # e Java, consentendo ai principianti e
sviluppatori professionisti per diventare rapidamente operativi.

È più facile da leggere rispetto a molti altri linguaggi di programmazione popolari.

9
È ampiamente utilizzato nell'istruzione.

9
Tollervey, N., Python in Education: Teach, Learn, Program (O'Reilly Media, Inc.,

2015).

hblS
un'

Migliora la produttività degli sviluppatori con ampie librerie standard e di terze parti
Pagina 32

librerie opensource, in modo che i programmatori possano scrivere codice più velocemente ed eseguire attività complesse
con codice minimo. Diremo di più su questo in ezione 1.4.

Esistono un numero enorme di applicazioni Python opensource gratuite.

È popolare nello sviluppo web (ad esempio, Django, Flask).

Supporta i paradigmi di programmazione più diffusi: procedurale, stile funzionale e oggetto


0
orientate. Inizieremo a introdurre le funzionalità di programmazione in stile funzionale in capitolo 4
e utilizzarli nei capitoli successivi.

0
ttps: //en.wikipedia.org/wiki/Python_ (programming_language) .

Semplifica la programmazione simultanea: con asyncio e async / await, sei in grado di scrivere
1
codice simultaneo a thread singolo , semplificando notevolmente i processi intrinsecamente complessi di
2
scrivere, eseguire il debug e mantenere quel codice.

1
ttps: //docs.python.org/3/library/asyncio.html .

2
ttps: //www.oreilly.com/ideas/5thingstowatchinpythonin

017 .
Ci sono molte funzionalità per migliorare le prestazioni di Python.

Viene utilizzato per creare qualsiasi cosa, da semplici script ad app complesse con un numero enorme di file
3
utenti, come Dropbox, YouTube, Reddit, Instagram e Quora.

3
ttps: //www.hartmannsoftware.com/Blog/Articles_from_Software_Fans/Mos

amousSoftwareProgramsWritteninPython .

È popolare nell'intelligenza artificiale, che sta godendo di una crescita esplosiva, in parte a causa di

il suo rapporto speciale con la scienza dei dati.

4
È ampiamente utilizzato nella comunità finanziaria.

4
Kolanovic, M. e R. Krishnamachari, Big Data and AI Strategies: Machine Learning
e Approccio alternativo ai dati per investire (JP Morgan, 2017).

C'è un vasto mercato del lavoro per i programmatori Python in molte discipline,

soprattutto nelle posizioni orientate alla datascienza, e i lavori Python sono tra i più alti
5, 6
pagato di tutti i lavori di programmazione.

5
ttps: //www.infoworld.com/article/3170838/developer/getpaid10

rogramminglanguagestolearnin2017.html .

6
ttps: //medium.com/@ChallengeRocket/top10ofprogramming

C2S
1hptF
Pagina 33
anguageswiththehighestsalariesin20174390f468256e .

R è un popolare linguaggio di programmazione opensource per applicazioni statistiche e


visualizzazione. Python e R sono i due linguaggi di datascience più diffusi.

Anaconda Python Distribution

Usiamo la distribuzione Anaconda Python perché è facile da installare su Windows, macOS


e Linux e supporta le ultime versioni di Python, l'interprete IPython (introdotto in

sezione 1.5.1 ) e Jupyter Notebook (introdotti in sezione 1.5.3 ). Anaconda include anche
altri pacchetti software e librerie comunemente usati nella programmazione e nei dati Python

science, permettendoti di concentrarti su Python e sulla scienza dei dati, piuttosto che sull'installazione del software
7
problemi. L'interprete IPython ha funzionalità che ti aiutano a esplorare, scoprire e sperimentare

con Python, la Python Standard Library e l'ampio set di librerie di terze parti.

7
ttps: //ipython.org/ .

Zen di Python
Aderiamo a The Zen of Python di Tim Peters , che riassume il creatore di Python Guido van

Principi di progettazione di Rossum per il linguaggio. Questo elenco può essere visualizzato in IPython con l'estensione
comando importa questo. Lo Zen di Python è definito nella proposta di miglioramento di Python

(PEP) 20. “Un PEP è un documento di progettazione che fornisce informazioni alla comunità Python, o
8
che descrive una nuova funzionalità per Python o i suoi processi o ambiente. "

8
ttps: //www.python.org/dev/peps/pep0001/ .

1.4 SONO LE BIBLIOTECHE!


In tutto il libro, ci concentriamo sull'utilizzo delle biblioteche esistenti per aiutarti a evitare di "reinventare il
wheel ", sfruttando così i vostri sforzi di sviluppo del programma. Spesso, piuttosto che sviluppare lotti

di codice originale, un processo costoso e che richiede tempo, puoi semplicemente creare un oggetto di un file
classe di libreria preesistente, che accetta solo una singola istruzione Python. Quindi, le biblioteche aiuteranno

si eseguono compiti significativi con modeste quantità di codice. In questo libro userete un ampio
gamma di librerie standard Python, librerie di datascience e librerie di terze parti.

1.4.1 Libreria standard di Python

La libreria standard Python fornisce funzionalità avanzate per l'elaborazione di dati di testo / binari,
matematica, programmazione in stile funzionale, accesso a file / directory, persistenza dei dati, dati
compressione / archiviazione, crittografia, servizi del sistema operativo, programmazione concorrente,

comunicazione tra processi, protocolli di rete, JSON / XML / altri formati di dati Internet,
multimedia, internazionalizzazione, GUI, debugging, profiling e altro. La tabella seguente

elenca alcuni dei moduli della libreria standard Python che usiamo negli esempi.

1S
lh

Alcuni dei moduli della libreria standard Python che usiamo nel libro
Pagina 34

os: interazione con l'operatore


raccolte: dati aggiuntivi
sistema.
strutture oltre elenchi, tuple,
dizionari e set.
coda: i primi dati, i primi
struttura.
csv: elaborazione del valore separato da virgole
File.
casuale: numeri pseudocasuali.

datetime, time: data e ora


re: espressioni regolari per pattern
manipolazioni.
corrispondenza.

decimale: virgola fissa e virgola mobile


sqlite3: database relazionale SQLite
aritmetica, inclusa quella monetaria
accesso.
calcoli.

statistica: statistica matematica


doctest: semplice unit test tramite
funzioni come media, mediana, modalità
test di convalida e risultati attesi
e varianza.
incorporato in docstrings.

string: elaborazione delle stringhe.


json: JavaScript Object Notation (JSON)
elaborazione per l'utilizzo con servizi web e
sys: argomento della riga di comando
Database di documenti NoSQL.
elaborazione; input standard, standard
output e flussi di errore standard.
math: costanti matematiche comuni e
operazioni.
timeit: analisi delle prestazioni.

1.4.2 Biblioteche di scienza dei dati

Python ha una comunità enorme e in rapida crescita di sviluppatori opensource in molti


campi. Uno dei motivi principali della popolarità di Python è la straordinaria gamma di open

librerie di sorgenti sviluppate dalla sua comunità opensource. Uno dei nostri obiettivi è creare
esempi e casi di studio di implementazione che ti danno un coinvolgente, stimolante e

divertente introduzione alla programmazione Python, coinvolgendoti anche nei dati manuali
scienza, biblioteche chiave di datascience e altro ancora. Rimarrai stupito dai compiti sostanziali che svolgi

può essere eseguito in poche righe di codice. La tabella seguente elenca vari dati popolari
biblioteche scientifiche. Userai molti di questi mentre lavori attraverso i nostri esempi di datascience.

Per la visualizzazione, useremo Matplotlib, Seaborn e Folium, ma ce ne sono molti altri. Per un
bel riepilogo delle librerie di visualizzazione Python vedere ttp: //pyviz.org/ .

hS

librerie opulari Python utilizzate nella scienza dei dati


Pagina 35

Informatica scientifica e statistica

NumPy (Numerical Python) - Python non ha una struttura dati di array incorporata.
Utilizza elenchi, che sono convenienti ma relativamente lenti. NumPy fornisce il massimo
struttura dei dati ndarray delle prestazioni per rappresentare elenchi e matrici, e anche

fornisce routine per l'elaborazione di tali strutture di dati.

SciPy (Scientific Python) - Costruito su NumPy, SciPy aggiunge routine per scientific

elaborazione, come integrali, equazioni differenziali, elaborazione di matrici aggiuntive


e altro ancora. scipy.org controlla SciPy e NumPy.

StatsModels— Fornisce supporto per stime di modelli statistici, statistici


test ed esplorazione statistica dei dati.

Manipolazione e analisi dei dati

Panda: una libreria estremamente popolare per la manipolazione dei dati. Pandas fa

uso abbondante di ndarray di NumPy. Le sue due strutture dati chiave sono Series (one

dimensionali) e DataFrames (bidimensionali).

Visualizzazione

Matplotlib: una libreria di grafici e visualizzazioni altamente personalizzabile. Supportato


i grafici includono regolare, dispersione, barra, contorno, torta, faretra, griglia, asse polare, 3D e testo.

Seaborn— Una libreria di visualizzazione di livello superiore costruita su Matplotlib. Seaborn aggiunge un file
aspetto più gradevole, visualizzazioni aggiuntive e consente di creare visualizzazioni
con meno codice.

Machine learning, deep learning e reinforcement learning

scikitlearn: la migliore libreria di machine learning . L'apprendimento automatico è un sottoinsieme dell'IA.


L'apprendimento profondo è un sottoinsieme dell'apprendimento automatico che si concentra sulle reti neurali.

ere— Una delle librerie di deeplearning più facili da usare. Keras corre sopra
K
P
Keras ne f lui asiest o se eep guadagnare ibrari epoche uns n operazione
f Pagina 36

ensorFlow (Google), CNTK (toolkit cognitivo di Microsoft per l'apprendimento profondo) o

Theano (Université de Montréal).

TensorFlow: di Google, questa è la libreria di deep learning più utilizzata.

TensorFlow funziona con GPU (unità di elaborazione grafica) o TPU personalizzate di Google
(Unità di elaborazione tensoriale) per le prestazioni. TensorFlow è importante nell'IA e grande

analisi dei dati, dove le richieste di elaborazione sono enormi. Userai la versione di Keras
che è integrato in TensorFlow.

OpenAI Gym— Una libreria e un ambiente per lo sviluppo, il test e il confronto


algoritmi di rinforzo dell'apprendimento.

Elaborazione del linguaggio naturale (PNL)

NLTK (Natural Language Toolkit) : utilizzato per l'elaborazione del linguaggio naturale (NLP)
compiti.
TextBlob: una libreria di elaborazione del testo NLP orientata agli oggetti costruita su NLTK e
librerie di pattern NLP. TextBlob semplifica molte attività di NLP.

Gensim: simile a NLTK. Comunemente utilizzato per creare un indice per una raccolta di
documenti, quindi determina quanto è simile un altro documento a ciascuno di quelli nel file

indice.

1.5 TEST DRIVES: USO DI IPYTHON E JUPYTER


I QUADERNI
9
In questa sezione, testerai l'interprete IPython in due modalità:

9
Prima di leggere questa sezione, seguire le istruzioni nella sezione Prima di iniziare per l'installazione
la distribuzione Anaconda Python, che contiene l'interprete IPython.

In modalità interattiva , inserirai piccoli bit di codice Python chiamati snippet e

vedere subito i risultati.

In modalità script , eseguirai il codice caricato da un file con estensione .py (short

l-rotleudO
.K
1T

per Python). Tali file sono chiamati script o programmi e generalmente sono più lunghi di
Pagina 37

gli snippet di codice che utilizzerai in modalità interattiva.

Quindi, imparerai come utilizzare l'ambiente basato su browser noto come Jupyter Notebook
0
per scrivere ed eseguire codice Python.

0
Jupyter supporta molti linguaggi di programmazione installando i loro "kernel". Per più
informazioni vedere TTP: //github.com/jupyter/jupyter/wiki/Jupyterkernels .

1.5.1 Utilizzo della modalità interattiva IPython come calcolatrice

Usiamo la modalità interattiva IPython per valutare semplici espressioni aritmetiche.

Accesso a IPython in modalità interattiva


Innanzitutto, apri una finestra della riga di comando sul tuo sistema:

Su macOS, apri un Terminale dalla sottocartella Utilità della cartella Applicazioni.

Su Windows, apri il prompt dei comandi di Anaconda dal menu di avvio.

Su Linux, apri il terminale o la shell del tuo sistema (questo varia a seconda della distribuzione Linux).

Nella finestra di comando, tipo ipython, quindi premere Invio (o Return ). Vedrai il testo

come il seguente, varia in base alla piattaforma e alla versione di IPython:

lecca qui per visualizzare l'immagine del codice

Python 3.7.0 | confezionato da condaforge | (impostazione predefinita, 20 gennaio 2019, 17:24:52)


Digita "copyright", "crediti" o "licenza" per ulteriori informazioni
IPython 6.5.0 Un Python interattivo migliorato. Genere '?'
per un aiuto.

In 1]:

Il testo "In [1]:" è un prompt , che indica che IPython è in attesa del tuo input. Puoi
genere ? per chiedere aiuto o inizia a inserire snippet, come farai momentaneamente.
Valutazione delle espressioni
In modalità interattiva, puoi valutare espressioni:

In [1]: 45 + 72
Uscita [1]: 117

In 2]:

hC
2

Dopo aver digitato 45 + 72 e premuto Invio , IPython legge lo snippet, lo valuta e lo stampa
Pagina 38
1
il suo risultato in Out [1]. Quindi IPython visualizza il prompt In [2] per mostrare che sta aspettando
per inserire il secondo snippet. Per ogni nuovo snippet, IPython aggiunge 1 al numero nel file

parentesi quadre. Ogni prompt In [1] nel libro indica che abbiamo iniziato un nuovo

sessione interattiva. Generalmente lo facciamo per ogni nuova sezione di un capitolo.

1
Nel prossimo capitolo, vedrai che ci sono alcuni casi in cui Out [] non è visualizzato.

Valutiamo un'espressione più complessa:

lecca qui per visualizzare l'immagine del codice

In [2]: 5 * ( 12.7 4 ) / 2
Uscita [2]: 21,75

Python usa l'asterisco (*) per la moltiplicazione e la barra (/) per la divisione. Come in

matematica, le parentesi forzano l'ordine di valutazione, quindi l'espressione tra parentesi (12.7

4) valuta per primo, dando 8.7. Successivamente, 5 * 8,7 valuta dando 43,5. Quindi, 43,5 / 2

valuta, dando il risultato 21.75, che IPython mostra in Out [2]. Numeri interi, tipo

5, 4 e 2, sono chiamati numeri interi . Numeri con punti decimali, come 12,7, 43,5 e 21,75,
sono chiamati numeri in virgola mobile .

Uscita dalla modalità interattiva

Per uscire dalla modalità interattiva, puoi:

Digitare il comando exit al prompt In [] corrente e premere Invio per uscire

subito.

Digita la sequenza di tasti <Ctrl> + d (o <control> + d ). Verrà visualizzato il prompt "Do you

vuoi davvero uscire ([y] / n)? ". Le parentesi quadre intorno a y indicano che è
la risposta predefinita: premendo Invio si invia la risposta predefinita e si esce.

Digita <Ctrl> + d (o <control> + d ) due volte (solo macOS e Linux).

1.5.2 Esecuzione di un programma Python utilizzando l'interprete IPython

In questa sezione, eseguirai uno script chiamato RollDieDynamic.py in cui scrivere

capitolo 6 . L' estensione .py indica che il file contiene codice sorgente Python. Il copione

RollDieDynamic.py simula il lancio di un dado a sei facce. Presenta un animato colorato

visualizzazione che rappresenta graficamente dinamicamente le frequenze di ciascuna faccia della matrice.

Passaggio alla cartella degli esempi di questo capitolo

Troverai lo script nella cartella del codice sorgente ch01 del libro. Nella sezione Prima di iniziare

hai estratto la cartella degli esempi nella cartella Documenti del tuo account utente. Ogni capitolo

2C

ha una cartella contenente il codice sorgente di quel capitolo. La cartella si chiama ch ##, dove ## è un file
Pagina 39

numero del capitolo a due cifre da 01 a 17. Per prima cosa, apri la finestra della riga di comando del tuo sistema.

Quindi, usa il comando cd ("cambia directory") per passare alla cartella ch01:

Su macOS / Linux, digita cd ~ / Documents / examples / ch01, quindi premi Invio .


Su Windows, digita cd C: \ Users \ YourAccount \ Documents \ examples \ ch01, quindi

premere Invio .

Esecuzione dello script

Per eseguire lo script, digita il seguente comando nella riga di comando, quindi premi Invio :

ipython RollDieDynamic.py 6000 1

Lo script mostra una finestra che mostra la visualizzazione. I numeri 6000 e 1 lo dicono

scrivi il numero di volte in cui tirare i dadi e quanti dadi lanciare ogni volta. In questo caso, lo faremo
aggiorna la tabella 6000 volte per 1 dado alla volta.

Per un dado a sei facce, i valori da 1 a 6 dovrebbero ciascuno presentarsi con "uguale probabilità": il
th
la probabilità di ciascuno è 1/6 o circa il 16,667%. Se tiriamo un dado 6000 volte, ce lo aspetteremmo

1000 di ogni faccia. Come il lancio di una moneta, il lancio del dado è casuale , quindi potrebbero esserci delle facce con
meno di 1000, alcuni con 1000 e altri con più di 1000. Abbiamo preso lo schermo
acquisisce di seguito durante l'esecuzione dello script. Questo script utilizza valori di fustella generati casualmente,
quindi i tuoi risultati saranno diversi. Sperimenta con lo script cambiando il valore da 1 a 100, 1000

e 10000. Notare che all'aumentare del numero di tiri di dado, le frequenze si azzerano
16,667%. Questo è un fenomeno del " aw di numeri grandi. "

Creazione di script
In genere, crei il tuo codice sorgente Python in un editor che ti consente di digitare il testo. Utilizzando

l'editor, digiti un programma, apporti le correzioni necessarie e lo salvi sul tuo computer.
Gli ambienti di sviluppo integrati (IDE) forniscono strumenti che supportano l'intero

processo di sviluppo software, come editor, debugger per individuare errori logici che causano
Pagina 40

programmi da eseguire in modo errato e altro ancora. Alcuni popolari IDE Python includono Spyder (che
viene fornito con Anaconda), PyCharm e Visual Studio Code.

Problemi che possono verificarsi al momento dell'esecuzione


I programmi spesso non funzionano al primo tentativo. Ad esempio, un programma in esecuzione potrebbe provare a

dividere per zero (un'operazione illegale in Python). Ciò causerebbe la visualizzazione di un file
messaggio di errore. Se ciò si è verificato in uno script, dovresti tornare all'editor, fare il necessario

correzioni e riesegui lo script per determinare se le correzioni hanno risolto il file


i problemi).

Errori come la divisione per zero si verificano durante l'esecuzione di un programma, quindi vengono chiamati errori di runtime o
errori di esecuzione . Errori irreversibili di runtime causano la chiusura immediata dei programmi

senza aver svolto con successo il proprio lavoro. Gli errori di runtime non irreversibili consentono
programmi da eseguire fino al completamento, producendo spesso risultati errati.

1.5.3 Scrittura ed esecuzione di codice in un notebook Jupyter

Arriva la distribuzione di Anaconda Python che hai installato nella sezione Prima di iniziare
con Jupyter Notebook, un ambiente interattivo basato su browser in cui puoi farlo
scrivere ed eseguire codice e mescolare il codice con testo, immagini e video. Quaderni Jupyter
sono ampiamente utilizzati nella comunità di datascience in particolare e nella più ampia scienza
comunità in generale. Sono il mezzo preferito per eseguire analisi dei dati basate su Python

studi e comunicando in modo riproducibile i loro risultati. L'ambiente Jupyter Notebook


supporta un numero crescente di linguaggi di programmazione.

Per tua comodità, tutto il codice sorgente del libro è fornito anche in Jupyter Notebooks
che puoi semplicemente caricare ed eseguire. In questa sezione utilizzerai l' interfaccia JupyterLab ,

che ti consente di gestire i file del tuo taccuino e altri file usati dai tuoi taccuini (come
immagini e video). Come vedrai, JupyterLab rende anche conveniente scrivere codice, eseguire

it, vedere i risultati, modificare il codice ed eseguirlo di nuovo.

Vedrai che la codifica in un notebook Jupyter è simile a lavorare con IPython, infatti,
I notebook Jupyter utilizzano IPython per impostazione predefinita. In questa sezione creerai un taccuino, aggiungi il file

codice da ezione 1.5.1 ad esso ed eseguire quel codice.

Apertura di JupyterLab nel tuo browser

Per aprire JupyterLab, passa alla cartella degli esempi ch01 nel tuo Terminale, shell o

Prompt dei comandi di Anaconda (come in ezione 1.5.2), digita il seguente comando, quindi premi

Invio (o ritorno ):

jupyter lab

Questo esegue il server Jupyter Notebook sul tuo computer e apre JupyterLab nel tuo file

browser web predefinito, che mostra il contenuto della cartella ch01 nella scheda Browser file
Pagina 41

sul lato sinistro dell'interfaccia JupyterLab:

Il server Jupyter Notebook ti consente di caricare ed eseguire Jupyter Notebooks nel tuo web
browser. Dalla scheda File JupyterLab, puoi fare doppio clic sui file per aprirli a destra

lato della finestra in cui è attualmente visualizzata la scheda Launcher. Ogni file che apri
appare come una scheda separata in questa parte della finestra. Se chiudi accidentalmente il browser,

puoi riaprire JupyterLab inserendo il seguente indirizzo nel tuo browser web

http: // localhost: 8888 / lab

Creazione di un nuovo notebook Jupyter

Nella scheda Launcher sotto Notebook, fai clic sul pulsante Python 3 per creare un nuovo Jupyter
Notebook denominato Untitled.ipynb in cui è possibile inserire ed eseguire il codice Python 3. Il
l'estensione file .ipynb è l'abbreviazione di IPython Notebook, il nome originale di Jupyter

Taccuino.

Rinominare il notebook
Rinomina Untitled.ipynb come TestDrive.ipynb:

1. Fare clic con il pulsante destro del mouse sulla scheda Untitled.ipynb e selezionare Rinomina blocco note.
Pagina 42

2. Modificare il nome in TestDrive.ipynb e fare clic su RENAME.

La parte superiore di JupyterLab dovrebbe ora apparire come segue:

Valutazione di un'espressione

L'unità di lavoro in un taccuino è una cella in cui puoi inserire frammenti di codice. Per impostazione predefinita, un file
il nuovo taccuino contiene una cella, il rettangolo nel taccuino TestDrive.ipynb, ma tu

può aggiungere altro. A sinistra della cella, la notazione []: è dove verrà visualizzato il Jupyter Notebook

il numero dello snippet della cella dopo aver eseguito la cella. Fare clic nella cella, quindi digitare l'espressione

45 + 72

Per eseguire il codice della cella corrente, digita Ctrl + Invio (o control + Invio ). JupyterLab viene eseguito
il codice in IPython, quindi visualizza i risultati sotto la cella:

Aggiunta ed esecuzione di un'altra cella


Valutiamo un'espressione più complessa. Innanzitutto, fai clic sul pulsante + nella barra degli strumenti sopra il file

prima cella del taccuino: aggiunge una nuova cella sotto quella corrente:

Fare clic nella nuova cella, quindi digitare l'espressione

5 * (12,7 4) / 2

Pagina 43

ed esegui la cella digitando Ctrl + Invio (o control + Invio ):


Salvataggio del taccuino
Se il tuo taccuino ha modifiche non salvate, la X nella scheda del taccuino cambierà in. Salvare

il notebook, seleziona il menu File in JupyterLab (non nella parte superiore della finestra del browser),
quindi selezionare Salva blocco appunti.

Quaderni forniti con gli esempi di ogni capitolo


Per tua comodità, vengono forniti anche gli esempi di ogni capitolo pronti per essere eseguiti
notebook senza i relativi output. Ciò ti consente di lavorare attraverso di loro snippetbysnippet

e vedi gli output apparire mentre esegui ogni snippet.

Affinché possiamo mostrarti come caricare un notebook esistente ed eseguire le sue celle, resettiamo il file

Notebook TestDrive.ipynb per rimuovere i numeri di output e di frammento. Questo lo restituirà


a uno stato come i quaderni che forniamo per gli esempi dei capitoli successivi. Dal
Dal menu Kernel selezionare Riavvia kernel e Cancella tutti gli output ..., quindi fare clic su RIAVVIA

pulsante. Il comando precedente è utile anche ogni volta che desideri rieseguire un blocco note
frammenti. Il notebook dovrebbe ora apparire come segue:

Dal menu File, seleziona Salva blocco appunti, quindi fai clic sulla X della scheda TestDrive.ipynb

pulsante per chiudere il notebook.

Apertura ed esecuzione di un blocco note esistente

Quando avvii JupyterLab dalla cartella degli esempi di un determinato capitolo, sarai in grado di aprire
taccuini da quella cartella o da una delle sue sottocartelle. Una volta individuato un taccuino specifico,

fare doppio clic per aprirlo. Apri di nuovo il notebook TestDrive.ipynb ora. Una volta a

notebook è aperto, puoi eseguire ogni cella individualmente, come hai fatto in precedenza in questa sezione, o

puoi eseguire l'intero taccuino in una volta. A tale scopo, dal menu Esegui selezionare Esegui tutto

Cellule. Il notebook eseguirà le celle in ordine, visualizzando l'output di ciascuna cella al di sotto di quello
Pagina 44

cellula.

Chiusura di JupyterLab
Quando hai finito con JupyterLab, puoi chiudere la sua scheda del browser, quindi nel Terminale, shell

o Prompt dei comandi di Anaconda da cui hai avviato JupyterLab, digita Ctrl + c (o
control + c ) due volte.

Suggerimenti JupyterLab
Mentre lavori in JupyterLab, potresti trovare utili questi suggerimenti:

Se devi inserire ed eseguire molti snippet, puoi eseguire la cella corrente e aggiungere

uno nuovo sotto di esso digitando Maiusc + Invio , invece di Ctrl + Invio (o control + Invio ).

Man mano che entri nei capitoli successivi, alcuni degli snippet che inserirai in Jupyter Notebooks
conterrà molte righe di codice. Per visualizzare i numeri di riga all'interno di ogni cella, selezionare Mostra

numeri di riga dal menu Visualizza di JupyterLab.

Ulteriori informazioni sull'utilizzo di JupyterLab


JupyterLab ha molte altre funzionalità che troverai utili. Ti consigliamo di leggere il
Presentazione del team di Jupyter a JupyterLab su:

ttps: //jupyterlab.readthedocs.io/en/stable/index.html

Per una rapida panoramica, fare clic su Panoramica in PER INIZIARE. Inoltre, sotto USER
GUIDA leggi le introduzioni a The JupyterLab Interface, Working with Files, Text

Editor e taccuini per molte funzionalità aggiuntive.

1.6 IL CLOUD E L'INTERNET DELLE COSE

1.6.1 Il cloud

Sempre più computer oggi vengono eseguiti "nel cloud", ovvero distribuiti in tutto il
Internet in tutto il mondo. Molte app che usi quotidianamente dipendono dai servizi basati su cloud che
utilizzare enormi cluster di risorse informatiche (computer, processori, memoria, unità disco,

ecc.) e database che comunicano tra loro su Internet e con le app che utilizzi.
Un servizio che fornisce l'accesso a se stesso su Internet è noto come servizio web . Come te

vedete, l'utilizzo di servizi basati su cloud in Python spesso è semplice come creare un oggetto software e
interagendo con esso. Quell'oggetto utilizza quindi i servizi Web che si connettono al cloud sul tuo

per conto.

Attraverso il hapters 11 - 6 esempi, lavorerai con molti servizi basati su cloud:

1C
h

Nel hapters 12 e 6 , utilizzerai i servizi web di Twitter (tramite la libreria Python Tweepy) per
Pagina 45

ottenere informazioni su utenti Twitter specifici, cercare i tweet degli ultimi sette giorni

e ricevere flussi di tweet non appena si verificano, ovvero in tempo reale.

Nel hapters 11 e 2 , utilizzerai la libreria Python TextBlob per tradurre il testo tra
le lingue. Dietro le quinte, TextBlob utilizza il servizio web di Google Translate per eseguire

quelle traduzioni.

Nel Nel capitolo 13 , utilizzerai Text to Speech, Speech to Text e Translate di IBM Watson
Servizi. Implementerai un'app di traduzione per assistente di viaggio che ti consente di parlare
una domanda in inglese, trascrive il discorso in testo, traduce il testo in spagnolo e

parla il testo spagnolo. L'app ti consente quindi di pronunciare una risposta in spagnolo (nel caso tu
non parlo spagnolo, forniamo un file audio che puoi utilizzare), trascrive il discorso in testo,

traduce il testo in inglese e parla la risposta in inglese. Tramite demo IBM Watson,
sperimenterai anche molti altri servizi basati su cloud Watson in formato capitolo 13 .

Nel al capitolo 16 , lavorerai con il servizio HDInsight di Microsoft Azure e altri servizi Web di Azure
servizi mentre si implementano applicazioni bigdata utilizzando Apache Hadoop e Spark. Azzurro

è il set di servizi basati su cloud di Microsoft.

Nel al capitolo 16 , utilizzerai il servizio web Dweet.io per simulare una connessione a Internet
termostato che pubblica online le letture della temperatura. Utilizzerai anche un file webbased

servizio per creare un “cruscotto” che visualizzi le letture di temperatura nel tempo e
ti avverte se la temperatura diventa troppo bassa o troppo alta.

Nel al capitolo 16 , utilizzerai una dashboard basata sul web per visualizzare un flusso simulato di live
dati del sensore dal servizio web PubNub. Creerai anche un'app Python che visualizza un file

PubNub simulava il flusso di variazioni del prezzo delle azioni in tempo reale.

Nella maggior parte dei casi, creerai oggetti Python che interagiscono con i servizi web per tuo conto,

nascondere i dettagli su come accedere a questi servizi su Internet.

Mashup
La metodologia di sviluppo delle applicazioni dei mashup consente di sviluppare rapidamente

potenti applicazioni software combinando servizi web complementari (spesso gratuiti) e


altre forme di feed di informazioni, come farai con il nostro assistente di viaggio IBM Watson
app di traduzione. Uno dei primi mashup combinava gli elenchi di immobili forniti da
ttp: //www.craigslist.org con le funzionalità di mappatura di Google Maps da offrire
mappe che mostravano l'ubicazione delle case in vendita o in affitto in una determinata area.

ProgrammableWeb ( ttp: //www.programmableweb.com/ ) fornisce una directory di over


20.750 servizi web e quasi 8.000 mashup. Forniscono anche guide e campioni
codice per lavorare con i servizi web e creare i propri mashup. Secondo loro
sito web, alcuni dei servizi web più utilizzati sono Facebook, Google Maps, Twitter e

1
hC

ouTube.
Pagina 46

1.6.2 Internet delle cose

Internet non è più solo una rete di computer , è un Internet of Things (IoT) . UN

cosa è qualsiasi oggetto con un indirizzo IP e la capacità di inviare, e in alcuni casi ricevere, dati
automaticamente su Internet. Queste cose includono:

un'auto con transponder per il pagamento dei pedaggi,

monitora la disponibilità di posti auto in garage,

un cardiofrequenzimetro impiantato in un essere umano,

monitor della qualità dell'acqua,

un contatore intelligente che segnala l'utilizzo di energia,

rilevatori di radiazioni,

tracker articoli in un magazzino,

app mobili in grado di monitorare i tuoi movimenti e la tua posizione,

termostati intelligenti che regolano la temperatura della stanza in base alle previsioni meteorologiche e all'attività
in casa e

elettrodomestici intelligenti.

Secondo statista.com, oggi sono già in uso oltre 23 miliardi di dispositivi IoT e
2
potrebbero esserci oltre 75 miliardi di dispositivi IoT nel 2025.

2
ttps: //www.statista.com/statistics/471264/iotnumberofconnected

evicesworldwide / .

1.7 QUANTO SONO GRANDI I BIG DATA?


Per gli informatici e gli scienziati dei dati, i dati ora sono importanti quanto la scrittura di programmi.

Secondo IBM, vengono creati circa 2,5 quintilioni di byte (2,5 exabyte ) di dati
3 4
ogni giorno e il 90% dei dati mondiali è stato creato negli ultimi due anni. Secondo IDC, il

la fornitura globale di dati raggiungerà i 175 zettabyte (pari a 175 trilioni di gigabyte o 175 miliardi
5
terabyte) all'anno entro il 2025. Considera i seguenti esempi di vari dati popolari

le misure.

3
ttps: //www.ibm.com/blogs/watson/2016/06/welcometotheworldofa
/.

hdY
2io

4 Pagina 47
ttps: //public.dhe.ibm.com/common/ssi/ecm/wr/en/wrl12345usen/watson

il coinvolgimento del clientewatsonmarketingwrotherpaperandreports

rl12345usen20170719.pdf .

5
ttps: //www.networkworld.com/article/3325397/storage/idcexpect
75zettabytesofdataworldwideby2025.html .

egabyte (MB)
20
Un megabyte equivale a circa un milione (in realtà 2) byte. Molti dei file che usiamo quotidianamente

base richiedono uno o più MB di spazio di archiviazione. Alcuni esempi includono:

6
File audio MP3: gli MP3 di alta qualità vanno da 1 a 2,4 MB al minuto.

6
ttps: //www.audiomountain.com/tech/audiofilesize.html .

Foto: le foto in formato JPEG scattate con una fotocamera digitale possono richiedere circa 8-10 MB ciascuna

foto.

Video: le fotocamere degli smartphone possono registrare video a varie risoluzioni. Ogni minuto di

il video può richiedere molti megabyte di spazio di archiviazione. Ad esempio, su uno dei nostri iPhone, il file
L'app per le impostazioni della fotocamera segnala che richiede un video 1080p a 30 framespersecond (FPS)

130 MB / minuto e video 4K a 30 FPS richiedono 350 MB / minuto.

Gigabyte (GB)
30
Un gigabyte corrisponde a circa 1000 megabyte (in realtà 2 byte). Un DVD duallayer può memorizzare fino a
7
8,5 GB , che si traduce in:

7
ttps: //en.wikipedia.org/wiki/DVD .

fino a 141 ore di audio MP3,

circa 1000 foto da una fotocamera da 16 megapixel,

circa 7,7 minuti di video 1080p a 30 FPS o

circa 2,85 minuti di video 4K a 30 FPS.

8
Gli attuali dischi Ultra HD Bluray con la più alta capacità possono memorizzare fino a 100 GB di video.
Lo streaming di un film 4K può utilizzare tra 7 e 10 GB all'ora (altamente compresso).

8
TTP: //en.wikipedia.org/wiki/Ultra_HD_Bluray .

Terabyte (TB)
40
Un terabyte è di circa 1000 gigabyte (in realtà 2 byte). Unità disco recenti per desktop

M
9
2h
1
w
9
I computer sono disponibili in dimensioni fino a 15 TB, che è equivalente a:
Pagina 48

9
ttps: //www.zdnet.com/article/worldsbiggestharddrivemeet

esterndigitals15tbmonster / .

circa 28 anni di audio MP3,

circa 1,68 milioni di foto da una fotocamera da 16 megapixel,

circa 226 ore di video 1080p a 30 FPS e

circa 84 ore di video 4K a 30 FPS.

Nimbus Data ora ha la più grande unità a stato solido (SSD) a 100 TB, che può memorizzare 6,67
0
volte i 15 TB di esempi di audio, foto e video sopra elencati.

0
ttps: //www.cinema5d.com/nimbusdata100tbssdworldslargestssd/ .

Petabyte, Exabyte e Zettabyte


Ci sono quasi quattro miliardi di persone online che creano circa 2,5 quintilioni di byte di dati ciascuno
1
giorno : 2500 petabyte (ogni petabyte corrisponde a circa 1000 terabyte) o 2,5 exabyte (ciascuno
exabyte è di circa 1000 petabyte). Secondo un articolo di AnalyticsWeek di marzo 2016 , all'interno

cinque anni ci saranno oltre 50 miliardi di dispositivi connessi a Internet (la maggior parte
attraverso l'Internet of Things, di cui discutiamo in ezioni 1.6.2 e 6.8 ) ed entro il 2020
2
produrremo 1,7 megabyte di nuovi dati ogni secondo per ogni persona sul pianeta .
3
Con i numeri di oggi (circa 7,7 miliardi di persone ) , questo è circa

1
ttps: //public.dhe.ibm.com/common/ssi/ecm/wr/en/wrl12345usen/watson

il coinvolgimento del clientewatsonmarketingwrotherpaperandreports

rl12345usen20170719.pdf .

2
ttps: //analyticsweek.com/content/bigdatafacts/ .

3
ttps: //en.wikipedia.org/wiki/World_population .

13 petabyte di nuovi dati al secondo,

780 petabyte al minuto,

46.800 petabyte (46,8 exabyte) all'ora e

1.123 exabyte al giorno, ovvero 1,123 zettabyte (ZB) al giorno (ogni zettabyte corrisponde a circa 1000
exabyte).

È l'equivalente di oltre 5,5 milioni di ore (oltre 600 anni) di video 4K ogni giorno o

c132hw
S

circa 116 miliardi di foto ogni giorno!


Pagina 49

Statistiche aggiuntive sui Big Data

Per un divertente senso in tempo reale dei big data, dai un'occhiata

ttps: //www.internetlivestats.com , con varie statistiche, compresi i numeri


finora oggi di

Ricerche su Google.

Tweets.

Video visualizzati su YouTube.

Foto caricate su Instagram.

È possibile fare clic su ciascuna statistica per visualizzare in dettaglio e ottenere ulteriori informazioni. Ad esempio, dicono finita
Nel 2018 sono stati inviati 250 miliardi di tweet.

Alcuni altri fatti interessanti sui bigdata:

Ogni ora, gli utenti di YouTube caricano 24.000 ore di video e quasi 1 miliardo di ore
4
i video vengono guardati su YouTube ogni giorno.

4
ttps: //www.brandwatch.com/blog/youtubestats/ .

Ogni secondo, ci sono 51.773 GB (o 51.773 TB) di traffico Internet, 7894 tweet inviati,
5
64.332 ricerche su Google e 72.029 video di YouTube visualizzati.

5
TTP: //www.internetlivestats.com/onesecond .

6 7
Su Facebook ogni giorno ci sono 800 milioni di " Mi piace", vengono inviati 60 milioni di emoji e

ci sono oltre due miliardi di ricerche degli oltre 2,5 trilioni di post di Facebook da quando il
8
inizio del sito.

6
ttps: //newsroom.fb.com/news/2017/06/twobillionpeoplecoming

ogetheronfacebook .
7 ttps: //mashable.com/2017/07/17/facebookworldemojiday/ .

8
ttps: //techcrunch.com/2016/07/27/facebookwillmakeyoutalk/ .

Nel giugno 2017, Will Marshall, CEO di Planet, ha affermato che la società ha 142 satelliti

immagine la massa terrestre dell'intero pianeta una volta al giorno. Aggiungono un milione di immagini e sette
TB di nuovi dati ogni giorno. Insieme ai loro partner, stanno utilizzando l'apprendimento automatico
quei dati per migliorare i raccolti, vedere quante navi ci sono in un dato porto e seguire

tun'
3h

eforestazione. Per quanto riguarda la deforestazione dell'Amazzonia, ha detto: "Una volta ci svegliavamo
Pagina 50

dopo pochi anni e in Amazzonia c'è un grosso buco. Ora possiamo letteralmente contare ogni
9
albero del pianeta ogni giorno. "

9
ttps: //www.bloomberg.com/news/videos/20170630/learningfrom

lanetsshoeboxedsizedsatellitesvideo , 30 Giugno 2017.

Domo, Inc. ha una bella infografica chiamata "I dati non dormono mai 6.0" che mostra la quantità di dati
0
generato ogni minuto , inclusi:

0
TTP: //www.domo.com/learn/dataneversleeps6 .

473.400 tweet inviati.

2.083.333 foto Snapchat condivise.

97.222 ore di video Netflix visualizzate.

12.986.111 milioni di messaggi di testo inviati.

49.380 post su Instagram.

176.220 chiamate Skype.

750.000 brani Spotify trasmessi in streaming.

3.877.140 ricerche su Google.

4.333.560 video di YouTube guardati.

Potenza informatica nel corso degli anni


I dati stanno diventando sempre più grandi, così come la potenza di calcolo per elaborarli. Il
le prestazioni dei processori odierni sono spesso misurate in termini di FLOPS (floatingpoint

operazioni al secondo) . Nella prima metà degli anni '90, le velocità dei supercomputer più elevate erano
9 12
misurata in gigaflop (10 FLOP). Alla fine degli anni '90, Intel ha prodotto il primo teraflop (10

FLOPS) supercomputer. All'inizio degli anni 2000, le velocità raggiunsero centinaia di teraflop,
15
poi, nel 2008, IBM ha rilasciato il primo supercomputer petaflop (10 FLOPS). Attualmente, il
supercomputer più veloce: l'IBM Summit, situato presso il Dipartimento dell'Energia (DOE) Oak
1
Ridge National Laboratory (ORNL): è in grado di eseguire 122,3 petaflop.

1
ttps: //en.wikipedia.org/wiki/FLOPS .

L'elaborazione distribuita può collegare migliaia di personal computer tramite Internet per la produzione
ancora più FLOP. Alla fine del 2016, la rete Folding @ home, una rete distribuita in cui

le persone offrono volontariamente le risorse dei loro personal computer per l'uso nella ricerca sulle malattie e sui farmaci

2 43

pd
43h

2 3
esign — era capace di oltre 100 petaflop. Aziende come IBM stanno ora lavorando
Pagina 51
18 4
supercomputer in grado di eseguire exaflops (10 FLOPS).

2
ttps: //en.wikipedia.org/wiki/Folding@home .
3 ttps: //en.wikipedia.org/wiki/FLOPS .

4
ttps: //www.ibm.com/blogs/research/2017/06/supercomputingweather

odelexascale / .

I computer quantistici attualmente in fase di sviluppo potrebbero teoricamente funzionare


5
18.000.000.000.000.000.000 di volte la velocità dei "computer convenzionali" di oggi! Questo

numero è così straordinario che in un secondo, teoricamente, un computer quantistico potrebbe farlo
incredibilmente più calcoli rispetto al totale che sono stati fatti da tutti i computer dopo il
apparve il primo computer al mondo. Questa potenza di calcolo quasi inimmaginabile potrebbe provocare

caos con criptovalute basate su blockchain come Bitcoin. Gli ingegneri stanno già ripensando
6
blockchain per prepararsi a tali massicci aumenti della potenza di calcolo.

5
ttps: //medium.com/@n.biedrzycki/onlygodcancountthatfastthe
orldofquantumcomputing406a0a91fcf4 .

6
ttps: //singularityhub.com/2017/11/05/isquantumcomputingan

xistentialthreattoblockchaintechnology / .

La storia del potere del supercalcolo è che alla fine si fa strada dalla ricerca
laboratori, dove sono state spese straordinarie somme di denaro per ottenere tali prestazioni

numeri, in sistemi informatici commerciali "a prezzi ragionevoli" e persino desktop


computer, laptop, tablet e smartphone.

Il costo della potenza di elaborazione continua a diminuire, soprattutto con il cloud computing. Persone usate
per porre la domanda: "Di quanta potenza di calcolo ho bisogno sul mio sistema per gestire il mio

esigenze di elaborazione di picco ? " Oggi, quel pensiero si è spostato su "Posso ritagliarmi rapidamente sul
cloud ciò di cui ho bisogno temporaneamente per le mie faccende informatiche più impegnative? " Paghi solo

cosa usi per svolgere un determinato compito.

L'elaborazione dei dati mondiali richiede molta elettricità

I dati provenienti dai dispositivi connessi a Internet di tutto il mondo stanno esplodendo e stanno elaborando tali dati
richiede enormi quantità di energia. Secondo un recente articolo, l'uso di energia per
l'elaborazione dei dati nel 2015 cresceva del 20% all'anno e consumava circa tre a
cinque per cento della potenza mondiale. L'articolo dice che il potere totale di elaborazione dei dati
7
il consumo potrebbe raggiungere il 20% entro il 2025.

7
ttps: //www.theguardian.com/environment/2017/dec/11/tsunamiof

atacouldconsumefifthglobalelectricityby2025 .

4d
m
hew

Un altro enorme consumatore di elettricità è la criptovaluta basata su blockchain Bitcoin.


Pagina 52

L'elaborazione di una sola transazione Bitcoin utilizza approssimativamente la stessa quantità di energia di

alimentare la casa americana media per una settimana! Il consumo di energia deriva dal processo
8
I "minatori" di Bitcoin usano per dimostrare che i dati delle transazioni sono validi.

8
ttps: //motherboard.vice.com/en_us/article/ywbbpm/bitcoinmining

lectricityconsumptionethereumenergyclimatechange .

Secondo alcune stime, un anno di transazioni Bitcoin consuma più energia di


9
molti paesi. Insieme, Bitcoin ed Ethereum (un'altra popolare blockchain basata
piattaforma e criptovaluta) consumano più energia all'anno rispetto a Israele e quasi altrettanto
0
come la Grecia.

9
TTP: //digiconomist.net/bitcoinenergyconsumption .

0
TTP: //digiconomist.net/ethereumenergyconsumption .

Morgan Stanley ha previsto nel 2018 che "il consumo di elettricità necessario per creare
Le criptovalute quest'anno potrebbero effettivamente superare il veicolo elettrico globale previsto dall'azienda
1
domanda, nel 2025 ". Questa situazione è insostenibile, soprattutto visto l'enorme interesse per
applicazioni basate su blockchain, anche oltre l'esplosione della criptovaluta. La blockchain
2, 3
la comunità sta lavorando alle correzioni.

1
ttps: //www.morganstanley.com/ideas/cryptocurrenciesglobal

capacità .

2
ttps: //www.technologyreview.com/s/609480/bitcoinusesmassive

mountsofenergybuttheresaplantofixit / .

3
ttp: //mashable.com/2017/12/01/bitcoinenergy/ .

Opportunità per i big data

È probabile che l'esplosione dei bigdata continui in modo esponenziale negli anni a venire. Con 50 miliardi
dispositivi informatici all'orizzonte, possiamo solo immaginare quanti altri ce ne saranno nel corso del

nei prossimi decenni. È fondamentale per le aziende, i governi, i militari e persino gli individui
per avere un controllo su tutti questi dati.

È interessante notare che alcuni dei migliori scritti su big data, data science, artificiale
intelligenza e altro ancora da distinte organizzazioni imprenditoriali, come JP

Morgan, McKinsey e altri ancora. Il fascino dei big data per le grandi imprese è innegabile dato il
risultati in rapida accelerazione. Molte aziende stanno facendo investimenti significativi

e ottenere risultati preziosi attraverso le tecnologie di questo libro, come big data, machine
apprendimento, apprendimento profondo ed elaborazione del linguaggio naturale. Questo costringe i concorrenti a investire

inoltre, aumentando rapidamente la necessità di professionisti informatici con datascience e


esperienza in informatica. È probabile che questa crescita continui per molti anni.

.7.1 Analisi dei Big Data


1
54UN
ue
hun'
.7.1 Analisi dei Big Data Pagina 53

L'analisi dei dati è una disciplina accademica e professionale matura e ben sviluppata. Il termine
4
"Analisi dei dati" è stata coniata nel 1962, anche se le persone hanno analizzato i dati utilizzando le statistiche
5
per migliaia di anni risalendo agli antichi egizi. L'analisi dei big data è qualcosa di più
6
fenomeno recente: il termine "big data" è stato coniato intorno al 2000.

4
ttps: //www.forbes.com/sites/gilpress/2013/05/28/averyshort

istoryofdatascience / .

5
ttps: //www.flydata.com/blog/abriefhistoryofdataanalysis/ .

6
ttps: //bits.blogs.nytimes.com/2013/02/01/theoriginsofbigdata

netymologicaldetectivestory / .

7, 8
Considera quattro delle V dei big data :

7
TTP: //www.ibmbigdatahub.com/infographic/fourvsbigdata .

8
Ci sono molti articoli e documenti che aggiungono molti altri Vwords a questo elenco.

1. Volume: la quantità di dati che il mondo sta producendo sta crescendo in modo esponenziale.

2. Velocità: la velocità con cui vengono prodotti i dati, la velocità con cui si muovono
0
9,, 1
attraverso le organizzazioni e la velocità con cui i dati cambiano stanno crescendo rapidamente.

9
ttps: //www.zdnet.com/article/volumevelocityandvariety

nderstandingthreevsofbigdata / .

0
ttps: //whatis.techtarget.com/definition/3Vs .

1
ttps: //www.forbes.com/sites/brentdykes/2017/06/28/bigdata

orgetvolumeandvarietyfocusonvelocity .

3. Varietà: i dati erano alfanumerici (cioè costituiti da caratteri alfabetici, cifre,

punteggiatura e alcuni caratteri speciali): oggi include anche immagini, audio, video
e dati da un numero sempre maggiore di sensori Internet of Things nelle nostre case,

aziende, veicoli, città e altro ancora.


4. La veridicità - la validità dei dati - è completa e accurata? Possiamo fidarci di quei dati

quando si prendono decisioni cruciali? È vero?

La maggior parte dei dati viene ora creata digitalmente in una varietà di tipi, in volumi straordinari e
muovendosi a velocità sorprendenti . La legge di Moore e le relative osservazioni ci hanno permesso di farlo
archiviare i dati in modo economico e elaborarli e spostarli più velocemente, e il tutto a velocità in crescita

esponenzialmente nel tempo. L'archiviazione dei dati digitali è diventata così vasta in termini di capacità, economica e piccola

1
2

566h
uf n'

che ora possiamo conservare comodamente ed economicamente tutti i dati digitali che stiamo creando.
2 Pagina 54

Sono i big data.

2
ttp: //www.lesk.com/mlesk/ksg97/ksg.html . [Il seguente articolo ci ha indicato
questo articolo di Michael Lesk:

ttps: //www.forbes.com/sites/gilpress/2013/05/28/averyshort

istoryofdatascience / .]

La seguente citazione di Richard W. Hamming, sebbene del 1962, dà il tono per il resto

questo libro:

3
"Lo scopo del calcolo è la comprensione, non i numeri."

3
Hamming, R. W., Numerical Methods for Scientists and Engineers (New York, NY.,
McGraw Hill, 1962). [Il seguente articolo ci ha indicato il libro di Hamming e la sua citazione

abbiamo citato:ttps: //www.forbes.com/sites/gilpress/2013/05/28/avery

horthistoryofdatascience / .]

La scienza dei dati sta producendo informazioni nuove, più profonde, più sottili e più preziose a un livello straordinario

ritmo. Sta davvero facendo la differenza. L'analisi dei big data è parte integrante della risposta. Noi
affrontare l'infrastruttura di big data in capitolo 16 con casi di studio handson su NoSQL

database, programmazione Hadoop MapReduce, Spark, Internet of Things (IoT) in tempo reale
programmazione del flusso e altro ancora.

Per avere un'idea della portata dei big data nell'industria, nel governo e nel mondo accademico, dai un'occhiata agli alti
4
grafica di risoluzione. Puoi fare clic per ingrandire per una più facile leggibilità:

4
Turck, M. e J. Hao, Great Power, Great Responsibility: The 2018 Big Data & AI
Paesaggio, ttp: //mattturck.com/bigdata2018/ .

ttp: //mattturck.com/wpcontent/uploads/2018/07/Matt_Turck_FirstMark_Big_Data_L ndscape_

.7.2 Scienza dei dati e Big Data fanno la differenza: casi d'uso

Il campo di datascience sta crescendo rapidamente perché sta producendo risultati significativi
Fare la differenza. Enumeriamo i casi di utilizzo di datascience e big data nella tabella seguente.

Ci aspettiamo che i casi d'uso e i nostri esempi in tutto il libro ti ispirino


perseguire nuovi casi d'uso nella tua carriera. L'analisi dei bigdata ha portato a migliori profitti,

migliori relazioni con i clienti e persino squadre sportive che vincono più partite e campionati
6
5,, 7
spendendo meno per i giocatori.

5
Sawchik, T., Big Data Baseball: matematica, miracoli e la fine di una serie di perdite di 20 anni
(New York, Flat Iron Books, 2015).

1
6

hC
66h
S
6
Ayres, I., Super Crunchers (Bantam Books, 2007), pagg.7 10.
Pagina 55

7
Lewis, M., Moneyball: The Art of Winning an Unfair Game (W. W. Norton & Company,

2004).
uso atascience
casi

rilevamento delle anomalie

assistere le persone
con disabilità

rischio di autoassicurazione

predizione

chiuso automatizzato

sottotitoli

immagine automatizzata
prevedere il tempo
didascalie
vendite di prodotti sensibili

investimenti automatizzati riconoscimento facciale analisi predittiva

navi autonome
monitoraggio del fitness medicina preventiva

mappatura del cervello intercettazione di una frode


prevenire le malattie
focolai
identificazione del chiamante gioco

leggere la lingua dei segni


cancro
genomica e sanità
diagnosi / trattamento
valutazione immobiliare
Sistemi di informazione geografica
emissioni di carbonio
(GIS) raccomandazione
riduzione
sistemi
Sistemi GPS
classificando
ridurre l'overbooking
grafia miglioramento dei risultati di salute

ride sharing
visione computerizzata riduzione della riammissione ospedaliera

minimizzazione del rischio


livello di crediti sequenziamento del genoma umano

robo financial advisor


crimine: previsione prevenzione del furto di identità
posizioni
miglioramenti della sicurezza

6D

rime: predire immunoterapia auto a guida autonoma


Pagina 56

recidività
prezzi assicurativi analisi del sentiment

crimine: predittivo
polizia assistenti intelligenti sharing economy

prevenzione del crimine Internet of Things (IoT) e rilevamento della somiglianza


monitoraggio di dispositivi medici
città intelligenti
Gene CRISPR
la modifica Internet delle cose e del tempo
previsione case intelligenti

resa delle colture


contatori intelligenti
miglioramento controllo dell'inventario

traduzione in lingua termostati intelligenti


fidelizzazione dei clienti

servizi basati sulla posizione controllo intelligente del traffico


cliente
Esperienza
analisi sociale
programmi fedeltà

fidelizzazione dei clienti


rilevamento di malware analisi del grafico sociale
cliente Mappatura rilevamento dello spam
soddisfazione

analisi dei dati spaziali


marketing
assistenza clienti

analisi di marketing reclutamento sportivo e


assistenza clienti
istruire
agenti
generazione di musica
previsioni del mercato azionario
diete personalizzate
traduzione naturallanguage
rendimento degli studenti
sicurezza informatica
nuovi prodotti farmaceutici valutazione

estrazione dei dati


prevenzione dell'abuso di oppioidi testo riassuntivo

visualizzazione dati
assistenti personali telemedicina

rilevamento di nuovi
medicina personalizzata attacco terroristico
virus
prevenzione
acquisti personalizzati
diagnosi del seno
prevenzione dei furti
cancro eliminazione del phishing

consigli di viaggio
diagnosi del cuore riduzione dell'inquinamento
patologia individuazione delle tendenze
medicina di precisione
medicina diagnostica ricerca visiva del prodotto
prevedere la sopravvivenza al cancro

vittima di disastro prevedere focolai di malattie riconoscimento vocale


Pagina 57

identificazione
prevedere i risultati di salute ricerca vocale
droni
prevedere le iscrizioni degli studenti previsioni del tempo
guida dinamica

itinerari

prezzi dinamici

salute elettronica

record

rilevamento delle emozioni

energia
consumo

riduzione

1.8 CASO DI STUDIO: APPLICAZIONE MOBILE PER BIG DATA


8
L'app di navigazione GPS Waze di Google, con i suoi 90 milioni di utenti attivi mensilmente, è una delle

app bigdata di maggior successo. I primi dispositivi e app di navigazione GPS si basavano su mappe statiche
e coordinate GPS per determinare il percorso migliore verso la destinazione. Non potevano adattarsi

dinamicamente al mutare delle situazioni di traffico.

8
ttps: //www.waze.com/brands/drivers/ .

Waze elabora enormi quantità di dati in crowdsourcing , ovvero i dati che sono

continuamente forniti dai loro utenti e dai dispositivi dei loro utenti in tutto il mondo. Lo analizzano
dati man mano che arrivano per determinare il percorso migliore per arrivare a destinazione nel minimo

quantità di tempo. Per farlo, Waze si affida alla connessione Internet del tuo smartphone.
L'app invia automaticamente gli aggiornamenti della posizione ai propri server (supponendo che tu lo consenta).
Usano questi dati per reindirizzarti dinamicamente in base alle condizioni del traffico correnti e a
sintonizza le loro mappe. Gli utenti segnalano altre informazioni, come blocchi stradali, lavori in corso, ostacoli,

veicoli in corsie di emergenza, posizioni della polizia, prezzi del gas e altro ancora. Waze quindi avvisa gli altri
conducenti in quelle località.

Waze utilizza molte tecnologie per fornire i suoi servizi. Non siamo al corrente di come sia Waze
implementato, ma deduciamo di seguito un elenco di tecnologie che probabilmente utilizzano. Userai molti di

questi in hapters 11 - 6 . Per esempio,

C
61
h

La maggior parte delle app create oggi utilizza almeno alcuni software opensource. Ne approfitterai Pagina 58

molte biblioteche e strumenti opensource in questo libro.

Waze comunica informazioni su Internet tra i propri server e i propri utenti


dispositivi mobili. Oggi, tali dati vengono spesso trasmessi in JSON (JavaScript Object

Notation), che introdurremo in capitolo 9 e utilizzarlo nei capitoli successivi. Il


I dati JSON sono in genere nascosti dalle librerie che utilizzi.

Waze utilizza la sintesi vocale per pronunciare le indicazioni stradali, gli avvisi e la voce
riconoscimento per comprendere i tuoi comandi vocali. Usiamo il discorso di IBM Watson

capacità di sintesi e riconoscimento vocale in capitolo 13 .

Una volta che Waze converte in testo un comando parlato in naturallanguage, deve determinare il

azione corretta da eseguire, che richiede l'elaborazione del linguaggio naturale (PNL). Noi presentiamo
PNL in capitolo 11 e utilizzarlo in diversi capitoli successivi.

Waze mostra visualizzazioni aggiornate dinamicamente come avvisi e mappe. Anche Waze
ti consente di interagire con le mappe spostandole o ingrandendole e riducendole. Noi creiamo

visualizzazioni dinamiche con Matplotlib e Seaborn in tutto il libro e noi mostriamo


mappe interattive con Folium in formato hapters 12 e 6.

Waze utilizza il tuo telefono come dispositivo Internet of Things (IoT) in streaming. Ogni telefono è un file
Sensore GPS che trasmette continuamente dati su Internet a Waze. Nel capitolo 16 , noi

introdurre l'IoT e lavorare con sensori di streaming IoT simulati.

Waze riceve flussi IoT da milioni di telefoni contemporaneamente. Deve elaborare, archiviare e
analizza immediatamente quei dati per aggiornare le mappe del tuo dispositivo, per visualizzare e parlare in modo pertinente

avvisi ed eventualmente per aggiornare le indicazioni stradali. Ciò richiede un enorme parallelismo
capacità di elaborazione implementate con cluster di computer nel cloud. Nel hapter

6 , introdurremo varie tecnologie di infrastruttura bigdata per la ricezione dello streaming


dati, archiviando tali big data in database appropriati ed elaborando i dati con il software

e hardware che forniscono capacità di elaborazione massicciamente parallele.

Waze utilizza funzionalità di intelligenza artificiale per eseguire le attività di analisi dei dati che abilitano

prevedere i percorsi migliori in base alle informazioni che riceve. Nel hapters 14 e 5 noi
utilizzare rispettivamente il machine learning e il deep learning per analizzare enormi quantità di dati

e fare previsioni basate su quei dati.

Waze probabilmente memorizza le sue informazioni di instradamento in un database a grafo. Tali database possono

calcolare in modo efficiente i percorsi più brevi. Introduciamo database a grafo, come Neo4J, in
capitolo 16 .

Molte auto sono ora dotate di dispositivi che consentono loro di "vedere" auto e ostacoli
intorno a loro. Questi vengono utilizzati, ad esempio, per aiutare a implementare sistemi di frenatura automatizzati

e sono una parte fondamentale della tecnologia delle auto a guida autonoma. Piuttosto che affidarsi agli utenti per la segnalazione

1
C

ostacoli e auto ferme sul ciglio della strada, le app di navigazione potrebbero trarne vantaggio Pagina 59

di telecamere e altri sensori utilizzando tecniche di calcolo approfondito per


analizzare le immagini "al volo" e segnalare automaticamente tali elementi. Introduciamo in profondità

apprendimento per la visione artificiale in capitolo 15 .


1.9 INTRO ALLA DATA SCIENCE: INTELLIGENZA ARTIFICIALE—
ALL'INTERSEZIONE DI CS E DATA SCIENCE
Quando un bambino apre gli occhi per la prima volta, "vede" i volti dei suoi genitori? Ne capisce qualcosa

nozione di cosa sia una faccia, o anche di cosa sia una forma semplice? I bambini devono "imparare" il mondo
intorno a loro. Questo è ciò che sta facendo l'intelligenza artificiale (AI) oggi. Sembra enorme

quantità di dati e imparare da essi. L'intelligenza artificiale viene utilizzata per giocare, implementare una vasta gamma
delle applicazioni di computervision, abilitano le auto che si guidano da sole, consentono ai robot di imparare a eseguire

nuove attività, diagnosticare condizioni mediche, tradurre discorsi in altre lingue quasi in tempo reale,
creare chatbot in grado di rispondere a domande arbitrarie utilizzando enormi database di

conoscenza e molto altro ancora. Chi l'avrebbe immaginato solo pochi anni fa artificialmente
auto intelligenti a guida autonoma sarebbero consentite sulle nostre strade o addirittura diventerebbero comuni? Ancora,

questa è ora un'area altamente competitiva. L'obiettivo finale di tutto questo apprendimento è artificiale
intelligenza generale: un'intelligenza artificiale in grado di eseguire compiti di intelligenza oltre agli esseri umani. Questo è un

pensiero spaventoso per molte persone.

Pietre miliari dell'intelligenza artificiale


Diverse pietre miliari dell'intelligenza artificiale, in particolare, hanno catturato l'attenzione della gente e
l'immaginazione, ha fatto sì che il grande pubblico iniziasse a pensare che l'IA fosse reale e ha fatto riflettere le aziende

sulla commercializzazione dell'IA:

In una partita del 1997 tra il sistema informatico DeepBlue di IBM e il Gran Maestro di scacchi

Gary Kasparov, DeepBlue è diventato il primo computer a battere gli scacchi in tutto il mondo
9
campione in condizioni di torneo. IBM ha caricato DeepBlue con centinaia di file
0
migliaia di partite di scacchi da gran maestro. DeepBlue era in grado di usare la forza bruta per
1
valuta fino a 200 milioni di mosse al secondo! Questi sono i big data al lavoro. IBM ha ricevuto il

Carnegie Mellon University Fredkin Prize, che nel 1980 ha offerto $ 100.000 ai creatori
2
del primo computer a battere un campione del mondo di scacchi.

9
ttps: //en.wikipedia.org/wiki/Deep_Blue_versus_Garry_Kasparov .

0
ttps: //en.wikipedia.org/wiki/Deep_Blue_ (chess_computer) .

1
ttps: //en.wikipedia.org/wiki/Deep_Blue_ (chess_computer) .

2
TTP: //articles.latimes.com/1997/jul/30/news/mn17696 .

Nel 2011, Watson di IBM ha battuto i due migliori Jeopardy umani! giocatori in un milione di dollari
incontro. Watson ha utilizzato contemporaneamente centinaia di tecniche di analisi delle lingue per localizzarlo

oC
76h

orrect risposte in 200 milioni di pagine di contenuto (inclusa tutta Wikipedia) che richiedono Pagina 60
3, 4
quattro terabyte di spazio di archiviazione.
Watson è stato addestrato con l'apprendimento automatico e
5
tecniche di rinforzo dell'apprendimento. il capitolo 13 discute IBM Watson e

il capitolo 14 discute l'apprendimento automatico.

3
ttps: //www.techrepublic.com/article/ibmwatsontheinside

storia di come è nato il pericolo che ha vinto il supercomputer e

hatitwantstodonext / .

4
ttps: //en.wikipedia.org/wiki/Watson_ (computer) .

5
ttps: //www.aaai.org/Magazine/Watson/watson.php , AI Magazine , autunno
2010.

6
Go, un gioco da tavolo creato in Cina migliaia di anni fa , è ampiamente considerato
170 7
uno dei giochi più complessi mai inventati con 10 possibili configurazioni del tabellone.
Per darti un'idea di quanto sia grande un numero, si ritiene che ci siano (solo)
78 87 8, 9
tra 10 e 10 atomi nell'universo conosciuto! Nel 2015, AlphaGo , creato da
Il gruppo DeepMind di Google ha utilizzato il deep learning con due reti neurali per battere il

Campione europeo di Go Fan Hui . Go è considerato un gioco molto più complesso di


scacchi. il capitolo 15 discute le reti neurali e l'apprendimento profondo.

6
TTP: //www.usgo.org/briefhistorygo .

7
ttps: //www.pbs.org/newshour/science/googleartificial

intelligencebeatschampionatworldsmostcomplicatedboard

ame .

8
ttps: //www.universetoday.com/36302/atomsintheuniverse/ .

9
ttps: //en.wikipedia.org/wiki/Observable_universe#Matter_content .

Più recentemente, Google ha generalizzato la sua AI AlphaGo per creare AlphaZero, un gameplay
AI che insegna a se stessa a giocare ad altri giochi . Nel dicembre 2017, AlphaZero ha imparato le regole

di e ha imparato a giocare a scacchi in meno di quattro ore utilizzando l'apprendimento per rinforzo. It
poi ha battuto il programma di scacchi campione del mondo, Stockfish 8, in una partita di 100 partite, vincendo

o disegnare ogni partita. Dopo essersi allenato in Go per sole otto ore, AlphaZero è stato in grado
0
per giocare a Go contro il suo predecessore AlphaGo, vincendo 60 su 100 giochi.

0
ttps: //www.theguardian.com/technology/2017/dec/07/alphazero

googledeepmindaibeatschampionprogramteachingitselftoplay

ourhours .

Un aneddoto personale
Quando uno degli autori, Harvey Deitel, era uno studente universitario al MIT a metà

c
C
87fh
gw

Anni 960, ha seguito un corso di intelligenza artificiale a livello di laurea con Marvin Minsky (a cui Pagina 61

questo libro è dedicato), uno dei fondatori dell'intelligenza artificiale (AI). Harvey:

Il professor Minsky ha richiesto un importante progetto a termine. Ci ha detto di pensare a quale intelligenza
è e per fare in modo che un computer faccia qualcosa di intelligente. Il nostro voto nel corso sarebbe

quasi esclusivamente dipendente dal progetto. Nessuna pressione!

Ho studiato i test del QI standardizzati che le scuole amministrano per aiutarli a valutarli

capacità di intelligenza degli studenti. Essendo un matematico in fondo, ho deciso di affrontare il


popolare problema IQtest di prevedere il numero successivo in una sequenza di numeri di

lunghezza e complessità arbitrarie. Ho usato Lisp interattivo in esecuzione su uno dei primi Digital
Equipment Corporation PDP1 ed è stato in grado di far funzionare il mio predittore di sequenza su alcuni

roba piuttosto complessa, gestire sfide ben oltre ciò che ricordavo di aver visto nei test del QI.
La capacità di Lisp di manipolare elenchi arbitrariamente lunghi in modo ricorsivo era esattamente ciò di cui avevo bisogno

soddisfare i requisiti del progetto. Python offre la ricorsione e l'elaborazione di elenchi generalizzati
( capitolo 5 ).

Ho provato il predittore di sequenza su molti dei miei compagni di classe del MIT. Avrebbero inventato il numero
sequenze e digitarle nel mio predittore. Il PDP1 "pensava" per un po ', spesso a

da molto tempo e quasi sempre ha trovato la risposta giusta.

Poi ho avuto un intoppo. Uno dei miei compagni di classe ha digitato la sequenza 14, 23, 34 e 42. My

predittore è andato a lavorare su di esso, e il PDP1 ha soffocato per molto tempo, non riuscendo a prevedere
il numero successivo. Neanche io sono riuscito a capirlo. Il mio compagno di classe mi ha detto di pensarci durante la notte,
e avrebbe rivelato la risposta il giorno successivo, sostenendo che si trattava di una semplice sequenza. I miei sforzi
furono inutili.

Il giorno dopo mi ha detto che il numero successivo era 57, ma non ho capito perché. Così lui

mi ha detto di pensarci di nuovo dall'oggi al domani, e il giorno dopo ha detto il numero successivo
era 125. Questo non ha aiutato un po ': ero perplesso. Ha detto che la sequenza erano i numeri
delle due vie trasversali di Manhattan. Ho gridato, "fallo", ma ha detto che ha incontrato il mio

criterio di previsione del numero successivo in una sequenza numerica. La mia visione del mondo era
matematica: la sua era più ampia.

Negli anni ho provato quella sequenza su amici, parenti e colleghi professionisti. UN

pochi che hanno trascorso del tempo a Manhattan lo hanno capito bene. Il mio predittore di sequenza aveva bisogno di molto di più
della semplice conoscenza matematica per gestire problemi come questo, richiedendo (possibilmente vasta)

conoscenza del mondo.

Watson e Big Data aprono nuove possibilità

Quando Paul e io abbiamo iniziato a lavorare a questo libro di Python, ne siamo stati immediatamente attratti
Watson di IBM utilizza big data e tecniche di intelligenza artificiale come il linguaggio naturale

elaborazione (PNL) e apprendimento automatico per battere due dei migliori rischi umani al mondo!
Giocatori. Ci siamo resi conto che Watson potrebbe probabilmente gestire problemi come la sequenza

predittore perché era caricato con le mappe stradali del mondo e molto altro ancora. Quello

1C

stimola la nostra voglia di scavare a fondo sui big data e sull'intelligenza artificiale di oggi Pagina 62

tecnologie e ha contribuito a dare forma hapters 11 - 6 di questo libro.

È interessante notare che tutti i casi di studio sull'implementazione della fascicolazione dei dati hapters
in 11 - 6 neanche
sono radicati nelle tecnologie di intelligenza artificiale o discutono di hardware e software per big data

infrastruttura che consente a informatici e scienziati di dati di implementare leadingedge


Soluzioni basate su AI in modo efficace.

AI: un campo con problemi ma senza soluzioni


Per molti decenni, l'IA è stata vista come un campo con problemi ma senza soluzioni. Quello è

perché una volta risolto un problema particolare, la gente dice: “Beh, questa non è intelligenza, è solo
un programma per computer che dice al computer esattamente cosa fare. " Tuttavia, con machine

apprendimentocapitolo
( 14 ) e deep learning ( capitolo 15 ) non stiamo preprogrammando soluzioni
a problemi specifici . Invece, stiamo permettendo ai nostri computer di risolvere i problemi imparando da
dati e, in genere, molti di essi.

Molti dei problemi più interessanti e stimolanti vengono affrontati in profondità

apprendimento. Solo Google ha migliaia di progetti di deeplearning in corso e questo numero lo è


1, 2
in rapida crescita. Mentre lavori in questo libro, ti presenteremo molti aspetti

la pratica dell'intelligenza artificiale, dei big data e delle tecnologie cloud.

1
ttp: //theweek.com/speedreads/654463/googlemorethan1000

rtificialintelligenceprojectsworks .

2
ttps: //www.zdnet.com/article/googlesaysexponentialgrowthofai

schangingnatureofcompute / .

1.10 WRAP-UP
In questo capitolo abbiamo introdotto la terminologia e i concetti che gettano le basi per
Programmazione Python in cui imparerai hapters 2 - 0 e il bigdata, intelligenza artificiale

e casi di studio basati su cloud in cui presentiamo hapters 11 - 6.

Abbiamo esaminato i concetti di programmazione orientata agli oggetti e discusso perché Python è diventato

così popolare. Abbiamo introdotto la Python Standard Library e varie librerie di datascience
che ti aiutano a evitare di "reinventare la ruota". Nei capitoli successivi userete queste librerie

per creare oggetti software con cui interagirai per eseguire compiti significativi con modesto
numero di istruzioni.

Hai lavorato su tre testdrive che mostrano come eseguire codice Python con IPython

interprete e quaderni Jupyter. Abbiamo introdotto il cloud e l'Internet of Things


(IoT), ponendo le basi per le applicazioni contemporanee in cui svilupperai hapters

1- 6.

Abbiamo discusso di quanto siano grandi i "big data" e di quanto velocemente stanno diventando ancora più grandi, e

w
1C
8io
hun'

ha risentito un caso di studio bigdata sull'app di navigazione mobile Waze, che utilizza molti file Pagina 63

tecnologie per fornire indicazioni stradali dinamiche che ti portino a destinazione il più rapidamente possibile
e nel modo più sicuro possibile. Abbiamo menzionato dove in questo libro ne userete molti

tecnologie. Il capitolo si è chiuso con la nostra prima sezione Intro to Data Science in cui abbiamo
ha discusso un'intersezione chiave tra informatica e scienza dei dati: artificiale

intelligenza.

https://avxhm.se/blogs/hill0
p
Pagina 64

Playlist

2. Introduzione alla programmazione Python


storia

Obiettivi
opiche

In questo capitolo potrai:


guadagnando Pat

Continua a utilizzare la modalità interattiva IPython per inserire frammenti di codice e vedere i risultati
ffers & Dea
subito.

ighlights
Scrivi semplici istruzioni e script Python.

ettingsCrea variabili per memorizzare i dati per un uso successivo.


Acquisisci
Supporto familiarità con i tipi di dati incorporati.

Disconnessione
Usa operatori aritmetici e operatori di confronto e comprendi i loro
precedenza.

Usa stringhe singole, doppie e triple.

Usa la funzione di stampa incorporata per visualizzare il testo.

Utilizzare l'input della funzione incorporata per richiedere all'utente di immettere i dati sulla tastiera e ottenere
quei dati da utilizzare nel programma.

Converti il ​testo in valori interi con la funzione incorporata int.

Usa gli operatori di confronto e l'istruzione if per decidere se eseguire un file


dichiarazione o gruppo di dichiarazioni.

Informazioni sugli oggetti e sulla digitazione dinamica di Python.

Usa il tipo di funzione incorporato per ottenere il tipo di un oggetto

Contorno

1
Pagina 65
.1 Introduzione

.2 Variabili e dichiarazioni di assegnazione

.3 Aritmetica

.4 Stampa delle funzioni e un'introduzione alle stringhe con virgolette singole e doppie

.5 Stringhe con tripla citazione

.6 Ottenere input dall'utente

.7 Processo decisionale: istruzione if e operatori di confronto

.8 Oggetti e digitazione dinamica

.9 Introduzione alla scienza dei dati: statistiche descrittive di base

.10 WrapUp

2.1 INTRODUZIONE
In questo capitolo, introduciamo la programmazione Python e presentiamo esempi illustrativi
caratteristiche linguistiche chiave. Si presume che tu abbia letto IPython TestDrive in capitolo 1 ,
che ha introdotto l'interprete IPython e lo ha utilizzato per valutare semplici operazioni aritmetiche
espressioni.

2.2 VARIABILI E DICHIARAZIONI DI ASSEGNAZIONE


Hai usato la modalità interattiva di IPython come calcolatrice con espressioni come

In [1]: 45 + 72
Uscita [1]: 117

Creiamo una variabile chiamata x che memorizza il numero intero 7:

In [2]: x = 7

Lo snippet [2] è una dichiarazione . Ogni istruzione specifica un'attività da eseguire. Il precedente
L'istruzione crea x e utilizza il simbolo di assegnazione (=) per dare a x un valore. Maggior parte

2C
Pagina 66
le istruzioni si fermano alla fine della riga, sebbene sia possibile che le istruzioni si estendano di più
più di una riga. La seguente istruzione crea la variabile y e le assegna il valore

3:

In [3]: y = 3

È ora possibile utilizzare i valori di x e y nelle espressioni:

In [4]: ​x + y
Uscita [4]: ​10

Calcoli nelle dichiarazioni di assegnazione

La seguente istruzione aggiunge i valori delle variabili x e y e assegna il risultato a


la variabile totale, che poi visualizziamo:

In [5]: totale = x + y

In [6]: totale
Uscita [6]: 10

Il simbolo = non è un operatore. Il lato destro del simbolo = viene sempre eseguito per primo,

quindi il risultato viene assegnato alla variabile sul lato sinistro del simbolo.

Stile Python
1
La Guida allo stile per il codice Python ti aiuta a scrivere codice conforme a Python
convenzioni di codifica. La guida allo stile consiglia di inserire uno spazio su ciascun lato di
il simbolo di assegnazione = e gli operatori binari come + per rendere i programmi più leggibili.

1
ttps: //www.python.org/dev/peps/pep0008/ .

Nomi variabili

Un nome di variabile, come x, è un identificatore . Ogni identificatore può essere composto da lettere,
cifre e trattini bassi (_) ma non possono iniziare con una cifra. Python fa distinzione tra maiuscole e minuscole , quindi

number e Number sono identificatori diversi perché uno inizia con una lettera minuscola
e l'altro inizia con una lettera maiuscola.

Tipi

h
Pagina 67
Ogni valore in Python ha un tipo che indica il tipo di dati rappresentato dal valore.
Puoi visualizzare il tipo di un valore con la funzione di tipo incorporata di Python , come in:
In [7]: digitare (x)
Out [7]: int

In [8]: digitare ( 10.5 )


Out [8]: float

La variabile x contiene il valore intero 7 (dallo snippet [2]), quindi Python mostra int
(abbreviazione di intero). Il valore 10.5 è un numero in virgola mobile, quindi viene visualizzato Python

galleggiante.

2.3 ARITMETICA
La tabella seguente riassume gli operatori aritmetici , che ne includono alcuni
simboli non usati in algebra.

Pitone Aritmetica Algebrico


Pitone
espressione
operazione operatore espressione

Aggiunta + f+7 f+7

Sottrazione - p-c pc

Moltiplicazione * b · m b*m

Esponenziazione ** X x ** y

Vera divisione / oo x/y

E
Pagina 68

o o

Divisione del piano // x // y

Resto
% r mod s r% s
(modulo)

Moltiplicazione (*)

Python utilizza l' operatore di moltiplicazione asterisco (*) :


In [1]: 7 * 4
Uscita [1]: 28

Esponenziazione (**)

L' operatore di esponenziazione (**) eleva un valore alla potenza di un altro:

In [2]: 2 ** 10
Uscita [2]: 1024

Per calcolare la radice quadrata, puoi usare l'esponente 1/2 (ovvero 0,5):

In [3]: 9 ** ( 1 / 2 )
Uscita [3]: 3.0

True Division (/) vs Floor Division (//)

La vera divisione (/) divide un numeratore per un denominatore e restituisce un virgola mobile
numero con punto decimale, come in:

In [4]: 7 / 4
Uscita [4]: ​1,75

Pagina 69

La divisione del piano (//) divide un numeratore per un denominatore, ottenendo il più alto
numero intero non maggiore del risultato. Python tronca (scarta) il frazionario
parte:

In [5]: 7 // 4
Fuori [5]: 1

In [6]: 3 // 5
Uscita [6]: 0

In [7]: 14 // 7
Fuori [7]: 2

Nella vera divisione, 13 diviso 4 dà 3.25:

In [8]: 13 / 4
Uscita [8]: 3.25

La divisione del piano fornisce il numero intero più vicino che non è maggiore di 3,25, ovvero 4:

In [9]: 13 // 4
Fuori [9]: 4

Eccezioni e tracce

La divisione per zero con / o // non è consentita e genera un'eccezione: un segno che a
si è verificato un problema:

lecca qui per visualizzare l'immagine del codice

In [10]: 123 / 0
ZeroDivisionError Traceback (la chiamata più recente per ultima
ipythoninput10cd759d3fcf39> in <module> ()
> 1 123 / 0

ZeroDivisionError : divisione per zero

Python segnala un'eccezione con un traceback . Questo traceback indica che un file
si è verificata un'eccezione di tipo ZeroDivisionError: la maggior parte dei nomi di eccezioni termina con

Errore. In modalità interattiva, viene specificato il numero di frammento che ha causato l'eccezione

C
<

Pagina 70
dal 10 in linea

<ipythoninput10cd759d3fcf39> in <module> ()

La riga che inizia con> mostra il codice che ha causato l'eccezione. Qualche volta
gli snippet hanno più di una riga di codice: l'1 a destra di> lo indica
la riga 1 all'interno dello snippet ha causato l'eccezione. L'ultima riga mostra l'eccezione che
, seguito da due punti (:) e un messaggio di errore con ulteriori informazioni su
l'eccezione:

ZeroDivisionError: divisione per zero

Il capitolo "File ed eccezioni" discute le eccezioni in dettaglio.

Si verifica un'eccezione anche se si tenta di utilizzare una variabile che non è stata ancora creata. Il
Il frammento di codice seguente tenta di aggiungere 7 alla variabile non definita z, risultando in un NameError:

lecca qui per visualizzare l'immagine del codice

In [11]: z + 7

NameError Traceback (la chiamata più recente per ultima


ipythoninput11f2cdbf4fe75d> in <module> ()
>1z+ 7

NameError : il nome "z" non è definito

Operatore resto

L' operatore resto di Python (%) restituisce il resto dopo l'operando di sinistra è
diviso per l'operando di destra:

In [12]: 17 % 5
Fuori [12]: 2

In questo caso, 17 diviso 5 produce un quoziente di 3 e un resto di 2. Questo operatore


è più comunemente usato con numeri interi, ma può anche essere usato con altri tipi numerici:

In [13]: 7,5 % 3,5


Uscita [13]: 0,5

C
<

Pagina 71

Forma lineare
Notazioni algebriche come

generalmente non sono accettabili per compilatori o interpreti. Per questo motivo algebrico
le espressioni devono essere digitate in forma lineare utilizzando gli operatori di Python. Il
l'espressione sopra deve essere scritta come a / b (o a // b per la divisione del piano) in modo che all
operatori e operandi vengono visualizzati su una linea retta orizzontale.

Raggruppamento di espressioni con parentesi


Le parentesi raggruppano le espressioni Python, come fanno nelle espressioni algebriche. Per
esempio, il codice seguente moltiplica 10 volte la quantità 5 + 3:

In [14]: 10 * ( 5 + 3 )
Uscita [14]: 80

Senza queste parentesi, il risultato è diverso :

In [15]: 10 * 5 + 3
Out [15]: 53

Le parentesi sono ridondanti (non necessarie) se rimuovendole si ottiene lo stesso risultato


risultato.

Regole di precedenza degli operatori

Python applica gli operatori nelle espressioni aritmetiche secondo le seguenti regole
di precedenza degli operatori . Questi sono generalmente gli stessi di quelli in algebra:

1. Le espressioni tra parentesi vengono valutate per prime, quindi le parentesi possono forzare l'ordine di
valutazione che si verifichi in qualsiasi sequenza si desideri. Le parentesi hanno il livello più alto di
precedenza. Nelle espressioni con parentesi nidificate , come (a / (b c)),
l'espressione tra le parentesi più interne (cioè b c) viene valutata per prima.

2. Le operazioni di esponenziazione valutano successivamente. Se un'espressione contiene diversi file


operazioni di esponenziazione, Python le applica da destra a sinistra.

3. Le operazioni di moltiplicazione, divisione e modulo valutano successivamente. Se un'espressione

Pagina 72
contiene diverse moltiplicazioni, truedivision, floordivision e moduli
operazioni, Python le applica da sinistra a destra. Moltiplicazione, divisione e
modulo sono "sullo stesso livello di precedenza".

4. Le operazioni di addizione e sottrazione valutano per ultime. Se un'espressione contiene diversi file
operazioni di addizione e sottrazione, Python le applica da sinistra a destra.
Anche l'addizione e la sottrazione hanno lo stesso livello di precedenza.

Per l'elenco completo degli operatori e la loro precedenza (nell'ordine dal più basso al più alto), vedere

ttps: //docs.python.org/3/reference/expressions.html#operatorprecedence

Raggruppamento di operatori

Quando diciamo che Python applica determinati operatori da sinistra a destra, ci riferiamo a
il raggruppamento degli operatori . Ad esempio, nell'espressione
a+b+c

gli operatori di addizione (+) si raggruppano da sinistra a destra come se tra parentesi l'espressione fosse stata inserita
come (a + b) + c. Tutti gli operatori Python dello stesso gruppo di precedenza sono rimasti a destra
ad eccezione dell'operatore di esponenziazione (**), che raggruppa righttoleft.

Parentesi ridondanti

È possibile utilizzare parentesi ridondanti per raggruppare sottoespressioni per creare l'espressione
più chiaro. Ad esempio, il polinomio di secondo grado

y = a * x ** 2 + b * x + c

può essere tra parentesi, per chiarezza, come

lecca qui per visualizzare l'immagine del codice

y = (a * (x ** 2)) + (b * x) + c

Rompere un'espressione complessa in una sequenza di affermazioni con più brevi, più semplici
le espressioni possono anche promuovere la chiarezza.

Tipi di operandi

h
C
Pagina 73
Ogni operatore aritmetico può essere utilizzato con numeri interi e numeri in virgola mobile. Se entrambi
gli operandi sono numeri interi, il risultato è un numero intero, ad eccezione dell'operatore truedivision (/),
che restituisce sempre un numero in virgola mobile. Se entrambi gli operandi sono in virgola mobile
numeri, il risultato è un numero in virgola mobile. Espressioni contenenti un numero intero e un file
i numeri in virgola mobile sono espressioni di tipo misto, che producono sempre il virgola mobile
risultati puntuali.

2.4 FUNCTION PRINT E INTRODUZIONE A SINGLE- AND


CORDE A DOPPIA CITAZIONE
La funzione di stampa incorporata mostra i suoi argomenti come una riga di testo:

lecca qui per visualizzare l'immagine del codice

In [1]: print ( 'Benvenuto in Python!' )


Benvenuto in Python!

In questo caso, l'argomento "Benvenuto in Python!" è una stringa, una sequenza di


caratteri racchiusi tra virgolette singole ('). A differenza di quando valuti le espressioni in
modalità interattiva, il testo visualizzato qui da stampare non è preceduto da Out [1]. Anche,

print non mostra le virgolette di una stringa, anche se presto mostreremo come visualizzare le virgolette
in stringhe.

Puoi anche racchiudere una stringa tra virgolette doppie ("), come in:

lecca qui per visualizzare l'immagine del codice

In [2]: print ( "Benvenuto in Python!" )


Benvenuto in Python!

I programmatori Python generalmente preferiscono virgolette singole. Quando la stampa completa il suo compito, esso
posiziona il cursore del video all'inizio della riga successiva.

Stampa di un elenco di elementi separati da virgole

La funzione di stampa può ricevere un elenco di argomenti separati da virgole, come in:

lecca qui per visualizzare l'immagine del codice

In [3]: print ( 'Benvenuto' , 'a' , 'Python!' )


Benvenuto in Python!

C
Pagina 74

t mostra ogni argomento separato dal successivo da uno spazio, producendo lo stesso
output come nei due frammenti precedenti. Qui abbiamo mostrato un elenco separato da virgole di
stringhe, ma i valori possono essere di qualsiasi tipo. Mostreremo nel prossimo capitolo come prevenire
spaziatura automatica tra i valori o utilizzare un separatore diverso dallo spazio.

Stampa di molte righe di testo con una sola istruzione

Quando una barra rovesciata (\) appare in una stringa, è nota come carattere di escape . Il
la barra rovesciata e il carattere immediatamente successivo formano una sequenza di escape . Per
esempio, \ n rappresenta la sequenza di escape del carattere di nuova riga , che dice a print to
sposta il cursore di output sulla riga successiva. Il frammento di codice seguente utilizza tre nuove righe
caratteri per creare diverse righe di output: i

lecca qui per visualizzare l'immagine del codice

In [4]: ​print ( 'Benvenuto \ nto \ n \ nPython!' )


benvenuto
per

Pitone!

Altre sequenze di escape

La tabella seguente mostra alcune sequenze di escape comuni.

Fuga
Descrizione
sequenza

Inserisce un carattere di nuova riga in una stringa. Quando la stringa è


\n visualizzato, per ogni nuova riga, spostare il cursore del video su
all'inizio della riga successiva.

Inserisci una tabulazione orizzontale. Quando viene visualizzata la stringa, per ciascuna scheda,
\t
spostare il cursore del video al successivo punto di tabulazione.

\\ Inserisce un carattere barra rovesciata in una stringa.

io
C
Pagina 75
\" Inserisce una virgoletta doppia in una stringa.

\' Inserisci una virgoletta singola in una stringa.

Ignorare un'interruzione di riga in una stringa lunga

Puoi anche dividere una stringa lunga (o un'istruzione lunga) su più righe usando il \
carattere di continuazione come ultimo carattere su una riga per ignorare l'interruzione di riga:

lecca qui per visualizzare l'immagine del codice

In [5]: print ( 'questa è una stringa più lunga, quindi \


...: dividerlo su due righe ' )
questa è una stringa più lunga, quindi la dividiamo su due righe

L'interprete riassembla le parti della stringa in una singola stringa senza interruzioni di riga.
Sebbene il carattere barra rovesciata nello snippet precedente sia all'interno di una stringa, non è il
carattere di escape perché un altro personaggio non lo segue.

Stampa del valore di un'espressione

I calcoli possono essere eseguiti in istruzioni di stampa:

lecca qui per visualizzare l'immagine del codice

In [6]: print ( 'Sum is' , 7 + 3 )


La somma è 10

2.5 STRINGHE TRIPLA


In precedenza, abbiamo introdotto stringhe delimitate da una coppia di virgolette singole (') o da una coppia di doppie
virgolette ("). Le stringhe tra virgolette iniziano e finiscono con tre virgolette doppie (" "") o

tre virgolette singole ('' '). La Guida allo stile per il codice Python consiglia tre doppie
virgolette ("" "). Utilizzale per creare:

C
Pagina 76
stringhe multilinea,

stringhe contenenti virgolette singole o doppie e

docstrings , che sono il modo consigliato per documentare gli scopi di alcuni file
componenti del programma.

Comprese le virgolette nelle stringhe

In una stringa delimitata da virgolette singole, puoi includere caratteri virgolette doppie:

lecca qui per visualizzare l'immagine del codice

In [1]: print ( "Visualizza" ciao "tra virgolette" )


Mostra "ciao" tra virgolette

ma non virgolette singole:


lecca qui per visualizzare l'immagine del codice

In [2]: print ( "Mostra" ciao "tra virgolette" )


File "<ipythoninput219bf596ccf72>", riga 1
print ('Mostra' ciao 'tra virgolette')
^
SyntaxError : sintassi non valida

a meno che non utilizzi la sequenza di escape \ ':

lecca qui per visualizzare l'immagine del codice

In [3]: print ( "Visualizza \" ciao \ "tra virgolette" )


Mostra "ciao" tra virgolette

Lo snippet [2] mostrava un errore di sintassi dovuto a virgolette singole all'interno di una stringa con virgolette singole.
IPython visualizza le informazioni sulla riga di codice che ha causato l'errore di sintassi e
indica l'errore con un simbolo ^. Visualizza anche il messaggio SyntaxError:

sintassi non valida.

Una stringa delimitata da virgolette doppie può includere virgolette singole:

lecca qui per visualizzare l'immagine del codice

In [4]: ​print ( "Visualizza il nome O'Brien" )


Pagina 77
Mostra il nome O'Brien

ma non virgolette doppie, a meno che non utilizzi la sequenza di escape \ ":

lecca qui per visualizzare l'immagine del codice

In [5]: print ( "Visualizza \" ciao \ "tra virgolette" )


Mostra "ciao" tra virgolette

Per evitare di utilizzare \ 'e \ "all'interno di stringhe, puoi racchiudere tali stringhe tra virgolette triple:

lecca qui per visualizzare l'immagine del codice

In [6]: print ( "" "Mostra" ciao "e" ciao "tra virgolette" "" )
Mostra "ciao" e "ciao" tra virgolette

Stringhe multilinea

Il frammento di codice seguente assegna una stringa a più righe con virgolette triple
triple_quoted_string:

lecca qui per visualizzare l'immagine del codice

In [7]: triple_quoted_string = "" "Questa è una tripla citazione


...: stringa che si estende su due righe "" "

IPython sa che la stringa è incompleta perché non abbiamo digitato la chiusura "" "
prima di premere Invio . Quindi, IPython mostra un prompt di continuazione ...: al quale
è possibile inserire la riga successiva della stringa multilinea. Questo continua fino a quando non inserisci il finale
"" "e premere Invio . Di seguito viene visualizzato triple_quoted_string:
lecca qui per visualizzare l'immagine del codice

In [8]: print (triple_quoted_string)


Questa è una tripla citazione
stringa che si estende su due righe

Python memorizza stringhe multilinea con caratteri di nuova riga incorporati. Quando valutiamo
triple_quoted_string invece di stamparlo, IPython lo visualizza tra virgolette singole

C
Pagina 78
con un carattere \ n dove hai premuto Invio nello snippet [7]. Le virgolette IPython
i display indicano che triple_quoted_string è una stringa, non fanno parte del
contenuto della stringa:

lecca qui per visualizzare l'immagine del codice

In [9]: triple_quoted_string
Out [9]: "Questa è una stringa con virgolette triple che si estende su due righe"

2.6 OTTENERE INGRESSO DALL'UTENTE


La funzione di input incorporata richiede e ottiene l'input dell'utente:

lecca qui per visualizzare l'immagine del codice

In [1]: name = input ( "Come ti chiami?" )


Come ti chiami? Paolo

In [2]: nome
Uscita [2]: "Paul"

In [3]: print (nome)


Paolo

Lo snippet viene eseguito come segue:

Innanzitutto, l'input mostra il suo argomento stringa, un prompt, per dire all'utente cosa digitare
e attende che l'utente risponda. Abbiamo digitato Paul e premuto Invio . Usiamo il grassetto
text per distinguere l'input dell'utente dal testo del prompt visualizzato dall'input.

L'input della funzione restituisce quindi quei caratteri come una stringa che il programma può utilizzare.
Qui abbiamo assegnato quella stringa al nome della variabile.

Lo snippet [2] mostra il valore del nome. La valutazione del nome mostra il suo valore tra virgolette singole come

"Paul" perché è una stringa. Il nome di stampa (nello snippet [3]) mostra la stringa senza
le virgolette. Se inserisci virgolette, fanno parte della stringa, come in:

lecca qui per visualizzare l'immagine del codice

In [4]: ​name = input ( "Come ti chiami?" )


Come ti chiami? 'Paolo'

C
Pagina 79
In [5]: nome
Uscita [5]: "'Paul'"
In [6]: print (nome)
'Paolo'

Input della funzione Restituisce sempre una stringa

Considera i seguenti frammenti che tentano di leggere due numeri e aggiungerli:

lecca qui per visualizzare l'immagine del codice

In [7]: value1 = input ( "Enter first number:" )


Immettere il primo numero: 7

In [8]: value2 = input ( "Enter second number:" )


Immettere il secondo numero: 3

In [9]: valore1 + valore2


Uscita [9]: "73"

Invece di aggiungere gli interi 7 e 3 per produrre 10, Python "aggiunge" i valori di stringa

"7" e "3", producendo la stringa "73". Questo è noto come concatenazione di stringhe . It
crea una nuova stringa contenente il valore dell'operando sinistro seguito da quello dell'operando destro
valore.

Ottenere un numero intero dall'utente

Se hai bisogno di un numero intero, converti la stringa in un numero intero utilizzando la funzione incorporata int :

lecca qui per visualizzare l'immagine del codice

In [10]: value = input ( "Enter an integer:" )


Immettere un numero intero: 7

In [11]: value = int (value)

In [12]: valore
Uscita [12]: 7

Avremmo potuto combinare il codice negli snippet [10] e [11]:

lecca qui per visualizzare l'immagine del codice

C
Pagina 80
In [13]: another_value = int (input ( 'Enter another integer:' ))
Immettere un altro numero intero: 13

In [14]: another_value
Uscita [14]: 13

Il valore delle variabili e un altro_valore ora contengono numeri interi. Aggiungendoli si ottiene un file
risultato intero (invece di concatenarli):

In [15]: valore + altro_valore


Uscita [15]: 20

Se la stringa passata a int non può essere convertita in un numero intero, si verifica un'eccezione ValueError:

lecca qui per visualizzare l'immagine del codice

In [16]: bad_value = int (input ( 'Enter another integer:' ))


Inserisci un altro numero intero: ciao

ValueError Traceback (la chiamata più recente last


ipythoninput16cd36e6cf8911> in <module> ()
> 1 bad_value = int (input ( 'Enter another integer:' ))

ValueError : valore letterale non valido per int () con base 10: 'hello'

La funzione int può anche convertire un valore a virgola mobile in un intero:

In [17]: int ( 10.5 )


Fuori [17]: 10

Per convertire le stringhe in numeri in virgola mobile, usa la funzione float incorporata .

2.7 PROCESSO DECISIONALE: LA DICHIARAZIONE IF E


OPERATORI A CONFRONTO
Una condizione è un'espressione booleana con il valore True o False . Il seguente
determina se 7 è maggiore di 4 e se 7 è minore di 4:

In [1]: 7 > 4
Out [1]: vero

C
<

In [2]: 7 < 4 Pagina 81


Fuori [2]: Falso

Vero e Falso sono parole chiave Python. L'uso di una parola chiave come identificatore causa un
Errore di sintassi. Vero e Falso sono ciascuno in maiuscolo.

Creerai spesso condizioni utilizzando gli operatori di confronto di seguito


tavolo:

Algebrico Pitone Campione


Senso
operatore operatore condizione

> > x> y x è maggiore di y

< < x <y x è minore di y

x è maggiore di o
≥ >= x> = y
uguale a y

x è minore o uguale
≤ <= x <= y
ay

= == x == y x è uguale a y
≠ != x! = y x non è uguale a y

Gli operatori>, <,> = e <= hanno tutti la stessa precedenza. Operatori == e! = Entrambi
hanno la stessa precedenza, che è inferiore a quella di>, <,> = e <=. Un errore di sintassi
si verifica quando uno degli operatori ==,! =,> = e <= contiene spazi tra la sua coppia di
simboli:

Pagina 82
lecca qui per visualizzare l'immagine del codice

In [3]: 7 > = 4
File "<ipythoninput35c6e2897f3b3>", riga 1
7> = 4
^
SyntaxError : sintassi non valida

Un altro errore di sintassi si verifica se si invertono i simboli negli operatori! = , > = E <=

(scrivendoli come = !, => e = <).

Prendere decisioni con l'istruzione if: Introduzione agli script

Ora presentiamo una semplice versione del se dichiarazione , che utilizza una condizione di
decidere se eseguire un'istruzione (o un gruppo di istruzioni). Qui ne leggeremo due
numeri interi dell'utente e confrontarli utilizzando sei istruzioni if ​consecutive, una per
ogni operatore di confronto. Se la condizione in una determinata istruzione if è True, il
viene eseguita l'istruzione print corrispondente; in caso contrario, viene ignorata.

La modalità interattiva IPython è utile per eseguire brevi frammenti di codice e vedere
risultati immediati. Quando hai molte istruzioni da eseguire come gruppo, in genere
scriverli come uno script memorizzato in un file con l'estensione .py (abbreviazione di Python), come
come fig02_01.py per lo script di questo esempio. Gli script sono anche chiamati programmi. Per
istruzioni su come individuare ed eseguire gli script in questo libro, vedere apo 1 ‘s IPython
Test di guida.

Ogni volta che esegui questo script, tre delle sei condizioni sono True. Per dimostrarlo, noi
eseguire lo script tre volte: una volta con il primo intero inferiore al secondo, una volta
con lo stesso valore per entrambi interi e una volta con il primo intero maggiore la
secondo. Le tre esecuzioni di esempio vengono visualizzate dopo lo script

Ogni volta che presentiamo uno script come quello qui sotto, lo introduciamo prima della figura, poi
spiegare il codice dello script dopo la figura. Mostriamo i numeri di riga per tua comodità—
questi non fanno parte di Python. Gli IDE ti consentono di scegliere se visualizzare la linea
numeri. Per eseguire questo esempio, passare alla cartella degli esempi ch02 di questo capitolo, quindi
accedere:

ipython fig02_01.py

oppure, se sei già in IPython, puoi utilizzare il comando:

C
Pagina 83
eseguire fig02_01.py
lecca qui per visualizzare l'immagine del codice

1 # fig02_01.py
2 "" "Confronto di numeri interi utilizzando istruzioni if ​e operatori di confronto." "
3
4 print ( 'Inserisci due numeri interi e te lo dirò' ,
5 "le relazioni che soddisfano." )
6
7 # legge il primo numero intero
8 number1 = int (input ( 'Enter first integer:' ))
9
10 # legge il secondo numero intero
11 number2 = int (input ( 'Enter second integer:' ))
12
13 se numero1 == numero2:
14 print (numero1, 'è uguale a' , numero2)
15
16 se numero1! = Numero2:
17 print (numero1, 'non è uguale a' , numero2)
18
19 se numero1 <numero2:
20 print (numero1, 'è minore di' , numero2)
21
22 se numero1> numero2:
23 print (numero1, 'è maggiore di' , numero2)
24
25 se numero1 <= numero2:
26 print (numero1, "è minore o uguale a" , numero2)
27
28 se numero1> = numero2:
29 print (numero1, "è maggiore o uguale a" , numero2)

lecca qui per visualizzare l'immagine del codice

Inserisci due numeri interi e ti dirò le relazioni che soddisfano.


Inserisci il primo numero intero: 37
Inserisci il secondo numero intero: 42
37 non è uguale a 42
37 è inferiore a 42
37 è minore o uguale a 42

lecca qui per visualizzare l'immagine del codice

C
Pagina 84
Inserisci due numeri interi e ti dirò le relazioni che soddisfano.
Immettere il primo numero intero: 7
Immettere il secondo numero intero: 7
7 è uguale a 7
7 è minore o uguale a 7
7 è maggiore o uguale a 7

lecca qui per visualizzare l'immagine del codice

Inserisci due numeri interi e ti dirò le relazioni che soddisfano.


Inserisci il primo numero intero: 54
Inserisci il secondo numero intero: 17
54 non è uguale a 17
54 è maggiore di 17
54 è maggiore o uguale a 17
Commenti

La riga 1 inizia con il carattere cancelletto ( # ), che indica che il resto della riga è un
commento :

# fig02_01.py

Per una facile consultazione, iniziamo ogni script con un commento che indica il file dello script
nome. Un commento può anche iniziare a destra del codice su una determinata riga e continuare
fino alla fine di quella riga.

Docstrings

La Guida allo stile per il codice Python afferma che ogni script dovrebbe iniziare con una docstring
che spiega lo scopo dello script, come quello nella riga 2:

"" "Confronto di numeri interi utilizzando istruzioni if ​e operatori di confronto." ""

Per script più complessi, la docstring si estende spesso su molte righe. Nei capitoli successivi, lo farai
usa docstrings per descrivere i componenti dello script che definisci, come nuove funzioni e
nuovi tipi chiamati classi. Discuteremo anche come accedere alle docstring con IPython
meccanismo di aiuto.

B
C Linee dinamiche

Righe vuote Pagina 85

La riga 3 è una riga vuota. Si utilizzano righe vuote e caratteri spazio per semplificare il codice
leggere. Insieme, le righe vuote, i caratteri di spazio ei caratteri di tabulazione sono noti come bianchi
spazio . Python ignora la maggior parte degli spazi bianchi: vedrai che è richiesta una certa indentazione.

Suddivisione di una frase lunga su più righe

Righe 4–5

lecca qui per visualizzare l'immagine del codice

print ( 'Inserisci due numeri interi e te lo dirò' ,


"le relazioni che soddisfano." )

visualizzare le istruzioni per l'utente. Questi sono troppo lunghi per stare su una riga, quindi li abbiamo interrotti
in due stringhe. Ricorda che puoi visualizzare diversi valori passando per stampare un file
elenco separato da virgole: print separa ogni valore dal successivo con uno spazio.

In genere, scrivi le dichiarazioni su una riga. Puoi diffondere una lunga dichiarazione
diverse righe con il carattere \ continuation. Python ti consente anche di dividere a lungo
righe di codice tra parentesi senza utilizzare caratteri di continuazione (come nelle righe 4-5). Questo
è il modo preferito per interrompere lunghe righe di codice secondo la Guida allo stile per Python
Codice . Scegli sempre i punti di interruzione che abbiano senso, ad esempio dopo una virgola nel file
precedente chiamata a print o prima di un operatore in un'espressione lunga.

Lettura di valori interi dall'utente

Successivamente, le righe 8 e 11 utilizzano le funzioni incorporate input e int per richiedere e leggere
due valori interi dall'utente.

se Dichiarazioni
L'istruzione if nelle righe 13-14

lecca qui per visualizzare l'immagine del codice

se numero1 == numero2:
print (numero1, 'è uguale a' , numero2)

utilizza l'operatore di confronto == per determinare se i valori delle variabili

numero1 e numero2 sono uguali. In tal caso, la condizione è True e la riga 14 visualizza a

C
Pagina 86
ine di testo che indica che i valori sono uguali. Se una delle restanti dichiarazioni if ​'
le condizioni sono Vere (righe 16, 19, 22, 25 e 28), la stampa corrispondente visualizza a
riga di testo.

Ogni istruzione if è composta dalla parola chiave if, dalla condizione da testare e da due punti (:)
seguito da un corpo rientrato chiamato suite . Ogni suite deve contenere uno o più
dichiarazioni. Dimenticare i due punti (:) dopo la condizione è un errore di sintassi comune.

Rientro della suite

Python richiede di indentare le istruzioni nelle suite. La guida allo stile per Python
Il codice raccomanda quattro rientri di spazio: usiamo questa convenzione in tutto il libro.
Vedrai nel prossimo capitolo che un rientro errato può causare errori.

Confondere == e =

Utilizzando il simbolo di assegnazione (=) invece dell'operatore di uguaglianza (==) in un if

la condizione dell'istruzione è un errore di sintassi comune. Per evitare questo problema, leggi == come "è uguale
a "e = come" è assegnato ". Vedrai nel prossimo capitolo che l'uso di == al posto di = in un file
la dichiarazione di incarico può portare a problemi sottili.

Concatenamento di confronti

È possibile concatenare confronti per verificare se un valore è in un intervallo. Il seguente


il confronto determina se x è compreso tra 1 e 5, inclusi:

In [1]: x = 3

In [2]: 1 <= x <= 5


Out [2]: vero

In [3]: x = 10

In [4]: 1 <= x <= 5


Fuori [4]: ​Falso

Precedenza degli operatori che abbiamo presentato finora

Di seguito viene mostrata la precedenza degli operatori introdotti in questo capitolo:

Tipo di raggruppamento operatori

l
Pagina 87
lasciato a
() parentesi
giusto
giusto per
** esponenziazione
sinistra

lasciato a moltiplicazione, divisione vera, divisione piano,


* / //%
giusto resto

lasciato a
+- addizione, sottrazione
giusto

> <= < lasciato a minore di, minore o uguale, maggiore di, maggiore

>= giusto di o uguale

lasciato a
==! = uguale, non uguale
giusto

La tabella elenca gli operatori dall'alto in basso in ordine decrescente di precedenza. quando
scrivendo espressioni contenenti più operatori, confermare che valutino nel file
ordine previsto facendo riferimento alla tabella delle priorità degli operatori all'indirizzo

ttps: //docs.python.org/3/reference/expressions.html#operatorprecedence

2.8 OGGETTI E DIGITAZIONE DINAMICA


Valori come 7 (un numero intero), 4.1 (un numero in virgola mobile) e "cane" sono tutti oggetti.
Ogni oggetto ha un tipo e un valore:

In [1]: tipo ( 7 )
Out [1]: int

In [2]: digitare ( 4.1 )

Out [2]: float Pagina 88

In [3]: tipo ( "cane" )


Uscita [3]: str

Il valore di un oggetto sono i dati memorizzati nell'oggetto. Gli snippet sopra mostrano oggetti di
tipi incorporati int (per interi), float (per numeri in virgola mobile) e str (per
stringhe).

Le variabili si riferiscono agli oggetti

Assegnare un oggetto a una variabile lega (associa) il nome di quella variabile all'oggetto.
Come hai visto, puoi quindi utilizzare la variabile nel codice per accedere al valore dell'oggetto:

In [4]: ​x = 7

In [5]: x + 10
Fuori [5]: 17
In [6]: x
Fuori [6]: 7

Dopo l'assegnazione dello snippet [4], la variabile x si riferisce all'oggetto intero che contiene

7. Come mostrato nello snippet [6], lo snippet [5] non cambia il valore di x. Puoi modificare x
come segue:

In [7]: x = x + 10

In [8]: x
Uscita [8]: 17

Digitazione dinamica

Python utilizza la digitazione dinamica: determina il tipo di oggetto a cui fa riferimento una variabile
durante l'esecuzione del codice. Possiamo dimostrarlo riassociando la variabile x a differente
oggetti e verificandone la tipologia:

In [9]: digitare (x)


Out [9]: int

In [10]: x = 4.1

In [11]: digitare (x)


Out [11]: float

Pagina 89
In [12]: x = "dog"

In [13]: digitare (x)


Uscita [13]: str

Raccolta dei rifiuti

Python crea oggetti in memoria e li rimuove dalla memoria se necessario. Dopo


snippet [10], la variabile x ora si riferisce a un oggetto float. L'oggetto intero da
lo snippet [7] non è più vincolato a una variabile. Come vedremo in un capitolo successivo, Python
rimuove automaticamente tali oggetti dalla memoria. Questo processo, chiamato spazzatura
raccolta: aiuta a garantire che la memoria sia disponibile per i nuovi oggetti creati.

2.9 INTRO ALLA DATA SCIENCE: DESCRITTIVO DI BASE


STATISTICHE
Nella scienza dei dati, utilizzerai spesso le statistiche per descrivere e riepilogare i tuoi dati. Qui,
iniziamo introducendo diverse di queste statistiche descrittive , tra cui:

minimo: il valore più piccolo in una raccolta di valori.

massimo: il valore più grande in una raccolta di valori.

intervallo: l'intervallo di valori dal minimo al massimo.

count: il numero di valori in una raccolta.

sum: il totale dei valori in una raccolta.

Vedremo come determinare il conteggio e la somma nel prossimo capitolo. Misure di


la dispersione (chiamata anche misura della variabilità ), come l' intervallo , aiuta a determinare
quanto sono distribuiti i valori. Altre misure di dispersione che presenteremo più avanti
i capitoli includono la varianza e la deviazione standard .

Determinazione del minimo di tre valori

Innanzitutto, mostriamo come determinare manualmente il minimo di tre valori. Il


il seguente script richiede e immette tre valori, utilizza le istruzioni if ​per determinare
il valore minimo, quindi lo visualizza.

lecca qui per visualizzare l'immagine del codice

C
Pagina 90
1 # fig02_02.py
2 "" "Trova il minimo di tre valori." ""
3
4 numero1 = int (input ( 'Inserisci il primo numero intero:' ))
5 numero2 = int (input ( 'Inserisci il secondo intero:' ))
6 number3 = int (input ( 'Enter third integer:' ))
7
8 minimo = numero1
9
10 se numero2 <minimo:
11 minimo = numero2
12
13 se numero3 <minimo:
14 minimo = numero 3
15
16 print ( "Il valore minimo è" , minimo)

lecca qui per visualizzare l'immagine del codice

Inserisci il primo numero intero: 12


Inserisci il secondo numero intero: 27
Immettere il terzo numero intero: 36
Il valore minimo è 12

lecca qui per visualizzare l'immagine del codice

Inserisci il primo numero intero: 27


Inserisci il secondo numero intero: 12
Immettere il terzo numero intero: 36
Il valore minimo è 12

lecca qui per visualizzare l'immagine del codice

Immettere il primo numero intero: 36


Inserisci il secondo numero intero: 27
Immettere il terzo numero intero: 12
Il valore minimo è 12

Dopo aver immesso i tre valori, elaboriamo un valore alla volta:

Innanzitutto, assumiamo che numero1 contenga il valore più piccolo, quindi la riga 8 lo assegna a
il minimo variabile. Naturalmente, è possibile che il numero2 o il numero3 contenga

C
Pagina 91
il valore più piccolo effettivo, quindi dobbiamo ancora confrontare ciascuno di questi con il minimo.
La prima istruzione if (righe 10-11) quindi verifica numero2 <minimo e if this
la condizione è True assegna il numero2 al minimo.

La seconda istruzione if (righe 13-14) verifica quindi number3 <minimum, e if this


condition è True assegna il numero3 al minimo.

Ora, il minimo contiene il valore più piccolo, quindi lo visualizziamo. Abbiamo eseguito lo script
tre volte per mostrare che trova sempre il valore più piccolo indipendentemente dal fatto che il
l'utente lo inserisce per primo, secondo o terzo.

Determinazione del minimo e del massimo con le funzioni integrate min e


max
Python ha molte funzioni incorporate per eseguire attività comuni. Funzioni incorporate
min e max calcolano rispettivamente il minimo e il massimo di una raccolta di
valori:

In [1]: min ( 36 , 27 , 12 )
Uscita [1]: 12

In [2]: max ( 36 , 27 , 12 )
Fuori [2]: 36

Le funzioni min e max possono ricevere un numero qualsiasi di argomenti.

Determinazione dell'intervallo di una raccolta di valori

L' intervallo di valori è semplicemente il valore minimo attraverso il valore massimo. In questo caso,
l'intervallo è compreso tra 12 e 36. Gran parte della scienza dei dati è dedicata alla conoscenza dei dati.
Le statistiche descrittive sono una parte cruciale di questo, ma devi anche capire come farlo
interpretare le statistiche. Ad esempio, se hai 100 numeri con un intervallo di 12
fino a 36, ​quei numeri potrebbero essere distribuiti uniformemente su quell'intervallo. Al contrario
estremo, potresti avere un raggruppamento con 99 valori di 12 e uno di 36 o uno di 12 e 99
valori di 36.

Programmazione in stile funzionale: riduzione

In questo libro, introduciamo vari tipi di programmazione in stile funzionale


capacità. Questi ti consentono di scrivere codice che può essere più conciso, più chiaro e più facile
per eseguire il debug -cioè, trovare e correggere gli errori. Le funzioni min e max sono esempi di

Pagina 92
concetto di programmazione in stile funzionale chiamato riduzione . Riducono una raccolta di
valori in un singolo valore. Altre riduzioni che vedrai includono la somma, la media, la varianza
e deviazione standard di una raccolta di valori. Vedrai anche come definire personalizzato
riduzioni.

Prossima introduzione alle sezioni sulla scienza dei dati

Nei prossimi due capitoli, continueremo la nostra discussione sulle statistiche descrittive di base
con misure di tendenza centrale , inclusi media , mediana e modo , e misure
di dispersione , compresa la varianza e la deviazione standard .

2.10 WRAP-UP
Questo capitolo ha continuato la nostra discussione sull'aritmetica. Hai utilizzato le variabili per memorizzare i valori
per un uso successivo. Abbiamo introdotto gli operatori aritmetici di Python e abbiamo dimostrato che è necessario
scrivi tutte le espressioni in forma lineare. Hai usato la funzione incorporata per stampare
visualizza dati. Abbiamo creato stringhe con virgolette singole, doppie e triple. Hai usato il triplo
stringhe tra virgolette per creare stringhe multilinea e per incorporare virgolette singole o doppie in
stringhe.

Hai utilizzato la funzione di input per richiedere e ottenere input dall'utente in

tastiera. Abbiamo usato le funzioni int e float per convertire le stringhe in valori numerici.
Abbiamo presentato gli operatori di confronto di Python. Quindi, li hai usati in uno script che leggeva
due numeri interi dall'utente e confrontato i loro valori utilizzando una serie di istruzioni if.

Abbiamo discusso della digitazione dinamica di Python e utilizzato il tipo di funzione incorporata per visualizzare
il tipo di un oggetto. Infine, abbiamo introdotto le statistiche descrittive di base minime e
massimo e li ha utilizzati per calcolare l'intervallo di una raccolta di valori. Nel prossimo
capitolo, presentiamo le istruzioni di controllo di Python.

un'
Pagina 93

elenchi

3. Dichiarazioni di controllo
storia

Obiettivi
foto

In questo capitolo potrai:


arning Pat

Prendi decisioni con if, if else e if elif else.


ffers & Dea

Esegui ripetutamente le istruzioni con while e for.


ighlights

Riduci le espressioni di assegnazione con assegnazioni aumentate.


ttings

Usa l'istruzione for e la funzione di intervallo incorporata per ripetere le azioni per un file
Supporto
sequenza di valori.

Disconnessione
Esegui l'iterazione controllata dalla sentinella con while.

Crea condizioni composte con gli operatori booleani and, or and not.

Smetti di girare con una pausa.

Forza l'iterazione successiva di un ciclo con continue.

Utilizza le funzionalità di programmazione in stile funzionale per scrivere script più concisi,
più chiaro, più facile da eseguire il debug e più facile da parallelizzare.
Contorno

3.3
Controllo
3.2
introduzione
3.1
ent
Dichiarazioni
e3.4
elif
S
Se
altroifStatem

Pagina 94
.5 Istruzione while

.6 per Statement

.6.1 Iterabili, elenchi e iteratori

.6.2 Funzione di portata incorporata

.7 Incarichi aumentati

.8 Iterazione controllata dalla sequenza; stringhe formattate

.9 Iterazione controllata da Sentinel

.10 Gamma di funzioni integrate: uno sguardo più profondo

.11 Utilizzo del tipo decimale per importi monetari

.12 break and continue Dichiarazioni

.13 Operatori booleani and, or and not

.14 Introduzione alla scienza dei dati: misure della tendenza centrale: media, mediana e modo

.15 WrapUp

3.1 INTRODUZIONE
In questo capitolo, presentiamo le istruzioni di controllo di Python: if, if else, if elif else,

mentre, per, rompere e continuare. Userai l'istruzione for per eseguire la sequenza
iterazione controllata: vedrai che il numero di elementi in una sequenza di elementi
determina il numero di iterazioni dell'istruzione for. Userai la funzione incorporata

range per generare sequenze di numeri interi.

Mostreremo l'iterazione controllata dalla sentinella con l'istruzione while. Userai il file
Tipo decimale della libreria standard Python per calcoli monetari precisi. Bene
formattare i dati in fstrings (ovvero, formattare le stringhe) utilizzando vari identificatori di formato. Bene
mostra anche gli operatori booleani e, o e non per la creazione di condizioni composte. Nel
nella sezione Introduzione alla scienza dei dati, prenderemo in considerazione le misure della tendenza centrale: media,
mediana e modalità, utilizzando il modulo delle statistiche della libreria standard di Python.

33 .2 DICHIARAZIONI DI CONTROLLO
Pagina 95
.2 DICHIARAZIONI DI CONTROLLO
Python fornisce tre istruzioni di selezione che eseguono il codice in base a una condizione che
restituisce True o False:

L'istruzione if esegue un'azione se una condizione è True o salta l'azione se il

condizione è False.

L' istruzione if ... else esegue un'azione se una condizione è True o esegue

una diversa azione se la condizione è falsa.

L' istruzione if ... elif ... else esegue una delle tante azioni diverse,
a seconda della verità o falsità di diverse condizioni.

Ovunque sia possibile posizionare una singola azione, è possibile posizionare un gruppo di azioni.

Python fornisce due istruzioni di iterazione, nel frattempo e per:

L' istruzione while ripete un'azione (o un gruppo di azioni) fintanto che a


la condizione rimane vera.

L' istruzione for ripete un'azione (o un gruppo di azioni) per ogni elemento in un file
sequenza di elementi.

Parole chiave

Le parole if, elif, else, while, for, True e False sono parole chiave Python. Utilizzando
una parola chiave come identificatore come il nome di una variabile è un errore di sintassi. La tabella seguente
elenca le parole chiave di Python.

Parole chiave Python

e come asserire asincrono attendere

rompere classe continua def del

3
Pagina 96
elif altro tranne Falso finalmente

per a partire dal globale Se importare

nel è lambda Nessuna non locale

non o passaggio aumentare ritorno

Vero provare mentre con dare la precedenza


3.3 DICHIARAZIONE IF
Eseguiamo un'istruzione if di Python:

lecca qui per visualizzare l'immagine del codice

In [1]: voto = 85
In [2]: se voto> = 60 :
...: print ( 'Superato' )
...:
Passato

La condizione grade> = 60 è True, quindi l'istruzione print indentata in if's


suite visualizza "Superato".

Rientro della suite

È richiesto il rientro di una suite; in caso contrario, si verifica un errore di sintassi di IndentationError:

lecca qui per visualizzare l'immagine del codice

In [3]: se voto> = 60 :
...: l' istruzione print ( 'Passed' ) # non è rientrata correttamente
File "<ipythoninput3f42783904220>", riga 2
L'istruzione print ('Passed') # non è rientrata correttamente

^ Pagina 97
IndentationError : previsto un blocco rientrato

Un errore IndentationError si verifica anche se hai più di un'istruzione in una suite

e quelle dichiarazioni non hanno la stessa indentazione:

lecca qui per visualizzare l'immagine del codice

In [4]: se voto> = 60 :
...: print ( 'Passed' ) # rientrato di 4 spazi
...: print ( 'Ottimo lavoro! ) # ha rientrato in modo errato solo due spazi
File <ipythoninput48c0d75c127bf>, riga 3
print ('Ottimo lavoro!) # ha rientrato in modo errato solo due spazi
^
IndentationError : unindent non corrisponde a nessun livello di rientro esterno

A volte i messaggi di errore potrebbero non essere chiari. Il fatto che Python richiami l'attenzione su
di solito è sufficiente per capire cosa c'è che non va. Applica il rientro
convenzioni in modo uniforme in tutto il codice, programmi che non sono uniformi
indentati sono difficili da leggere.

Ogni espressione può essere interpretata come vera o falsa

Puoi basare le decisioni su qualsiasi espressione. Un valore diverso da zero è True. Zero è falso:

lecca qui per visualizzare l'immagine del codice

In [5]: se 1 :
...: print ( 'I valori diversi da zero sono veri, quindi verrà stampato')
...:
I valori diversi da zero sono veri, quindi verrà stampato

In [6]: se 0 :
...: print ( 'Zero è falso, quindi non verrà stampato' )

In [7]:

Le stringhe contenenti caratteri sono True, mentre le stringhe vuote ('', "" o "" "" "") lo sono

Falso.

Confondere == e =

L'uso dell'operatore di uguaglianza == invece di = in un'istruzione di assegnazione può portare a


problemi sottili. Ad esempio, in questa sessione, lo snippet [1] ha definito il voto con

C
Pagina 98
Incarico:

grado = 85

Se invece scrivessimo accidentalmente:

grado == 85

allora il grado sarebbe indefinito e avremmo un'eccezione NameError. Se il grado fosse stato definito
prima dell'affermazione precedente, quindi voto == 85 restituirebbe semplicemente True o

Falso e non eseguire un incarico. Questo è un errore logico.

3.4 DICHIARAZIONI IF ELSE E IF ELIF ELSE


L'istruzione if else esegue suite diverse, a seconda che una condizione sia vera

o Falso:

lecca qui per visualizzare l'immagine del codice

In [1]: voto = 85

In [2]: se voto> = 60 :
...: print ( 'Superato' )
...: altro :
...: print ( 'Fallito' )
...:
Passato

La condizione sopra è True, quindi la suite if mostra "Superato". Nota che quando
premere Invio dopo aver digitato print ("Passed"), IPython fa rientrare la riga successiva di quattro spazi.
È necessario eliminare questi quattro spazi in modo che else: suite si allinei correttamente sotto i

in se.

Il codice seguente assegna 57 al voto variabile, quindi mostra if else

ancora una volta per dimostrare che solo la suite else viene eseguita quando la condizione è

Falso:

lecca qui per visualizzare l'immagine del codice

In [3]: voto = 57

In [4]: se voto> = 60 : Pagina 99


...: print ( 'Superato' )
...: altro :
...: print ( 'Fallito' )
...:
Fallito

Utilizzare i tasti freccia su e giù per spostarsi avanti e indietro nel file
frammenti di sessione interattiva corrente. Premendo Invio viene eseguito nuovamente lo snippet
visualizzato. Impostiamo il grado su 99, premi due volte il tasto freccia su per richiamare il codice da

snippet [4], quindi premi Invio per rieseguire il codice come snippet [6]. Ogni richiamato
lo snippet che esegui ottiene un nuovo ID:

lecca qui per visualizzare l'immagine del codice

In [5]: voto = 99

In [6]: se voto> = 60 :
...: print ( 'Superato' )
...: altro :
...: print ( 'Fallito' )
...:
Passato

Espressioni condizionali

A volte le suite in un'istruzione if else assegnano valori diversi a una variabile,


in base a una condizione, come in:

lecca qui per visualizzare l'immagine del codice

In [7]: voto = 87

In [8]: se voto> = 60 :
...: risultato = 'Superato'
...: altro :
...: result = 'Failed'
...:

Possiamo quindi stampare o valutare quella variabile:

In [9]: risultato
Out [9]: "Passed"

C
Pagina 100
Puoi scrivere istruzioni come snippet [8] usando un'espressione condizionale concisa :

lecca qui per visualizzare l'immagine del codice

In [10]: risultato = ( "Superato" se voto> = 60 altro "Non superato " )

In [11]: risultato
Out [11]: "Passed"

Le parentesi non sono obbligatorie, ma chiariscono che l'istruzione assegna il


valore dell'espressione condizionale da ottenere. Innanzitutto, Python valuta il grado della condizione

> = 60:

Se è True, lo snippet [10] assegna come risultato il valore dell'espressione a sinistra


di if, vale a dire "Passed". La parte else non viene eseguita.
Se è False, lo snippet [10] assegna come risultato il valore dell'espressione a
diritto di altro, vale a dire "Fallito".

In modalità interattiva, puoi anche valutare direttamente l'espressione condizionale, come in:

lecca qui per visualizzare l'immagine del codice

In [12]: "Superato" se voto> = 60 altrimenti "Non superato "


Out [12]: "Passed"

Dichiarazioni multiple in una suite

Il codice seguente mostra due istruzioni nella suite else di un if ... else
dichiarazione:

lecca qui per visualizzare l'immagine del codice

In [13]: voto = 49

In [14]: se voto> = 60 :
...: print ( 'Superato' )
...: altro :
...: print ( 'Fallito' )
...: print ( 'Devi ripetere questo corso' )
...:
Fallito
Devi ripetere questo corso

C
Pagina 101

In questo caso, il voto è inferiore a 60, quindi vengono eseguite entrambe le istruzioni nella suite else.

Se non indenti la seconda stampa, non è nella suite dell'altro. Così che
l'istruzione viene eseguita sempre , creando forse uno strano output errato:

lecca qui per visualizzare l'immagine del codice

In [15]: voto = 100

In [16]: se voto> = 60 :
...: print ( 'Superato' )
...: altro :
...: print ( 'Fallito' )
...: print ( 'Devi ripetere questo corso' )
...:
Passato
Devi ripetere questo corso

if ... elif ... else Istruzione

Puoi testare per molti casi usando l' istruzione if ... elif ... else . Il
Il codice seguente visualizza "A" per i voti maggiori o uguali a 90, "B" per i voti in
intervallo 80-89, "C" per i gradi 70-79, "D" per i gradi 60-69 e "F" per tutti gli altri gradi.
Viene eseguita solo l'azione per la prima condizione True. Lo snippet [18] mostra C, perché

il voto è 77:

In [17]: voto = 77

In [18]: se voto> = 90 :
...: print ( 'A' )
...: grado elif > = 80 :
...: print ( 'B' )
...: grado elif > = 70 :
...: print ( 'C' )
...: grado elif > = 60 :
...: print ( 'D' )
...: altro :
...: print ( 'F' )
...:
C

La prima condizione, voto> = 90, è False, quindi la stampa ("A") viene saltata. Il secondo
anche la condizione — grado> = 80 — è False, quindi la stampa ("B") viene saltata. Il terzo
condition — grade> = 70 — is True, quindi print ('C') viene eseguito. Poi tutto il resto

C
Pagina 102
il codice nell'istruzione if ... elif ... else viene ignorato. Un if ... elif ... else lo è
più veloce delle istruzioni if ​separate, perché il test delle condizioni si ferma non appena a
la condizione è vera.

altro è facoltativo

L'altro nell'istruzione if ... elif ... else è facoltativo. Compreso ti consente


per gestire i valori che non soddisfano nessuna delle condizioni. Quando un if ... elif
dichiarazione senza un'altra verifica un valore che non rende vera nessuna delle sue condizioni,
il programma non esegue nessuna delle suite dell'istruzione: l'istruzione successiva in
sequenza dopo l'esecuzione dell'istruzione if ... elif ... Se specifichi l'altro, tu
deve posizionarlo dopo l'ultimo elif, altrimenti si verifica un SyntaxError.

Errori logici

Il segmento di codice rientrato in modo errato nello snippet [16] è un esempio di non irreversibile
errore logico . Il codice viene eseguito, ma produce risultati errati. Per un errore logico fatale
in uno script , si verifica un'eccezione (come ZeroDivisionError da un tentativo di
dividere per 0), quindi Python visualizza un traceback, quindi termina lo script. Un errore fatale in
la modalità interattiva termina solo lo snippet corrente, quindi IPython attende il tuo prossimo
ingresso.

3.5 DURANTE LA DICHIARAZIONE


L' istruzione while ti consente di ripetere una o più azioni durante una condizione

rimane vero. Usiamo un'istruzione while per trovare la prima potenza di 3 maggiore di 50:

lecca qui per visualizzare l'immagine del codice

In [1]: prodotto = 3

In [2]: while product <= 50 :


...: prodotto = prodotto * 3
...:

In [3]: prodotto
Uscita [3]: 81

Lo snippet [3] valuta il prodotto per vedere il suo valore, 81, che è la prima potenza di 3 più grande
di 50.

Qualcosa nella suite dell'istruzione while deve cambiare il valore del prodotto, quindi il file

C
Pagina 103
la condizione alla fine diventa Falso. In caso contrario, si verifica un ciclo infinito. Nel
applicazioni eseguite da Terminale, Prompt dei comandi di Anaconda o shell, digita Ctrl
+ c o control + c per terminare un ciclo infinito. Gli IDE hanno in genere un pulsante della barra degli strumenti o
opzione di menu per interrompere l'esecuzione di un programma.

3.6 PER DICHIARAZIONE


L' istruzione for consente di ripetere un'azione o più azioni per ogni elemento in un file
sequenza di elementi. Ad esempio, una stringa è una sequenza di singoli caratteri. Andiamo
visualizzare 'Programmazione' con i suoi caratteri separati da due spazi:

lecca qui per visualizzare l'immagine del codice

In [1]: per il carattere in "Programmazione" :


...: print (carattere, fine = '' )
...:
Programming

L'istruzione for viene eseguita come segue:

Entrando nell'istruzione, assegna al target la "P" in "Programmazione"


variabile tra le parole chiave per e in, in questo caso, carattere.

Successivamente, viene eseguita l'istruzione nella suite, visualizzando il valore del carattere seguito da
due spazi: ne parleremo tra poco.

Dopo aver eseguito la suite, Python assegna al personaggio l'elemento successivo nel file
sequenza (cioè la "r" in "Programmazione"), quindi esegue nuovamente la suite.

Questo continua finché ci sono più elementi nella sequenza da elaborare. In questo caso,
l'istruzione termina dopo aver visualizzato la lettera "g", seguita da due spazi.

L'uso della variabile target nella suite, come abbiamo fatto qui per visualizzarne il valore, è comune ma
non richiesto.

Argomento della parola chiave della fine della stampa della funzione

La funzione incorporata print mostra i suoi argomenti, quindi sposta il cursore al successivo
linea. Puoi cambiare questo comportamento con l'argomento end , come in

C
Pagina 104
print (carattere, fine = '' )

che mostra il valore del carattere seguito da due spazi. Quindi, tutti i personaggi
visualizzare orizzontalmente sulla stessa riga. Le chiamate Python terminano un argomento di parola chiave , ma

fine in sé non è una parola chiave Python. Gli argomenti delle parole chiave sono talvolta chiamati named
argomenti . L'argomento della parola chiave end è facoltativo. Se non lo includi, stampa

utilizza una nuova riga ('\ n') per impostazione predefinita. La Guida allo stile per il codice Python consiglia
non inserire spazi attorno al =.

Argomento parola chiave sep di stampa della funzione

È possibile utilizzare l'argomento della parola chiave sep (abbreviazione di separator) per specificare la stringa that
appare tra gli elementi visualizzati per la stampa. Quando non lo specifichi
argomento, print utilizza uno spazio per impostazione predefinita. Visualizziamo tre numeri, ciascuno
separato dal successivo da una virgola e uno spazio, anziché solo uno spazio:

lecca qui per visualizzare l'immagine del codice

In [2]: print ( 10 , 20 , 30 , sep = ',' )


10, 20, 30

Per rimuovere gli spazi predefiniti, utilizzare sep = '' (ovvero una stringa vuota).

3.6.1 Iterabili, elenchi e iteratori


La sequenza a destra della parola chiave in dell'istruzione for deve essere un iterabile , ovvero
è un oggetto da cui l'istruzione for può prendere un elemento alla volta fino a quando non più
gli elementi rimangono. Python ha altri tipi di sequenza iterabili oltre alle stringhe. Uno dei più
comune è un elenco , che è una raccolta di elementi separati da virgole racchiusi in un quadrato
parentesi ([e]). Il codice seguente totalizza cinque numeri interi in un elenco:

lecca qui per visualizzare l'immagine del codice

In [3]: totale = 0

In [4]: per il numero in [ 2 , 3 , 0 , 17 , 9 ]:


...: totale = totale + numero
...:

In [5]: totale
Uscita [5]: 25

C
Pagina 105
Ogni sequenza ha un iteratore . L'istruzione for utilizza l'iteratore "dietro
scene "per ottenere ogni elemento consecutivo fino a quando non ce ne sono più da elaborare. L'iteratore è
come un segnalibro: sa sempre dove si trova nella sequenza, quindi può restituire il successivo
oggetto quando è chiamato a farlo. Copriamo gli elenchi in dettaglio nella sezione "Sequenze: elenchi e
Capitolo Tuple ". Lì, vedrai che l'ordine degli elementi in un elenco è importante e che a
gli elementi della lista sono mutabili (cioè modificabili).

3.6.2 Funzione di portata incorporata


Usiamo un'istruzione for e la funzione di intervallo incorporata per iterare esattamente 10
volte, visualizzando i valori da 0 a 9:

lecca qui per visualizzare l'immagine del codice

In [6]: per contatore in serie ( 10 ):


...: print (counter, end = '' )
...:
0123456789

La chiamata di funzione range (10) crea un oggetto iterabile che rappresenta una sequenza di
interi consecutivi che iniziano da 0 e continuano fino a, ma non includendo, il
valore argomento (10): in questo caso, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. L'istruzione for termina

quando termina l'elaborazione dell'ultimo numero intero che l'intervallo produce. Iteratori e iterabili
gli oggetti sono due delle caratteristiche di programmazione in stile funzionale di Python . Ti presenteremo
più di questi in tutto il libro.

Errori off-by-one

Un tipo comune di errore offbyone si verifica quando si assume l'argomento di quell'intervallo


il valore è incluso nella sequenza generata. Ad esempio, se fornisci 9 come intervallo
quando si tenta di produrre la sequenza da 0 a 9, l'intervallo genera solo 0
fino a 8.

3.7 INCARICHI AUMENTATI


Le assegnazioni aumentate abbreviano le espressioni di assegnazione in cui lo stesso
il nome della variabile appare a sinistra ea destra del = dell'assegnazione, come total fa in:

lecca qui per visualizzare l'immagine del codice

per numero in [ 1 , 2 , 3 , 4 , 5 ]:

totale = totale + numero Pagina 106

Lo snippet [2] lo reimplementa utilizzando un'addizione aumentata di assegnazione (+ =)

dichiarazione :

lecca qui per visualizzare l'immagine del codice

In [1]: totale = 0

In [2]: per il numero in [ 1 , 2 , 3 , 4 , 5 ]:


...: totale + = numero # aggiunge il numero al totale
...:

In [3]: totale
Uscita [3]: 15

L'espressione + = nello snippet [2] prima aggiunge il valore di number al totale corrente, quindi
memorizza il nuovo valore in totale. La tabella seguente mostra le assegnazioni aumentate di esempio:

Aumentato Campione
Spiegazione Assegna
Incarico espressione

Supponiamo: c = 3, d = 5, e = 4, f = 2, g = 9, h = 12

+= c+=7 c=c+7 Da 10 a c

= d=4 d=d4 Da 1 a d

*= e*=5 e=e*5 20 a e

** = f ** = 3 f = f ** 3 Da 8 a f

/= g/=2 g=g/2 4,5 a g

C
Pagina 107
// = g // = 2 g = g // 2 4ag

%= h% = 9 h = h% 9 3 alle h

3.8 ITERAZIONE CONTROLLATA IN SEQUENZA; FORMATTATO


STRINGHE
Questa sezione e la successiva risolvono due problemi di media delle classi. Considera quanto segue
dichiarazione dei requisiti:

Una classe di dieci studenti ha risposto a un quiz. I loro voti (numeri interi nell'intervallo 0-100) sono 98,
76, 71, 87, 83, 90, 57, 79, 82, 94. Determina la media della classe durante il quiz.

Il seguente script per risolvere questo problema mantiene un totale parziale dei voti,
calcola la media e visualizza il risultato. Abbiamo inserito i 10 voti in una lista, ma tu
potrebbe inserire i voti di un utente alla tastiera (come faremo nel prossimo esempio) o
leggerli da un file (come vedrai come fare nel capitolo "File ed eccezioni"). Noi
mostra come leggere i dati dai database SQL e NoSQL in formato capitolo 16 .

lecca qui per visualizzare l'immagine del codice

1 # class_average.py
2 "" "Programma medio di classe con iterazione controllata dalla sequenza." ""
3
4 # fase di inizializzazione
5 totale = 0 # somma dei voti
6 grade_counter = 0
7 voti = [ 98 , 76 , 71 , 87 , 83 , 90 , 57 , 79 , 82 , 94 ] # elenco di 10 voti
8
9 # fase di elaborazione
10 per voto in gradi:
11 totale + = voto # aggiunge il voto attuale al totale parziale
12 grade_counter + = 1 # indica che è stato elaborato un altro voto d
13
14 # fase di terminazione
15 media = total / grade_counter
16 print (f 'La media della classe è {media} ' )

C
Pagina 108
lecca qui per visualizzare l'immagine del codice

La media della classe è 81,7

Le righe 5-6 creano le variabili total e grade_counter e inizializzano ciascuna a 0.


Linea 7

lecca qui per visualizzare l'immagine del codice

voti = [ 98 , 76 , 71 , 87 , 83 , 90 , 57 , 79 , 82 , 94 ] # elenco di 10 voti

crea i voti variabili e li inizializza con un elenco di 10 voti interi.

L'istruzione for elabora ogni voto nell'elenco dei voti. La riga 11 aggiunge la corrente
voto sul totale. Quindi, la riga 12 aggiunge 1 alla variabile grade_counter da mantenere
traccia del numero di voti elaborati finora. L'iterazione termina quando tutti i 10 voti
nell'elenco sono stati elaborati. La Guida allo stile per il codice Python consiglia di inserire un file
riga vuota sopra e sotto ogni istruzione di controllo (come nelle righe 8 e 13). Quando il for

l'istruzione termina, la riga 15 calcola la media e la riga 16 la visualizza. Più avanti in questo
capitolo, usiamo la programmazione in stile funzionale per calcolare la media degli elementi di una lista
in modo più conciso.

Introduzione alle stringhe formattate

Linea 16 utilizza la seguente semplice fstring (abbreviazione di stringa formattata ) per formattare questo
risultato dello script inserendo il valore di media in una stringa:

lecca qui per visualizzare l'immagine del codice

f "La media della classe è {media} "

La lettera f prima dell'apice della stringa indica che si tratta di una stringa. Tu specifichi
dove inserire i valori utilizzando segnaposto delimitati da parentesi graffe ({e}). Il
segnaposto

{media}

converte il valore della media variabile in una rappresentazione di stringa, quindi lo sostituisce

C
Pagina 109
{average} con quel testo sostitutivo . Le espressioni di testo sostitutivo possono contenere
valori, variabili o altre espressioni, come calcoli o chiamate di funzioni. Nella riga 16,
avremmo potuto usare total / grade_counter al posto della media, eliminando il
è necessaria la riga 15.

3.9 ITERAZIONE CONTROLLATA DA SENTINEL


Generalizziamo il problema della media di classe. Considera i seguenti requisiti
dichiarazione:

Sviluppa un programma di valutazione della classe che elabori un numero arbitrario di voti
ogni volta che il programma viene eseguito.

La dichiarazione dei requisiti non indica quali sono i voti o quanti ce ne sono,
quindi faremo in modo che l'utente inserisca i voti. Il programma elabora un arbitrario
numero di voti. L'utente inserisce i voti uno alla volta finché tutti i voti sono stati
inserito, quindi immette un valore sentinella (chiamato anche valore del segnale , valore fittizio o un
valore flag ) per indicare che non ci sono più voti.

Implementazione dell'iterazione controllata da Sentinel

Il seguente script risolve il problema della media della classe con l'iterazione controllata dalla sentinella.
Si noti che testiamo la possibilità di divisione per zero. Se non viene rilevato, ciò causerebbe
un errore logico fatale. Nel capitolo "File ed eccezioni", scriviamo programmi che
riconoscere tali eccezioni e intraprendere azioni appropriate.

lecca qui per visualizzare l'immagine del codice

1 # class_average_sentinel.py
2 "" "Programma medio di classe con iterazione controllata da sentinella." ""
3
4 # fase di inizializzazione
5 totale = 0 # somma dei voti
6 grade_counter = 0 # numero di voti inseriti
7
8 # fase di elaborazione
9 grado = int (input ( 'Inserisci voto, 1 alla fine:' )) # ottieni un voto
10
11 mentre voto! = 1 :
12 totale + = voto
13 contatore_gradi + = 1
14 grado = int (input ( 'Inserisci voto, 1 alla fine:' ))
15
16 # fase di terminazione
17 if grade_counter! = 0 :

18 media = totale / grado_counter Pagina 110


19 print (f 'La media della classe è {media: .2 f} ' )
20 altro :
21 print ( "Non sono stati inseriti voti" )

lecca qui per visualizzare l'immagine del codice

Inserisci voto, da 1 a fine: 97


Inserisci voto, da 1 a fine: 88
Inserisci voto, da 1 a fine: 72
Inserisci voto, 1 per terminare: 1
La media della classe è 85,67

Logica di programma per iterazione controllata da Sentinel

Nell'iterazione controllata dalla sentinella, il programma legge il primo valore (riga 9) prima
raggiungendo l'istruzione while. Il valore immesso nella riga 9 determina se il file
il flusso di controllo del programma dovrebbe entrare nella suite di while (righe 12-14). Se la condizione
nella riga 11 è False, l'utente ha inserito il valore sentinel (1), quindi la suite non lo fa
eseguire perché l'utente non ha inserito alcun voto. Se la condizione è True, la suite

viene eseguito, aggiungendo il valore del voto al totale e incrementando il

grade_counter.

Successivamente, la riga 14 immette un altro grado dall'utente e la condizione (riga 11) viene verificata
ancora una volta, utilizzando il voto più recente inserito dall'utente. Il valore del voto è sempre
input immediatamente prima che il programma verifichi la condizione while, in modo che possiamo determinare
se il valore appena inserito è la sentinella prima di elaborare quel valore come un voto.

Quando viene immesso il valore sentinella, il ciclo termina e il programma non aggiunge –1
al totale. In un ciclo controllato da sentinel che esegue l'input dell'utente, qualsiasi prompt (righe 9
e 14) dovrebbe ricordare all'utente il valore sentinella.

Formattazione della media della classe con due cifre decimali

Questo esempio ha formattato la media della classe con due cifre a destra del decimale
punto. In una fstring, puoi opzionalmente seguire un'espressione di testo sostitutivo con un
due punti (:) e un identificatore di formato che descrive come formattare il testo sostitutivo.
L'identificatore di formato .2f (riga 19) formatta la media come numero a virgola mobile (f)

con due cifre a destra del punto decimale (.2). In questo esempio, la somma di
i voti erano 257, che, quando diviso per 3, restituisce 85,666666666 .... Formattando il file
media con .2f lo arrotonda alla posizione dei centesimi, producendo la sostituzione

C
Pagina 111
testo 85.67. Sarebbe una media con solo una cifra a destra del punto decimale
formattato con uno zero finale (ad esempio, 85,50). Il capitolo "Stringhe: uno sguardo più profondo"

discute molte altre funzionalità di formattazione delle stringhe.

3.10 GAMMA DI FUNZIONI INTEGRATE: UNO SGUARDO PIÙ PROFONDO


La gamma di funzioni ha anche due e tre versioni di strumenti. Come hai visto, range's
La versione oneargument produce una sequenza di numeri interi consecutivi da 0 fino a, ma
escluso il valore dell'argomento. La versione a due argomenti della gamma di funzioni produce
una sequenza di numeri interi consecutivi dal valore del primo argomento fino a, ma non
incluso, il valore del secondo argomento, come in:

lecca qui per visualizzare l'immagine del codice

In [1]: per numero di serie ( 5 , 10 ):


...: print (numero, fine = '' )
...:
56789

La versione a tre strumenti dell'intervallo di funzioni produce una sequenza di numeri interi dal primo
valore dell'argomento fino a, ma non incluso, il valore del secondo argomento, incrementando
dal valore del terzo argomento, che è noto come il passaggio :

lecca qui per visualizzare l'immagine del codice

In [2]: per numero di intervallo ( 0 , 10 , 2 ):


...: print (numero, fine = '' )
...:
02468

Se il terzo argomento è negativo, la sequenza procede dal primo argomento


valore fino a, ma escluso il valore del secondo argomento, decrementato del
valore del terzo argomento, come in:

lecca qui per visualizzare l'immagine del codice

In [3]: per numero di serie ( 10 , 0 , 2 ):


...: print (numero, fine = '' )
...:
10 8 6 4 2

3C .11 UTILIZZO DEL TIPO DECIMALE PER GLI IMPORTI MONETARI


Pagina 112
3.11 UTILIZZO DEL TIPO DECIMALE PER GLI IMPORTI MONETARI
In questa sezione, introduciamo le funzionalità Decimal per calcoli monetari precisi. Se

sei nel settore bancario o in altri campi che richiedono una precisione "da un centesimo", dovresti
indagare in profondità le capacità di Decimal.

Per la maggior parte delle applicazioni scientifiche e matematiche che utilizzano numeri con decimale
punti, i numeri in virgola mobile incorporati di Python funzionano bene. Ad esempio, quando noi
parliamo di una temperatura corporea “normale” di 98,6, non abbiamo bisogno di essere precisi alla grande
numero di cifre. Quando osserviamo la temperatura su un termometro e la leggiamo come 98,6,
il valore effettivo può essere 98,5999473210643. Il punto qui è che chiamare questo numero
98.6 è adeguato per la maggior parte delle applicazioni a temperatura corporea.

I valori in virgola mobile sono memorizzati in formato binario (abbiamo introdotto binario nel primo
capitolo e discuterne in profondità nell'appendice in linea "Sistemi numerici"). Alcuni
i valori in virgola mobile vengono rappresentati solo approssimativamente quando vengono convertiti in
binario. Ad esempio, considera l'importo variabile con il valore di dollari e centesimi

112.31. Se visualizzi l'importo, sembra che abbia il valore esatto che gli hai assegnato:

In [1]: importo = 112,31

In [2]: stampa (importo)


112.31

Tuttavia, se si stampa l'importo con 20 cifre di precisione a destra del decimale


punto, puoi vedere che il valore in virgola mobile effettivo in memoria non è esattamente 112,31
—È solo un'approssimazione:

lecca qui per visualizzare l'immagine del codice

In [3]: print (f ' {amount: .20 f} ' )


112.31000000000000227374

Molte applicazioni richiedono una rappresentazione precisa di numeri con punti decimali.
Istituzioni come le banche che gestiscono milioni o addirittura miliardi di transazioni al giorno
devono legare le loro transazioni "al centesimo". I numeri in virgola mobile possono rappresentare
alcuni ma non tutti gli importi monetari con precisione in centesimi.

1
La libreria standard di Python fornisce molte funzionalità predefinite che puoi utilizzare
nel codice Python per evitare di "reinventare la ruota". Per calcoli monetari e
altre applicazioni che richiedono una rappresentazione e manipolazione precise dei numeri

C
Pagina 113
con punti decimali, la libreria standard Python fornisce il tipo Decimal , che utilizza un file
schema di codifica speciale per risolvere il problema della precisione del centesimo. Quello schema
richiede memoria aggiuntiva per contenere i numeri e tempo di elaborazione aggiuntivo
esegue calcoli ma fornisce la precisione richiesta per i calcoli monetari.
Le banche devono anche affrontare altri problemi come l'utilizzo di un algoritmo di arrotondamento equo quando
2
stanno calcolando l'interesse giornaliero sui conti. Il tipo Decimal offre tali funzionalità.

1
ttps: //docs.python.org/3.7/library/index.html .

2
Per ulteriori funzionalità del modulo decimale, visitare

ttps: //docs.python.org/3.7/library/decimal.html .

Importazione di tipo Decimal dal modulo decimal

Abbiamo usato diversi tipi incorporati : int (per interi, come 10), float (per floatingpoint
numeri, come 7.5) e str (per stringhe come "Python"). Il tipo Decimal non viene creato
in Python. Piuttosto, fa parte della libreria standard Python, che è divisa in
gruppi di capacità correlate chiamate moduli . Il modulo decimale definisce il tipo

Decimale e sue capacità.

Per usare il tipo Decimal, devi prima importare l'intero modulo decimale, come in

importa decimale

e fare riferimento al tipo Decimal come decimal.Decimal, oppure è necessario indicare uno specifico
capacità di importare utilizzando from import , come facciamo qui:

lecca qui per visualizzare l'immagine del codice


In [4]: da decimal import Decimal

Questo importa solo il tipo Decimal dal modulo decimal in modo che tu possa usarlo
nel codice. Discuteremo altre forme di importazione a partire dal prossimo capitolo.

Creazione di decimali

In genere crei un decimale da una stringa:

lecca qui per visualizzare l'immagine del codice

hC
Pagina 114
In [5]: principal = Decimal ( '1000.00' )

In [6]: principale
In uscita [6]: decimale ("1000,00")

In [7]: tasso = decimale ( "0,05" )

In [8]: tasso
In uscita [8]: decimale ("0,05")

Presto utilizzeremo queste variabili principal e rate in un interesse composto


calcolo.

Aritmetica decimale

I decimali supportano gli operatori aritmetici standard +,, *, /, //, ** e%, oltre a
i corrispondenti incarichi aumentati:

In [9]: x = decimale ( '10,5 ' )

In [10]: y = decimale ( "2" )

In [11]: x + y
Fuori [11]: Decimale ('12,5 ')

In [12]: x // y
Fuori [12]: Decimale ("5")

In [13]: x + = y

In [14]: x
Fuori [14]: Decimale ('12,5 ')

È possibile eseguire operazioni aritmetiche tra decimali e interi, ma non tra

Decimali e numeri in virgola mobile.

Dichiarazione sui requisiti per il problema degli interessi composti

Calcoliamo l'interesse composto utilizzando il tipo Decimale per un valore monetario preciso
calcoli. Considera la seguente dichiarazione dei requisiti:

Una persona investe $ 1000 in un conto di risparmio con un interesse del 5%. Supponendo che il file
persona lascia tutti gli interessi in deposito nel conto, calcola e visualizza l'importo
di denaro sul conto alla fine di ogni anno per 10 anni. Utilizza il seguente
formula per determinare queste quantità:

n Pagina 115
a = p (1 + r )

dove

p è l'importo originariamente investito (ovvero il capitale),

r è il tasso di interesse annuale,

n è il numero di anni e

una è la quantità in deposito alla fine del n ° anno.

Calcolo dell'interesse composto

Per risolvere questo problema, usiamo le variabili principal e rate che abbiamo definito in
frammenti [5] e [7] e un'istruzione for che esegue il calcolo degli interessi per
ciascuno dei 10 anni in cui il denaro rimane in deposito. Per ogni anno, il ciclo mostra un file
stringa formattata contenente il numero dell'anno e l'importo del deposito alla fine del
quell'anno:

lecca qui per visualizzare l'immagine del codice

In [15]: per l' anno in serie ( 1 , 11 ):


...: importo = capitale * ( 1 + tasso) ** anno
...: print (f ' {anno:> 2 } {importo:> 10.2 f} ' )
...:
1 1050.00
2 1102.50
3 1157.62
4 1215.51
5 1276.28
6 1340.10
7 1407.10
8 1477.46
9 1551.33
10 1628.89

n
L'espressione algebrica (1 + r) dalla dichiarazione dei requisiti è scritta come

( 1 + tariffa) ** anno

dove il tasso variabile rappresenta re l' anno variabile rappresenta n .

Formattazione dell'anno e dell'importo del deposito

C
Pagina 116
La dichiarazione

lecca qui per visualizzare l'immagine del codice

print (f ' {anno:> 2} {importo:> 10.2f} ' )

usa una stringa con due segnaposto per formattare l'output del ciclo.

Il segnaposto

{anno:> 2}

utilizza l'identificatore di formato> 2 per indicare che il valore dell'anno deve essere allineato a destra (>)

in un campo di larghezza 2: la larghezza del campo specifica il numero di posizioni dei caratteri da utilizzare
durante la visualizzazione del valore. Per i valori dell'anno a una cifra da 1 a 9, l'identificatore di formato

> 2 visualizza uno spazio seguito dal valore, allineando così a destra gli anni nel
prima colonna. Il diagramma seguente mostra i numeri 1 e 10 ciascuno formattato in a
larghezza del campo di 2:

Puoi allineare i valori a sinistra con <.

L'identificatore di formato 10.2f nel segnaposto

{importo:> 10.2f}

formatta la quantità come numero a virgola mobile (f) allineato a destra (>) in una larghezza di campo di 10
con un punto decimale e due cifre a destra del punto decimale (.2). Formattazione
gli importi in questo modo allineano verticalmente i loro punti decimali , come è tipico con monetario
importi. Nelle posizioni di 10 caratteri, i tre caratteri più a destra sono i numeri
punto decimale seguito dalle due cifre alla sua destra. I restanti sette caratteri
le posizioni sono gli spazi iniziali e le cifre a sinistra del punto decimale. In questo
Ad esempio, tutti gli importi in dollari hanno quattro cifre a sinistra del punto decimale, quindi ciascuno
il numero è formattato con tre spazi iniziali . Il diagramma seguente mostra il file
formattazione per il valore 1050.00:

C
Pagina 117

3.12 BREAK E CONTINUA AFFERMAZIONI


Le istruzioni break e continue alterano il flusso di controllo di un ciclo. Eseguire una pausa
dichiarazione in un istante o per esce immediatamente da tale istruzione. Nel codice seguente,

range produce la sequenza intera 0–99, ma il ciclo termina quando number è


10:

lecca qui per visualizzare l'immagine del codice

In [1]: per numero di serie ( 100 ):


...: se numero == 10 :
...: pausa
...: print (numero, fine = '' )
...:
0123456789

In uno script, l'esecuzione continuerà con l'istruzione successiva dopo il ciclo for. Il

Le istruzioni while e for hanno ciascuna una clausola else opzionale che viene eseguita solo se il
il ciclo termina normalmente, ovvero non come risultato di un'interruzione.

L'esecuzione di un'istruzione continue in un ciclo while o for salta il resto del


suite di loop. In un attimo, la condizione viene quindi testata per determinare se il ciclo
dovrebbe continuare l'esecuzione. In un for, il ciclo elabora l'elemento successivo nella sequenza
(se presente):

lecca qui per visualizzare l'immagine del codice

In [2]: per numero di serie ( 10 ):


...: se numero == 5 :
...: continua
...: print (numero, fine = '' )
...:
012346789

3.13 OPERATORI BOOLEANI E, O E NON


C
Pagina 118
Gli operatori condizionali>, <,> =, <=, == e! = Possono essere usati per formare semplice
condizioni come grado> = 60. Per formare condizioni più complesse che si combinano
condizioni semplici, utilizzare gli operatori and , or e not booleani.

Operatore booleano e

Per garantire che due condizioni siano entrambe True prima di eseguire un'istruzione di controllo
suite, utilizza l' operatore booleano e per combinare le condizioni. Il codice seguente

definisce due variabili, quindi verifica una condizione che è vera se e solo se entrambe semplici
le condizioni sono Vere: se una delle condizioni semplici (o entrambe) è False, l'intera

e l'espressione è falsa:

lecca qui per visualizzare l'immagine del codice

In [1]: sesso = "Femmina"

In [2]: età = 70

In [3]: se sesso == "Femmina" ed età> = 65 :


...: print ( 'Senior female' )
...:
Femmina senior

L'istruzione if ha due semplici condizioni:

genere == "Femmina" determina se una persona è una donna e

età> = 65 determina se quella persona è un cittadino anziano.

La semplice condizione a sinistra dell'operatore e valuta per prima perché == ha


precedenza maggiore di e. Se necessario, la semplice condizione a destra di e
valuta dopo, perché> = ha una precedenza maggiore di e. (Discuteremo a breve perché
il lato destro di un operatore and valuta solo se il lato sinistro è True.) L'intero if
la condizione dell'istruzione è vera se e solo se entrambe le condizioni semplici sono vere. Il
la condizione combinata può essere resa più chiara aggiungendo parentesi ridondanti

lecca qui per visualizzare l'immagine del codice

(sesso == 'Femmina' ) e (età> = 65 )

La tabella seguente riassume l'operatore e mostrando tutti e quattro i possibili

C
combinazioni di valori False e True per expression1 e expression2: tali tabelle Pagina 119
sono chiamate tabelle di verità :

espressione1 espressione2 espressione1 ed espressione2

Falso Falso Falso

Falso Vero Falso

Vero Falso Falso

Vero Vero Vero

Operatore booleano o

Utilizzare l' operatore booleano o per verificare se una o entrambe le due condizioni sono vere.
Il codice seguente verifica una condizione True se una o entrambe le condizioni semplici lo sono

Vero: l'intera condizione è Falso solo se entrambe le condizioni semplici sono False:

lecca qui per visualizzare l'immagine del codice

In [4]: ​semester_average = 83

In [5]: final_exam = 95

In [6]: se semester_average> = 90 o final_exam> = 90 :


...: print ( 'Lo studente riceve una A' )
...:
Lo studente ottiene un A

Lo snippet [6] contiene anche due semplici condizioni:

semester_average> = 90 determina se la media di uno studente era un A (90


o superiore) durante il semestre, e

C
Pagina 120
final_exam> = 90 determina se il voto finalexam di uno studente era un A.

La tabella di verità di seguito riepiloga l'operatore booleano o. Operatore e ha una maggiore


precedenza rispetto a o.

espressione1 espressione2 espressione1 o espressione2

Falso Falso Falso

Falso Vero Vero


Vero Falso Vero

Vero Vero Vero

Miglioramento delle prestazioni con la valutazione del cortocircuito

Python smette di valutare un'espressione and non appena sa se l'intero file


condizione è False. Allo stesso modo, Python smette di valutare un'espressione o non appena questa
sa se l'intera condizione è vera. Questa è chiamata valutazione del cortocircuito . Così
la condizione

lecca qui per visualizzare l'immagine del codice

sesso == "Femmina" ed età> = 65

smette di valutare immediatamente se il sesso non è uguale a 'Femmina' perché il tutto


l'espressione deve essere False. Se il sesso è uguale a "Femmina", l'esecuzione continua,
perché l'intera espressione sarà True se l'età è maggiore o uguale a 65.

Allo stesso modo, la condizione

C
Pagina 121
lecca qui per visualizzare l'immagine del codice

semester_average> = 90 o final_exam> = 90

interrompe la valutazione immediatamente se semester_average è maggiore o uguale a 90


perché l'intera espressione deve essere True. Se semester_average è inferiore a 90,
l'esecuzione continua, perché l'espressione potrebbe essere ancora True se final_exam lo è

maggiore o uguale a 90.

Nelle espressioni che usano e, rendere la condizione che è più probabile sia False il

condizione più a sinistra. Nelle espressioni dell'operatore o, crea la condizione che è più probabile
essere True la condizione più a sinistra. Queste tecniche possono ridurre l'esecuzione di un programma
tempo.

Operatore booleano no

L' operatore booleano non "inverte" il significato di una condizione: True diventa

False and False diventa True. Questo è un operatore unario: ha un solo operando.
Metti l'operatore not prima di una condizione per scegliere un percorso di esecuzione se il file
la condizione originale (senza l'operatore not) è False, come nel codice seguente:

lecca qui per visualizzare l'immagine del codice

In [7]: voto = 87

In [8]: se non voto == 1 :


...: print ( 'Il voto successivo è' , voto)
...:
Il grado successivo è 87
Spesso si può evitare di utilizzare not esprimendo la condizione in modo più “naturale” o
modo conveniente. Ad esempio, l'istruzione if precedente può anche essere scritta come
segue:

lecca qui per visualizzare l'immagine del codice

In [9]: se voto! = 1 :
...: print ( 'Il voto successivo è' , voto)
...:
Il grado successivo è 87

C
Pagina 122
La tabella di verità di seguito riassume l'operatore not.

espressione non espressione

Falso Vero

Vero Falso

La tabella seguente mostra la precedenza e il raggruppamento degli operatori così introdotti


lontano, dall'alto verso il basso, in ordine decrescente di precedenza.

Operatori Raggruppamento

() da sinistra a destra

** da destra a sinistra

* / //% da sinistra a destra

+ da sinistra a destra

<<=>> = ==! = da sinistra a destra

non da sinistra a destra

T
e da sinistra a destra Pagina 123

o da sinistra a destra

3.14 INTRO A DATA SCIENCE: MISURE DI


TENDENZA CENTRALE: MEDIA, MEDIA E MODO
Qui continuiamo la nostra discussione sull'utilizzo delle statistiche per analizzare i dati con diversi
statistiche descrittive aggiuntive, tra cui:

media: il valore medio in un insieme di valori.

mediana: il valore medio quando tutti i valori sono disposti in ordine ordinato .

modalità: il valore che si verifica più di frequente .

Queste sono misure di tendenza centrale: ciascuna è un modo per produrre un singolo valore
che rappresenta un valore "centrale" in un insieme di valori, cioè un valore che è in un certo senso
tipico degli altri.

Calcoliamo la media, la mediana e il modo su un elenco di numeri interi. La sessione successiva


crea un elenco chiamato voti, quindi utilizza le funzioni incorporate sum e len per il calcolo
la media "a mano": la somma calcola il totale dei voti (397) e len restituisce il
numero di voti (5):

lecca qui per visualizzare l'immagine del codice

In [1]: voti = [ 85 , 93 , 45 , 89 , 85 ]

In [2]: somma (voti) / len (voti)


Uscita [2]: 79,4

Il capitolo precedente ha menzionato il conteggio e la somma delle statistiche descrittive:


implementato in Python come funzioni incorporate len e sum. Come le funzioni min e

max (introdotto nel capitolo precedente), sum e len sono entrambi esempi di
riduzioni della programmazione in stile funzionale: riducono una raccolta di valori a
valore singolo: la somma di questi valori e il numero di valori, rispettivamente. Nel ezione

C
S
Pagina 124
Nell'esempio della media della classe .8 , avremmo potuto eliminare le righe 10-15 dello script e
ha sostituito la media nella riga 16 con il calcolo dello snippet [2].

Il modulo delle statistiche della libreria standard Python fornisce funzioni per
calcolare la media, la mediana e il modo: anche queste sono riduzioni. Per usarli
funzionalità, prima importa il modulo delle statistiche:

In [3]: statistiche sulle importazioni

Quindi, puoi accedere alle funzioni del modulo con "statistiche". seguito dal
nome della funzione da chiamare. Quanto segue calcola la media dell'elenco dei voti, mediana
e modalità, utilizzando le funzioni media , mediana e modalità del modulo statistiche :

lecca qui per visualizzare l'immagine del codice


In [4]: ​statistics.mean (voti)
Uscita [4]: ​79,4

In [5]: statistics.median (voti)


Uscita [5]: 85

In [6]: statistics.mode (voti)


Uscita [6]: 85

L'argomento di ciascuna funzione deve essere un iterabile, in questo caso l'elenco valuta. Per confermare
che la mediana e la modalità siano corrette, puoi usare la funzione ordinata incorporata per ottenere
una copia dei voti con i suoi valori disposti in ordine crescente:

In [7]: ordinato (voti)


Uscita [7]: [45, 85, 85, 89, 93]

L'elenco dei voti ha un numero dispari di valori (5), quindi la mediana restituisce il valore medio
(85). Se il numero di valori dell'elenco è pari, mediana restituisce la media dei due
valori medi. Studiando i valori ordinati, puoi vedere che 85 è la modalità perché
si verifica più frequentemente (due volte). La funzione mode causa un'eccezione StatisticsError per
elenchi come

[ 85 , 93 , 45 , 89 , 85 , 93 ]

in cui sono presenti due o più valori “più frequenti”. Si dice che un tale insieme di valori sia

3C
Pagina 125
imodal . Qui, sia 85 che 93 si verificano due volte.

3.15 WRAP-UP
In questo capitolo, abbiamo discusso le istruzioni di controllo di Python, incluso if, if ... else,

if ... elif ... else, while, for, break and continue. Hai visto che il per
l'istruzione esegue l'iterazione controllata dalla sequenza: elabora ogni elemento in un file
iterabile, come un intervallo di numeri interi, una stringa o un elenco. Hai usato la funzione incorporata
intervallo per generare sequenze di numeri interi da 0 fino a, ma escluso, il suo argomento,
e per determinare quante volte un'istruzione for itera.

Hai usato l'iterazione controllata da sentinella con l'istruzione while per creare un ciclo che
continua l'esecuzione fino a quando non viene rilevato un valore sentinella. Hai usato la funzione incorporata
la versione a due argomenti dell'intervallo per generare sequenze di numeri interi dal primo
il valore dell'argomento fino al valore del secondo argomento, ma escluso. Hai anche usato
la versione a tre documenti in cui il terzo argomento indicava il passaggio tra
numeri interi in un intervallo.

Abbiamo introdotto il tipo Decimale per calcoli monetari precisi e lo abbiamo utilizzato
calcolare l'interesse composto. Hai usato fstrings e vari specificatori di formato per creare
output formattato. Abbiamo introdotto le istruzioni break e continue per modificare il file
flusso di controllo in loop. Abbiamo discusso degli operatori booleani and, or and not for
creando condizioni che combinano condizioni semplici.

Infine, abbiamo continuato la nostra discussione sulle statistiche descrittive introducendo misure di
tendenza centrale - media, mediana e modo - e calcolandoli con funzioni da
il modulo delle statistiche della Python Standard Library.
Nel prossimo capitolo, creerai funzioni personalizzate e utilizzerai funzioni esistenti da
Matematica di Python e moduli casuali. Mostriamo diversi funzionali predefiniti
riduzioni della programmazione e vedrai una programmazione funzionale aggiuntiva
capacità.

https://avxhm.se/blogs/hill0

b
Pagina 126

laylist

storia . Funzioni
Obiettivi
opiche

In questo capitolo, tu
guadagnando Pat

Crea funzioni personalizzate.


ffers & Dea

Importa e utilizza i moduli della libreria standard Python, come random e math, in
ighlights
riutilizza il codice ed evita di "reinventare la ruota".

ettingsPassa i dati tra le funzioni.

Supporto
Genera un intervallo di numeri casuali.

Disconnessione
Vedi le tecniche di simulazione che utilizzano la generazione di numeri casuali.

Semina il generatore di numeri casuali per garantire la riproducibilità.

Comprimere i valori in una tupla e decomprimere i valori da una tupla.

Restituisce più valori da una funzione tramite una tupla.

Comprendi come l'ambito di un identificatore determina dove puoi utilizzare nel tuo programma
esso.

Crea funzioni con valori di parametro predefiniti.

Chiama funzioni con argomenti di parole chiave.

Crea funzioni che possono ricevere un numero qualsiasi di argomenti.

Usa i metodi di un oggetto.

Scrivi e usa una funzione ricorsiva.

4
Contorno Pagina 127

.1 Introduzione

.2 Definizione delle funzioni

.3 Funzioni con più parametri

.4 Generazione RandomNumber

.5 Case Study: Un gioco d'azzardo

.6 Libreria standard Python

.7 Funzioni del modulo matematico

.8 Utilizzo del completamento della scheda IPython per il rilevamento

.9 Valori dei parametri predefiniti

.10 Argomenti delle parole chiave

.11 Elenchi di argomenti arbitrari

.12 Metodi: funzioni che appartengono agli oggetti

.13 Regole di ambito

.14 import: uno sguardo più approfondito

.15 Passaggio di argomenti alle funzioni: uno sguardo più approfondito

.16 Ricorsione

.17 Programmazione FunctionalStyle

.18 Introduzione alla scienza dei dati: misure di dispersione

.19 WrapUp

4.1 INTRODUZIONE

4
Pagina 128
In questo capitolo, continuiamo la nostra discussione sui fondamenti di Python con custom
funzioni e argomenti correlati. Useremo il modulo random della Python Standard Library
e la generazione di numeri casuali per simulare il lancio di un dado a sei facce. Ci uniremo
funzioni personalizzate e generazione di numeri casuali in uno script che implementa i dadi
gioco di dadi. In questo esempio, introdurremo anche il tipo e l'uso di sequenza di tupla di Python
tuple per restituire più di un valore da una funzione. Discuteremo di seeding del casuale
generatore di numeri per garantire la riproducibilità.

Importerai il modulo matematico della libreria standard Python, quindi lo userai per saperne di più
Completamento della scheda IPython, che accelera i processi di codifica e rilevamento. Tu
creare funzioni con valori di parametro predefiniti, chiamare funzioni con argomenti di parole chiave
e definire funzioni con elenchi di argomenti arbitrari. Mostreremo i metodi di chiamata
di oggetti. Discuteremo anche di come l'ambito di un identificatore determina dove nel tuo
programma puoi usarlo.
Daremo uno sguardo più approfondito all'importazione di moduli. Vedrai che gli argomenti sono passati
riferimento alle funzioni. Dimostreremo anche una funzione ricorsiva e inizieremo
presentando le capacità di programmazione in stile funzionale di Python.

Nella sezione Introduzione alla scienza dei dati, continueremo la nostra discussione sul descrittivo
statistiche introducendo misure di dispersione (varianza e deviazione standard) e
calcolandoli con funzioni tratte dalle statistiche della Python Standard Library
modulo.

4.2 DEFINIZIONE DELLE FUNZIONI


Hai chiamato molte funzioni incorporate (int, float, print, input, type, sum, len,

min e max) e alcune funzioni dal modulo statistiche (media, mediana e


modalità). Ciascuno ha svolto un singolo compito ben definito. Spesso definirai e chiamerai personalizzato
funzioni. La sessione seguente definisce una funzione quadrata che calcola il quadrato di
il suo argomento. Quindi chiama la funzione due volte, una per quadrare il valore int 7
(producendo il valore int 49) e una volta per quadrare il valore float 2.5 (producendo il

valore float 6.25):

lecca qui per visualizzare l'immagine del codice

In [1]: def quadrato (numero):


...: "" "Calcola il quadrato del numero." ""
...: numero di ritorno ** 2
...:

In [2]: quadrato ( 7 ) Pagina 129


Uscita [2]: 49

In [3]: quadrato ( 2.5 )


Uscita [3]: 6.25

Le istruzioni che definiscono la funzione nel primo frammento vengono scritte una sola volta, ma possono
essere chiamato "a fare il proprio lavoro" da molti punti durante il programma e tutte le volte che si
piace. La chiamata di square con un argomento non numerico come "hello" causa un'eccezione TypeError
perché l'operatore di esponenziazione (**) funziona solo con valori numerici.

Definizione di una funzione personalizzata


Una definizione di funzione (come il quadrato nello snippet [1]) inizia con la parola chiave def ,
seguito dal nome della funzione (quadrato), un insieme di parentesi e due punti (:). Piace
identificatori di variabili, per convenzione i nomi delle funzioni dovrebbero iniziare con una lettera minuscola
e nei nomi composti da più parole, i trattini bassi dovrebbero separare ogni parola.

Le parentesi obbligatorie contengono l' elenco dei parametri della funzione, separati da virgole
elenco di parametri che rappresentano i dati di cui la funzione ha bisogno per svolgere il proprio compito.
La funzione quadrato ha un solo parametro denominato numero: il valore da quadrare. Se
le parentesi sono vuote, la funzione non utilizza parametri per svolgere il proprio compito.

Le linee rientrate dopo i due punti (:) sono il blocco della funzione , che consiste in un
docstring facoltativo seguito dalle istruzioni che eseguono il compito della funzione. Bene
sottolinea subito la differenza tra il blocco di una funzione e la suite di un'istruzione di controllo.

Specificare la docstring di una funzione personalizzata

La Guida allo stile per il codice Python dice che la prima riga in un blocco di funzione dovrebbe essere un file
docstring che spiega brevemente lo scopo della funzione:

"" "Calcola il quadrato del numero." ""

Per fornire maggiori dettagli, puoi utilizzare una docstring su più righe, consigliato dalla guida allo stile
iniziando con una breve spiegazione, seguita da una riga vuota e dai dettagli aggiuntivi.

Restituzione di un risultato al chiamante di una funzione

Quando una funzione termina l'esecuzione, restituisce il controllo al suo chiamante, ovvero la riga di
codice che ha chiamato la funzione. Nel blocco di square, l' istruzione return :

Pagina 130
numero di ritorno ** 2

il primo numero di quadrati, quindi termina la funzione e restituisce il risultato a


chiamante. In questo esempio, il primo chiamante è nello snippet [2], quindi IPython mostra il risultato
in Out [2]. Il secondo chiamante è nello snippet [3], quindi IPython mostra il risultato in

Fuori [3].

Le chiamate di funzione possono anche essere incorporate nelle espressioni. Il codice seguente chiama square
prima, poi stampa mostra il risultato:

lecca qui per visualizzare l'immagine del codice

In [4]: ​print ( 'Il quadrato di 7 è' , quadrato ( 7 ))


Il quadrato del 7 è 49

Esistono altri due modi per restituire il controllo da una funzione al suo chiamante:

L'esecuzione di un'istruzione return senza un'espressione termina la funzione e


restituisce implicitamente il valore None al chiamante. La documentazione di Python afferma
che Nessuno rappresenta l'assenza di un valore. Nessuno restituisce False nelle condizioni.

Quando non c'è un'istruzione return in una funzione, restituisce implicitamente il valore

Nessuno dopo aver eseguito l'ultima istruzione nel blocco della funzione.

Variabili locali
Sebbene non abbiamo definito le variabili nel blocco di square, è possibile farlo. UN

i parametri e le variabili della funzione definiti nel suo blocco sono tutte variabili locali: esse
può essere utilizzato solo all'interno della funzione ed esiste solo mentre la funzione è in esecuzione.
Il tentativo di accedere a una variabile locale al di fuori del blocco della sua funzione provoca un NameError,
indicando che la variabile non è definita.

Accesso alla docstring di una funzione tramite il meccanismo di aiuto di IPython

IPython può aiutarti a conoscere i moduli e le funzioni che intendi utilizzare nel tuo
codice, così come IPython stesso. Ad esempio, per visualizzare la docstring di una funzione per sapere come
per utilizzare la funzione, digita il nome della funzione seguito da un punto interrogativo (?) :

lecca qui per visualizzare l'immagine del codice

C
Pagina 131
In [5]: quadrato?
Firma: quadrato (numero)
Docstring: Calcola il quadrato del numero.
File: ~ / Documents / examples / ch04 / <ipythoninput17268c8ff93a9>
Tipo: funzione

Per la nostra funzione quadrata, le informazioni visualizzate includono:

Il nome della funzione e l'elenco dei parametri, noto come firma .

La docstring della funzione.

Il nome del file contenente la definizione della funzione. Per una funzione in un file
sessione interattiva, questa riga mostra le informazioni per lo snippet che ha definito il file
funzione: l'1 in "<ipythoninput17268c8ff93a9>" significa snippet [1].

Il tipo di elemento per il quale si accede al meccanismo di aiuto di IPython, in questo caso,
una funzione.

Se il codice sorgente della funzione è accessibile da IPython, come una funzione definita in
la sessione corrente o importata nella sessione da un file .py: puoi utilizzare ?? per
visualizzare la definizione completa del codice sorgente della funzione:

lecca qui per visualizzare l'immagine del codice

In [6]: quadrato ??
Firma: quadrato (numero)
Fonte:
def quadrato (numero):
"" "Calcola il quadrato del numero." ""
numero di ritorno ** 2
File: ~ / Documents / examples / ch04 / <ipythoninput17268c8ff93a9>
Tipo: funzione

Se il codice sorgente non è accessibile da IPython, ?? mostra semplicemente la docstring.

Se la docstring si adatta alla finestra, IPython visualizza il successivo prompt In []. Se una
docstring è troppo lungo per adattarsi, IPython indica che c'è di più visualizzando i due punti (:)
nella parte inferiore della finestra: premere il tasto Spazio per visualizzare la schermata successiva. Puoi
navigare avanti e indietro attraverso la docstring con la freccia su e giù
tasti, rispettivamente. IPython mostra (END) alla fine della docstring. Premere q (per
"Quit") in qualsiasi: o al prompt (END) per tornare al prompt In [] successivo. Prendere un

C
Pagina 132
senso delle caratteristiche di IPython, tipo? in qualsiasi prompt di In [], premere Invio , quindi leggere il file
guida panoramica della documentazione.

4.3 FUNZIONI CON PARAMETRI MULTIPLI


Definiamo una funzione di massimo che determina e restituisce il più grande di tre valori

—La sessione seguente chiama la funzione tre volte con numeri interi, virgola mobile
rispettivamente numeri e stringhe.

lecca qui per visualizzare l'immagine del codice

In [1]: def massimo (valore1, valore2, valore3):


...: "" "Restituisce il massimo di tre valori." ""
...: valore_max = valore1
...: se valore2> valore_max:
...: valore_max = valore2
...: se valore3> valore_max:
...: valore_max = valore3
...: restituisce max_value
...:

In [2]: massimo ( 12 , 27 , 36 )
Fuori [2]: 36

In [3]: massimo ( 12.3 , 45.6 , 9.7 )


Uscita [3]: 45.6

In [4]: ​massimo ( "giallo" , "rosso" , "arancione" )


Fuori [4]: ​"giallo"

Non abbiamo inserito righe vuote sopra e sotto le istruzioni if, perché premendo
ritorno su una riga vuota in modalità interattiva completa la definizione della funzione.

Puoi anche chiamare il massimo con tipi misti, come int e float:

In [5]: massimo ( 13,5 , 3 , 7 )


Fuori [5]: 13.5

La chiamata massima (13.5, 'hello', 7) risulta in TypeError perché le stringhe e


i numeri non possono essere confrontati tra loro con l'operatore maggiore di (>).

Definizione della funzione massima

La funzione massima specifica tre parametri in un elenco separato da virgole. Snippet [2]

C
Pagina 133
gli argomenti 12, 27 e 36 sono assegnati ai parametri valore1, valore2 e

valore3, rispettivamente.

Per determinare il valore più grande, elaboriamo un valore alla volta:

Inizialmente, assumiamo che value1 contenga il valore più grande, quindi lo assegniamo a
variabile locale max_value. Naturalmente, è possibile che value2 o value3 contengano
il valore più grande effettivo, quindi dobbiamo ancora confrontare ciascuno di questi con max_value.

La prima istruzione if quindi verifica value2> max_value e se questa condizione è

True assegna valore2 a max_value.

La seconda istruzione if verifica quindi value3> max_value e se questa condizione è

True assegna value3 a max_value.

Ora, max_value contiene il valore più grande, quindi lo restituiamo. Quando il controllo ritorna a
il chiamante, i parametri value1, value2 e value3 e la variabile max_value
nel blocco della funzione, che sono tutte variabili locali, non esistono più.

Funzioni max e min integrate di Python

Per molte attività comuni, le capacità di cui hai bisogno esistono già in Python. Per
esempio, le funzioni incorporate max e min sanno come determinare il valore più grande e
il più piccolo dei loro due o più argomenti, rispettivamente:

lecca qui per visualizzare l'immagine del codice

In [6]: max ( "giallo" , "rosso" , "arancione" , "blu" , "verde" )


Fuori [6]: "giallo"

In [7]: min ( 15 , 9 , 27 , 14 )
Uscita [7]: 9

Ognuna di queste funzioni può anche ricevere un argomento iterabile, come un elenco o una stringa.
Utilizzo di funzioni incorporate o funzioni dai moduli della libreria standard di Python
piuttosto che scrivere il tuo può ridurre i tempi di sviluppo e aumentare il programma
affidabilità, portabilità e prestazioni. Per un elenco delle funzioni integrate di Python e
moduli, vedere

ttps: //docs.python.org/3/library/index.html

4hC .4 GENERAZIONE DI NUMERI CASUALI


Pagina 134
4.4 GENERAZIONE DI NUMERI CASUALI
Ora prendiamo una breve deviazione in un tipo popolare di applicazione di programmazione—
simulazione e gioco. Puoi introdurre l' elemento del caso tramite
Modulo casuale della libreria standard di Python .

Lancio di un dado a sei facce

Produciamo 10 numeri interi casuali nell'intervallo 1-6 per simulare il lancio di un dado a sei facce:

lecca qui per visualizzare l'immagine del codice

In [1]: importa casuale

In [2]: in rotolo in serie ( 10 ):


...: print (random.randrange ( 1 , 7 ), end = '' )
...:
4255464615

Per prima cosa, importiamo random in modo da poter utilizzare le capacità del modulo. Il randrange
la funzione genera un numero intero dal primo valore dell'argomento fino al, ma non incluso, il
secondo valore di argomento. Usiamo quindi il tasto freccia su per richiamare l'istruzione for
premere Invio per rieseguirlo. Si noti che vengono visualizzati valori diversi :

lecca qui per visualizzare l'immagine del codice

In [3]: in rotolo in serie ( 10 ):


...: print (random.randrange ( 1 , 7 ), end = '' )
...:
4545141465

A volte, potresti voler garantire la riproducibilità di una sequenza casuale, per


debugging, per esempio. Alla fine di questa sezione, useremo il seme del modulo casuale
funzione per fare questo.

Lanciare un dado a sei facce 6.000.000 di volte

Se randrange produce veramente numeri interi a caso, ogni numero nel suo intervallo ha un
uguale probabilità (o probabilità o probabilità ) di essere restituito ogni volta che lo chiamiamo. Per
mostrare che le facce 1–6 del dado si verificano con la stessa probabilità, simula il seguente script
6.000.000 di tiri di dado. Quando esegui lo script, ogni faccia della fustella dovrebbe apparire approssimativamente
1.000.000 di volte, come nell'output di esempio.

C
Pagina 135
lecca qui per visualizzare l'immagine del codice

1 # fig04_01.py
2 "" "Tira un dado a sei facce 6.000.000 di volte." ""
3 importazione casuale
4
5 # contatori di frequenza del viso
6 frequenza1 = 0
7 frequenza2 = 0
8 frequenza3 = 0
9 frequenza4 = 0
10 frequenza5 = 0
11 frequenza6 = 0
12
13 # 6.000.000 di dado
14 per roll in range ( 6_000_000 ): # nota i separatori di sottolineatura
15 face = random.randrange ( 1 , 7 )
16
17 # incrementa il contatore di volti appropriato
18 se faccia == 1 :
19 frequenza1 + = 1
20 elif face == 2:
21 frequenza2 + = 1
22 elif face == 3:
23 frequenza3 + = 1
24 elif face == 4:
25 frequenza4 + = 1
26 elif face == 5:
27 frequenza5 + = 1
28 elif face == 6:
29 frequenza6 + = 1
30
31 print (f 'Face { "Frequency" :> 13 } ' )
32 print (f ' { 1 :> 4 } {frequency1:> 13 } ' )
33 print (f ' { 2 :> 4 } {frequency2:> 13 } ' )
34 print (f ' { 3 :> 4 } {frequency3:> 13 } ' )
35 print (f ' { 4 :> 4 } {frequency4:> 13 } ' )
36 print (f ' { 5 :> 4 } {frequency5:> 13 } ' )
37 print (f ' { 6 :> 4 } {frequency6:> 13 } ' )

lecca qui per visualizzare l'immagine del codice

Frequenza del viso


1 998686
2 1001481
3 999900
4 1000453
5 999953
6 999527

C
Pagina 136
Lo script utilizza istruzioni di controllo annidate (un'istruzione if elif annidata nel file for
dichiarazione) per determinare il numero di volte in cui ogni faccia del dado appare. L'istruzione for
itera 6.000.000 di volte. Abbiamo usato il separatore di cifre di sottolineatura (_) di Python per creare il file
valore 6000000 più leggibile. L'intervallo di espressioni (6.000.000) sarebbe
sbagliato. Le virgole separano gli argomenti nelle chiamate di funzione, quindi Python tratterebbe
range (6.000.000) come chiamata a range con i tre argomenti 6, 0 e 0.

Per ogni tiro di dado, lo script aggiunge 1 alla variabile contatore appropriata. Corri il
programma e osservare i risultati. Il completamento di questo programma potrebbe richiedere alcuni secondi
esecuzione. Come vedrai, ogni esecuzione produce risultati diversi . Nota che non l'abbiamo fatto
fornire una clausola else nell'istruzione if elif.

Semina del generatore di numeri casuali per la riproducibilità


La funzione randrange genera effettivamente numeri pseudocasuali , basati su un file
calcolo interno che inizia con un valore numerico noto come seme . Ripetutamente
chiamare randrange produce una sequenza di numeri che sembrano essere casuali,
perché ogni volta che si avvia una nuova sessione interattiva o si esegue uno script che utilizza l'estensione
1
funzioni del modulo random, Python utilizza internamente un diverso valore seed . quando
stai eseguendo il debug di errori logici in programmi che utilizzano dati generati casualmente, può essere
utile usare la stessa sequenza di numeri casuali fino a quando non hai eliminato la logica
errori, prima di testare il programma con altri valori. Per fare ciò, puoi usare il
del modulo casuale seme funzione per inizializzare il generatore di RandomNumber da soli
-Questo forza randrange a iniziare a calcolare la sua sequenza numerica pseudocasuale da
il seme che specifichi. Nella sessione successiva, gli snippet [5] e [8] producono lo stesso
risultati, perché gli snippet [4] e [7] utilizzano lo stesso seme (32):

1
Secondo la documentazione, Python basa il valore seed sull'orologio di sistema o
una fonte di casualità dipendente dal sistema operativo. Per applicazioni che richiedono sicurezza
numeri casuali, come la crittografia, la documentazione consiglia di utilizzare l'estensione
modulo segreti, piuttosto che il modulo casuale.

lecca qui per visualizzare l'immagine del codice

In [4]: ​random.seed ( 32 )

In [5]: per rotolo in serie ( 10 ):


...: print (random.randrange ( 1 , 7 ), end = '' )
...:
1223624161
In [6]: in rotolo in serie ( 10 ):
...: print (random.randrange ( 1 , 7 ), end = '' )

...: Pagina 137


1353156435
In [7]: random.seed ( 32 )

In [8]: per rotolo in serie ( 10 ):


...: print (random.randrange ( 1 , 7 ), end = '' )
...:
1223624161

Snippet [6] genera valori diversi perché continua semplicemente lo pseudocasuale


sequenza numerica iniziata nello snippet [5].

4.5 CASO DI STUDIO: UN GIOCO DI CASE


In questa sezione, simuliamo il popolare gioco di dadi noto come "craps". Ecco il file
dichiarazione dei requisiti:

Tiri due dadi a sei facce, ciascuna con facce contenenti uno, due, tre, quattro, cinque e
sei punti, rispettivamente. Quando i dadi si fermano, la somma dei punti sui due
vengono calcolate le facce verso l'alto. Se la somma è 7 o 11 al primo tiro, vinci. Se la somma è
2, 3 o 12 al primo lancio (chiamato "craps"), perdi (cioè, la "casa" vince). Se la somma è
4, 5, 6, 8, 9 o 10 al primo tiro, quella somma diventa il tuo "punto". Per vincere, devi
continuare a tirare i dadi fino a quando non "ottieni il tuo punto" (cioè, tira lo stesso valore in punti).
Perdi tirando un 7 prima di raggiungere il tuo punto.

Il seguente script simula il gioco e mostra diverse esecuzioni di esempio,


illustrando la vittoria al primo lancio, la sconfitta al primo lancio, la vittoria al successivo
rotolare e perdere in un tiro successivo.
lecca qui per visualizzare l'immagine del codice

1 # fig04_02.py
2 "" "Simula il gioco dei dadi Craps." ""
3 importazione casuale
4
5 def roll_dice ():
6 "" "Lancia due dadi e restituisci i loro valori nominali come una tupla." ""
7 die1 = random.randrange ( 1 , 7 )
8 die2 = random.randrange ( 1 , 7 )
9 return (die1, die2) # racchiude i valori nominali del dado in una tupla
10
11 def display_dice (dice):
12 "" "Mostra un lancio dei due dadi." ""
13 die1, die2 = dice # scompatta la tupla nelle variabili die1 e die2
14 print (f 'Player rolled {die1} + {die2} = {sum (dice)} ' )

15 Pagina 138
16 die_values ​= roll_dice () # primo lancio
17 display_dice (die_values)
18
19 # determina lo stato e il punteggio del gioco, in base al primo tiro
20 sum_of_dice = sum (die_values)
21
22 if sum_of_dice in ( 7 , 11 ): # win
23 game_status = ' VINTO '
24 elif sum_of_dice in ( 2 , 3 , 12 ): # perde
25 game_status = 'LOST'
26 else : # ricorda il punto
27 game_status = 'CONTINUA'
28 my_point = sum_of_dice
29 print ( 'Point is' , my_point)
30
31 # continua a tirare finché il giocatore non vince o perde
32 while game_status == 'CONTINUA' :
33 die_values ​= roll_dice ()
34 display_dice (die_values)
35 sum_of_dice = sum (die_values)
36
37 if sum_of_dice == my_point: # vinci guadagnando punti
38 game_status = ' VINTO '
39 elif sum_of_dice == 7: # perde tirando 7
40 game_status = 'LOST'
41
42 # visualizza il messaggio "vince" o "perde"
43 se game_status == 'WON':
44 print ( 'Il giocatore vince' )
45 altro :
46 print ( 'Player perde' )

lecca qui per visualizzare l'immagine del codice

Il giocatore ha ottenuto 2 + 5 = 7
Il giocatore vince

lecca qui per visualizzare l'immagine del codice

Il giocatore ha ottenuto 1 + 2 = 3
Il giocatore perde

lecca qui per visualizzare l'immagine del codice

C
Pagina 139
Il giocatore ha ottenuto 5 + 4 = 9
Il punto è 9
Il giocatore ha ottenuto 4 + 4 = 8
Il giocatore ha ottenuto 2 + 3 = 5
Il giocatore ha ottenuto 5 + 4 = 9
Il giocatore vince

lecca qui per visualizzare l'immagine del codice

Il giocatore ha ottenuto 1 + 5 = 6
Il punto è 6
Il giocatore ha ottenuto 1 + 6 = 7
Il giocatore perde

Funzione roll_dice: restituzione di più valori tramite una tupla

La funzione roll_dice (righe 5–9) simula il lancio di due dadi a ogni lancio. La funzione
viene definito una volta, quindi richiamato da più punti del programma (righe 16 e 33). Il
un elenco di parametri vuoto indica che roll_dice non richiede argomenti per l'esecuzione
il suo compito.

Le funzioni incorporate e personalizzate che hai chiamato finora restituiscono ciascuna un valore.
A volte è utile restituire più di un valore, come in roll_dice, che restituisce
entrambi i valori die (linea 9) come tupla -an immutabili (cioè non modificabili) sequenze
di valori. Per creare una tupla, separa i suoi valori con virgole, come nella riga 9:

(die1, die2)

Questo è noto come impacchettare una tupla . Le parentesi sono facoltative, ma consigliamo
usandoli per chiarezza. Discuteremo approfonditamente le tuple nel prossimo capitolo.

Funzione display_dice

Per utilizzare i valori di una tupla, puoi assegnarli a un elenco di variabili separato da virgole,
che decomprime la tupla. Per visualizzare ogni lancio di dadi, la funzione display_dice
(definito nelle righe 11-14 e chiamato nelle righe 17 e 34) decomprime l'argomento della tupla it
riceve (riga 13). Il numero di variabili a sinistra di = deve corrispondere al numero di
elementi nella tupla; in caso contrario, si verifica un'eccezione ValueError. La riga 14 stampa un file formattato
stringa contenente sia i valori del dado che la loro somma. Calcoliamo la somma dei dadi di

C
Pagina 140
passando la tupla alla funzione di somma incorporata: come una lista, una tupla è una sequenza.

Notare che le funzioni roll_dice e display_dice iniziano ciascuna i propri blocchi con un
docstring che indica cosa fa la funzione. Inoltre, entrambe le funzioni contengono variabili locali
die1 e die2. Queste variabili non "entrano in collisione", perché appartengono a differenti
blocchi di funzioni. Ogni variabile locale è accessibile solo nel blocco che l'ha definita.

Primo tiro

Quando lo script inizia l'esecuzione, le righe 16-17 lanciano i dadi e visualizzano i risultati. Linea
20 calcola la somma dei dadi da utilizzare nelle righe 22-29. Puoi vincere o perdere al primo
rotolo o qualsiasi rotolo successivo. La variabile game_status tiene traccia della vittoria / sconfitta
stato.
L' operatore in linea 22

sum_of_dice in ( 7 , 11 )

verifica se la tupla (7, 11) contiene il valore di sum_of_dice. Se questa condizione è

È vero, hai ottenuto un 7 o un 11. In questo caso, hai vinto al primo tiro, quindi il copione si imposta
game_status su "WON". L'operando destro dell'operatore può essere qualsiasi iterabile. C'è anche
un operatore non in per determinare se un valore non è in un iterabile. Il precedente
condizione concisa è equivalente a

lecca qui per visualizzare l'immagine del codice

(sum_of_dice == 7 ) o (sum_of_dice == 11 )

Allo stesso modo, la condizione nella riga 24

sum_of_dice in ( 2 , 3 , 12 )

verifica se la tupla (2, 3, 12) contiene il valore di sum_of_dice. Se è così, hai perso
il primo tiro, quindi lo script imposta game_status su "LOST".

Per qualsiasi altra somma dei dadi (4, 5, 6, 8, 9 o 10):

la riga 27 imposta game_status su "CONTINUE" in modo che tu possa continuare a scorrere

C
Pagina 141
la riga 28 memorizza la somma dei dadi in my_point per tenere traccia di ciò che devi tirare
vincere e

la riga 29 mostra my_point.

Rotoli successivi

Se game_status è uguale a "CONTINUE" (riga 32), non hai vinto o perso, quindi il

while la suite dell'istruzione (righe 33–40) viene eseguita. Ogni iterazione del ciclo chiama roll_dice,
visualizza i valori della fustella e calcola la loro somma. Se sum_of_dice è uguale a my_point
(riga 37) o 7 (riga 39), lo script imposta game_status su "WON" o "LOST",
rispettivamente, e il ciclo termina. In caso contrario, il ciclo while continua l'esecuzione
con il prossimo tiro.

Visualizzazione dei risultati finali

Quando il ciclo termina, lo script passa all'istruzione if else (righe 43-46),


che stampa "Player wins" se game_status è "WON" o "Player perde"
altrimenti.

4.6 LIBRERIA STANDARD PYTHON


In genere, scrivi programmi Python combinando funzioni e classi (ovvero,
tipi personalizzati) che crei con funzioni e classi preesistenti definite in
moduli, come quelli nella libreria standard Python e altre librerie. Una chiave
l'obiettivo della programmazione è evitare di "reinventare la ruota".

Un modulo è un file che raggruppa funzioni, dati e classi correlati. Il tipo Decimal
dal modulo decimale della libreria standard Python è in realtà una classe. Abbiamo introdotto
classi brevemente in capitolo 1 e discuterli in dettaglio in "ObjectOriented
Capitolo "Programmazione". Un pacchetto raggruppa i moduli correlati. In questo libro lavorerai
con molti moduli e pacchetti preesistenti e creerai i tuoi moduli - in formato
infatti, ogni file codice sorgente Python (.py) che crei è un modulo. La creazione di pacchetti è
oltre lo scopo di questo libro. Sono tipicamente usati per organizzare una grande biblioteca
funzionalità in sottoinsiemi più piccoli che sono più facili da mantenere e possono essere importati
separatamente per comodità. Ad esempio, la libreria di visualizzazione matplotlib che abbiamo

utilizzare in
la sezione 5.17 ha funzionalità estese (la sua documentazione è di oltre 2300 pagine),
quindi importeremo solo i sottoinsiemi di cui abbiamo bisogno nei nostri esempi (pyplot e animazione).

La libreria standard Python viene fornita con il linguaggio Python di base. I suoi pacchetti
2
ei moduli contengono funzionalità per un'ampia varietà di attività di programmazione quotidiane.

C
S
Pagina 142
Puoi vedere un elenco completo dei moduli della libreria standard su

2
Il tutorial di Python si riferisce a questo come l'approccio incluso nelle batterie.

ttps: //docs.python.org/3/library/

Hai già utilizzato funzionalità dal decimale, statistica e casuale


moduli. Nella sezione successiva, utilizzerai le capacità matematiche della matematica
modulo. Vedrai molti altri moduli della libreria standard Python in tutto il libro
esempi, inclusi molti di quelli nella tabella seguente:

Alcuni popolari moduli della libreria standard Python

math: costanti matematiche comuni


e operazioni.

os: interazione con l'operatore


collezioni: strutture dati
sistema.
oltre a liste, tuple, dizionari e
imposta.
profilo, pstats, timeit—
Analisi di performance.
Moduli di crittografia: crittografia
dati per una trasmissione sicura.
casuale: numeri pseudocasuali.

csv: elaborazione separata da virgole


re: espressioni regolari per
file di valori (come quelli in Excel).
corrispondenza del modello.

datetime: data e ora


sqlite3: relazionale SQLite
manipolazioni. Anche il tempo dei moduli
accesso al database.
e calendario.

statistica: matematica
decimale: virgola fissa e virgola mobile
funzioni statistiche come media,
aritmetica dei punti, inclusa quella monetaria
mediana, modo e varianza.
calcoli.

string: elaborazione delle stringhe.


doctest: include test di convalida
e risultati attesi in docstrings per
sys: argomento della riga di comando
semplice unit test.
hY
Pagina 143
gettext e locale— elaborazione; input standard,
Internazionalizzazione e localizzazione output standard e standard
moduli. flussi di errore.

json: notazione dell'oggetto JavaScript tkinter: utente grafico


(JSON) elaborazione utilizzata con web interfacce (GUI) e basate su canvas
servizi e documento NoSQL grafica.
banche dati.
tartaruga: grafica della tartaruga.

browser web: per convenienza


visualizzazione di pagine web in Python
app.

4.7 FUNZIONI DEL MODULO MATEMATICO


Il modulo di matematica definisce le funzioni per eseguire varie operazioni matematiche comuni
calcoli. Ricordiamo dal capitolo precedente che un'istruzione import di
il modulo seguente consente di utilizzare le definizioni di un modulo tramite il nome del modulo e un file
punto (.):

In [1]: importa matematica

Ad esempio, lo snippet seguente calcola la radice quadrata di 900 chiamando la matematica


la funzione sqrt del modulo , che restituisce il risultato come valore float:

In [2]: math.sqrt ( 900 )


Uscita [2]: 30.0

Allo stesso modo, lo snippet seguente calcola il valore assoluto di 10 chiamando la matematica
la funzione fabs del modulo , che restituisce il risultato come valore float:

In [3]: math.fabs ( 10 )
Uscita [3]: 10.0

Alcune funzioni del modulo matematico sono riepilogate di seguito: è possibile visualizzare l'elenco completo all'indirizzo

Pagina 144
ttps: //docs.python.org/3/library/math.html

Funzione Descrizione Esempio

ceil (9.2) è
10.0
Arrotonda x al numero intero più piccolo non inferiore
ceil ( x )
di x
ceil (9.8) è
9.0
floor (9.2) è
9.0
Arrotonda x al numero intero più grande non maggiore
pavimento ( x )
di x
il pavimento (9.8) è
10.0

peccato ( x ) Seno trigonometrico di x ( x in radianti) sin (0,0) è 0,0

cos ( x ) Coseno trigonometrico di x ( x in radianti) cos (0,0) è 1,0

tan ( x ) Tangente trigonometrica di x ( x in radianti) tan (0,0) è 0,0

exp (1.0) è
2.718282
X
exp ( x ) Funzione esponenziale e
exp (2.0) è
7.389056

registro (2.718282)
è 1.0

Pagina 145
log ( x ) Logaritmo naturale di x (base e ) registro (7.389056)
è 2.0

log10 (10.0) è
1.0
log10 ( x ) Logaritmo di x (base 10)
log10 (100.0)
è 2.0

pow (2.0, 7.0)


è 128.0
pow ( x ,
x elevato alla potenza y ( x )
y)
pow (9.0, .5)
è 3.0

sqrt (900.0) è
30.0
sqrt ( x ) radice quadrata di x
sqrt (9.0) è
3.0
fabs (5.1) è
Valore assoluto di x: restituisce sempre un valore float.
5.1
Python ha anche la funzione incorporata abs,
fabs ( x )
che restituisce un int o un float, basato su
fabs (5.1) è
il suo argomento.
5.1

fmod ( x , fmod (9.8,


Resto di x / y come numero in virgola mobile
y) 4.0) è 1.8

4
y .8 UTILIZZO DEL COMPLETAMENTO DELLA SCHEDA IPYTHON PER LA DISCOVERY
Pagina 146
4.8 UTILIZZO DEL COMPLETAMENTO DELLA SCHEDA IPYTHON PER LA DISCOVERY
È possibile visualizzare la documentazione di un modulo in modalità interattiva IPython tramite tab
completamento: una funzione di rilevamento che accelera i processi di codifica e rilevamento.
Dopo aver digitato una parte di un identificatore e premuto Tab , IPython completa l'identificatore
per te o fornisce un elenco di identificatori che iniziano con ciò che hai digitato finora. Questo
può variare in base alla piattaforma del sistema operativo e a ciò in cui è stato importato
la tua sessione IPython:

lecca qui per visualizzare l'immagine del codice

In [1]: importa matematica

In [2]: ma <Tab>
map% macro %% markdown
math% magic% matplotlib
max ()% man

È possibile scorrere gli identificatori con i tasti freccia su e giù. Come fai tu,
IPython evidenzia un identificatore e lo mostra a destra del prompt In [].

Visualizzazione degli identificatori in un modulo

Per visualizzare un elenco di identificatori definiti in un modulo, digitare il nome del modulo e un punto (.),
quindi premere Tab :

lecca qui per visualizzare l'immagine del codice

In [3]: matematica. <Tab>


acos () atan () copysign () e expm1 ()
acosh () atan2 () cos () erf () fabs ()
asin () atanh () cosh () erfc () fattoriale ()>
asinh () ceil () gradi () exp () floor ()

Se ci sono più identificatori da visualizzare rispetto a quelli attualmente mostrati, IPython mostra il>
simbolo (su alcune piattaforme) sul bordo destro, in questo caso a destra del fattoriale ().
È possibile utilizzare i tasti freccia su e giù per scorrere l'elenco. Nell'elenco di
identificatori:

Quelle seguite da parentesi sono funzioni (o metodi, come vedrai più avanti).

Identificatori di parole singole (come Employee) che iniziano con una lettera maiuscola e
C
Pagina 147
identificatori multiparola in cui ogni parola inizia con una lettera maiuscola (come

CommissionEmployee) rappresentano i nomi delle classi (non ce ne sono nei precedenti


elenco). Questa convenzione di denominazione, consigliata dalla Guida allo stile per il codice Python ,
è noto come CamelCase perché le lettere maiuscole risaltano come quelle di un cammello
gobbe.

Identificatori minuscoli senza parentesi, come pi (non mostrato nel file precedente
list) ed e, sono variabili. L'identificatore pi restituisce 3,141592653589793 e
l'identificatore e restituisce 2,718281828459045. Nel modulo di matematica, pi ed e
rappresentano le costanti matematiche π ed e , rispettivamente.

Python non ha costanti , sebbene molti oggetti in Python siano immutabili


(non modificabile). Quindi, anche se pi ed e sono costanti del mondo reale, non devi
assegnare loro nuovi valori , perché ciò cambierebbe i loro valori. Per aiutare a distinguere
costanti da altre variabili, la guida allo stile consiglia di denominare il file personalizzato
costanti con tutte le lettere maiuscole.

Utilizzo della funzione attualmente evidenziata

Mentre navighi tra gli identificatori, se desideri utilizzare un file


, inizia semplicemente a digitare i suoi argomenti tra parentesi. IPython quindi nasconde il file
elenco di completamento automatico. Se hai bisogno di ulteriori informazioni sull'elemento attualmente evidenziato,
puoi visualizzare la sua docstring digitando un punto interrogativo (?) dopo il nome e
premendo Invio per visualizzare la documentazione della guida. Quanto segue mostra i fab
docstring della funzione:

lecca qui per visualizzare l'immagine del codice

In [4]: ​math.fabs?
Docstring:
fabs (x)

Restituisce il valore assoluto del float x.


Digita: builtin_function_or_method

Il builtin_function_or_method mostrato sopra indica che fabs fa parte di un file


Modulo Python Standard Library. Tali moduli sono considerati integrati in Python.
In questo caso, fabs è una funzione incorporata nel modulo math.

4.9 VALORI DEI PARAMETRI DI DEFAULT

C
Pagina 148
Quando si definisce una funzione, è possibile specificare che un parametro ha un parametro predefinito
valore . Quando si chiama la funzione, se si omette l'argomento di un parametro con estensione
valore del parametro predefinito, il valore predefinito per quel parametro viene passato automaticamente.
Definiamo una funzione rectangle_area con i valori dei parametri predefiniti:

lecca qui per visualizzare l'immagine del codice

In [1]: def rectangle_area (length = 2 , width = 3 ):


...: "" "Restituisce l'area di un rettangolo." ""
...: lunghezza di ritorno * larghezza
...:

Si specifica un valore di parametro predefinito seguendo il nome di un parametro con un = e a


valore: in questo caso, i valori dei parametri predefiniti sono 2 e 3 per lunghezza e larghezza,
rispettivamente. Tutti i parametri con valori di parametro predefiniti devono essere visualizzati nel file
elenco dei parametri a destra dei parametri che non hanno valori predefiniti.

La seguente chiamata a rectangle_area non ha argomenti, quindi IPython li usa entrambi


valori dei parametri predefiniti come se avessi chiamato rectangle_area (2, 3):

In [2]: rectangle_area ()
Fuori [2]: 6

La seguente chiamata a rectangle_area ha un solo argomento. Gli argomenti sono


assegnato ai parametri da sinistra a destra, quindi 10 viene utilizzato come lunghezza. L'interprete

passa il valore del parametro predefinito 3 per la larghezza come se avessi chiamato

rettangolo_area (10, 3):

In [3]: rectangle_area ( 10 )
Uscita [3]: 30

La seguente chiamata a rectangle_area ha argomenti sia per la lunghezza che per la larghezza, quindi
IPython ignora i valori dei parametri predefiniti:

In [4]: ​rectangle_area ( 10 , 5 )
Uscita [4]: ​50

4.10 PAROLE CHIAVE ARGOMENTI

C
Pagina 149
Quando si chiamano funzioni, è possibile utilizzare argomenti di parole chiave per passare argomenti in any
ordine. Per dimostrare gli argomenti delle parole chiave, ridefiniamo rectangle_area
funzione, questa volta senza i valori dei parametri predefiniti:

lecca qui per visualizzare l'immagine del codice

In [1]: def rectangle_area (length, width):


...: "" "Restituisce l'area di un rettangolo." ""
...: lunghezza di ritorno * larghezza
...:

Ogni argomento della parola chiave in una chiamata ha la forma parametername = value . Il seguente
call mostra che l'ordine degli argomenti delle parole chiave non ha importanza, non è necessario
abbinare le posizioni dei parametri corrispondenti nella definizione della funzione:

lecca qui per visualizzare l'immagine del codice

In [2]: rectangle_area (larghezza = 5 , lunghezza = 10 )


Uscita [3]: 50

In ogni chiamata di funzione, è necessario inserire gli argomenti delle parole chiave dopo il posizionamento di una funzione
argomenti, ovvero qualsiasi argomento per il quale non si specifica il nome del parametro.
Tali argomenti vengono assegnati ai parametri della funzione lefttoright, in base a
posizioni dell'argomento nell'elenco degli argomenti. Gli argomenti delle parole chiave sono utili anche per
migliorare la leggibilità delle chiamate di funzione, specialmente per le funzioni con molti
argomenti.
4.11 ELENCHI ARBITRALI ARBITRALI
Funzioni con elenchi di argomenti arbitrari , come le funzioni incorporate min e max,
può ricevere un numero qualsiasi di argomenti. Considera la seguente chiamata min:

min ( 88 , 75 , 96 , 55 , 83 )

La documentazione della funzione afferma che min ha due parametri obbligatori (denominati

arg1 e arg2) e un terzo parametro facoltativo nella forma * args , che lo indica
la funzione può ricevere un numero qualsiasi di argomenti aggiuntivi. Il * prima del
nome parametro dice a Python di comprimere tutti gli argomenti rimanenti in una tupla che è
passato al parametro args. Nella chiamata precedente, il parametro arg1 riceve 88,

C
Pagina 150
il parametro arg2 riceve 75 e il parametro args riceve la tupla (96, 55, 83).

Definizione di una funzione con un elenco di argomenti arbitrario

Definiamo una funzione media che può ricevere un numero qualsiasi di argomenti:

lecca qui per visualizzare l'immagine del codice

In [1]: def media (* args):


...: return sum (args) / len (args)
...:

Il nome del parametro args viene utilizzato per convenzione, ma è possibile utilizzare qualsiasi identificatore. Se la
ha più parametri, il parametro * args deve essere il più a destra
parametro.

Ora, chiamiamo media più volte con elenchi di argomenti arbitrari di diversa lunghezza:

lecca qui per visualizzare l'immagine del codice

In [2]: media ( 5 , 10 )
Uscita [2]: 7.5

In [3]: media ( 5 , 10 , 15 )
Uscita [3]: 10.0

In [4]: ​media ( 5 , 10 , 15 , 20 )
Fuori [4]: ​12.5

Per calcolare la media, dividi la somma degli elementi della tupla args (restituita da
builtin function sum) dal numero di elementi della tupla (restituito dalla funzione builtin

len). Nota nella nostra definizione media che se la lunghezza di args è 0, a


Si verifica ZeroDivisionError. Nel prossimo capitolo vedrai come accedere a una tupla
elementi senza disimballarli.

Passaggio dei singoli elementi di un iterabile come argomenti della funzione


Puoi decomprimere gli elementi di una tupla, di una lista o di altri iterabili per passarli come singoli
argomenti della funzione. L' operatore * , quando applicato a un argomento iterabile in un file
chiamata di funzione, decomprime i suoi elementi. Il codice seguente crea una valutazione a cinque elementi
list, quindi utilizza l'espressione * grades per decomprimere i suoi elementi come media
argomenti:
C
Pagina 151
lecca qui per visualizzare l'immagine del codice

In [5]: voti = [ 88 , 75 , 96 , 55 , 83 ]

In [6]: media (* voti)


Uscita [6]: 79,4

La chiamata mostrata sopra è equivalente alla media (88, 75, 96, 55, 83).

4.12 METODI: FUNZIONI A CUI APPARTENGONO


OGGETTI
Un metodo è semplicemente una funzione che chiami su un oggetto usando il form

nome_oggetto . nome_metodo ( argomenti )

Ad esempio, la sessione seguente crea la variabile stringa s e le assegna la stringa


oggetto "Hello". Quindi la sessione chiama i metodi inferiore e superiore dell'oggetto , che
produrre nuove stringhe contenenti versioni tutte minuscole e tutte maiuscole dell'originale
stringa, lasciando s invariato:

lecca qui per visualizzare l'immagine del codice

In [1]: s = "Hello"

In [2]: s.lower () # chiama il metodo lower sull'oggetto stringa s


Uscita [2]: "ciao"

In [3]: s.upper ()
Uscita [3]: "CIAO"

In [4]: ​s
Uscita [4]: ​"Ciao"

Il riferimento alla libreria standard Python in

ttps: //docs.python.org/3/library/index.html

descrive i metodi dei tipi incorporati e dei tipi nella libreria standard Python.
Nel capitolo "Programmazione ObjectOriented", creerai tipi personalizzati chiamati
classi e definire metodi personalizzati che è possibile chiamare su oggetti di tali classi.

4hC .13 REGOLE DI SCOPO


Pagina 152
4.13 REGOLE DI CAMPO DI APPLICAZIONE
Ogni identificatore ha un ambito che determina dove puoi usarlo nel tuo programma. Per
quella parte del programma, si dice che l'identificatore sia "nell'ambito".

Ambito locale

L'identificatore di una variabile locale ha un ambito locale . È "nell'ambito" solo dalla sua definizione a
la fine del blocco della funzione. “Esce dall'ambito” quando la funzione ritorna al suo
chiamante. Quindi, una variabile locale può essere utilizzata solo all'interno della funzione che la definisce.

Ambito globale

Gli identificatori definiti al di fuori di qualsiasi funzione (o classe) hanno un ambito globale: questi possono
includono funzioni, variabili e classi. Le variabili con ambito globale sono note come
variabili globali . Gli identificatori con ambito globale possono essere utilizzati in un file .py o interattivi

sessione ovunque dopo la definizione.

Accesso a una variabile globale da una funzione

Puoi accedere al valore di una variabile globale all'interno di una funzione:

lecca qui per visualizzare l'immagine del codice

In [1]: x = 7

In [2]: def access_global ():


...: print ( 'x stampata da access_global:' , x)
...:

In [3]: access_global ()
x stampato da access_global: 7

Tuttavia, per impostazione predefinita, non è possibile modificare una variabile globale in una funzione, la prima volta
assegna un valore a una variabile nel blocco di una funzione, Python crea una nuova variabile locale:

lecca qui per visualizzare l'immagine del codice

In [4]: def try_to_modify_global ():


...: x = 3.5
...: print ( 'x stampato da try_to_modify_global:' , x)
...:

In [5]: try_to_modify_global ()
x stampato da try_to_modify_global: 3.5

C
Pagina 153
In [6]: x
Fuori [6]: 7

Nel blocco della funzione try_to_modify_global, la x locale ombreggia la x globale,


rendendolo inaccessibile nell'ambito del blocco della funzione. Lo snippet [6] lo mostra
la variabile globale x esiste ancora e ha il suo valore originale (7) dopo la funzione

try_to_modify_global viene eseguito.

Per modificare una variabile globale in un blocco funzione, è necessario utilizzare un'istruzione globale a
dichiarare che la variabile è definita nell'ambito globale:

lecca qui per visualizzare l'immagine del codice

In [7]: def modify_global ():


...: globale x
...: x = 'ciao'
...: print ( 'x stampata da modify_global:' , x)
...:

In [8]: modify_global ()
x stampato da modify_global: hello

In [9]: x
Uscita [9]: "ciao"

Blocks vs. Suites

Sono stati ora definiti blocchi funzione e suite di istruzioni di controllo . Quando crei un file
variabile in un blocco, è locale per quel blocco. Tuttavia, quando crei una variabile in un file
suite dell'istruzione di controllo, l'ambito della variabile dipende da dove si trova l'istruzione di controllo
è definito:

Se l'istruzione di controllo è nell'ambito globale, tutte le variabili definite in


le istruzioni di controllo hanno un ambito globale.

Se l'istruzione di controllo è nel blocco di una funzione, tutte le variabili definite nel file
le istruzioni di controllo hanno un ambito locale.

Continueremo la nostra discussione sull'ambito nel capitolo "Programmazione ObjectOriented"


quando introduciamo classi personalizzate.

Funzioni di ombreggiatura

C
Pagina 154
Nei capitoli precedenti, durante la somma dei valori, abbiamo memorizzato la somma in una variabile
denominato totale. Il motivo per cui l'abbiamo fatto è che la somma è una funzione incorporata. Se definisci un file

variabile denominata sum, ombreggia la funzione incorporata, rendendola inaccessibile nel tuo file
codice. Quando si esegue la seguente assegnazione, Python associa la somma dell'identificatore a
l'oggetto int che contiene 15. A questo punto, l'identificatore sum non fa più riferimento al file
funzione incorporata. Quindi, quando provi a usare sum come funzione, si verifica un'eccezione TypeError:

lecca qui per visualizzare l'immagine del codice

In [10]: somma = 10 + 5

In [11]: sum
Uscita [11]: 15

In [12]: sum ([ 10 , 5 ])

TypeError Traceback (la chiamata più recente per ultima


ipythoninput121237d97a65fb> in <module> ()
> 1 somma ([ 10 , 5 ])

TypeError : l'oggetto 'int' non è richiamabile

Dichiarazioni a Global Scope

Negli script che hai visto finora, abbiamo scritto alcune istruzioni al di fuori delle funzioni nel file
ambito globale e alcune istruzioni all'interno dei blocchi funzione. Dichiarazioni di script a livello globale
scope vengono eseguite non appena vengono incontrate dall'interprete, mentre le istruzioni in
un blocco viene eseguito solo quando viene chiamata la funzione.

4.14 IMPORTAZIONE: UNO SGUARDO PIÙ PROFONDO


Hai importato moduli (come matematica e casuale) con un'istruzione come:

import nome_modulo

quindi accedere alle loro funzionalità tramite il nome di ogni modulo e un punto (.). Inoltre, hai
ha importato un identificatore specifico da un modulo (come Decimal
type) con un'istruzione come:

da nome_modulo importazione identificatore


C
<

Pagina 155
poi ha usato quell'identificatore senza doverlo precedere con il nome del modulo e un punto
(.).

Importazione di più identificatori da un modulo

Utilizzando l'istruzione from import è possibile importare un elenco di identificatori separati da virgole

da un modulo quindi usali nel tuo codice senza doverli precedere con il
nome del modulo e un punto (.):

lecca qui per visualizzare l'immagine del codice

In [1]: from math import ceil, floor

In [2]: ceil ( 10.3 )


Fuori [2]: 11

In [3]: floor ( 10.7 )


Uscita [3]: 10

Il tentativo di utilizzare una funzione non importata provoca un'eccezione NameError, che indica che il file
nome non è definito.

Attenzione: evitare le importazioni di caratteri jolly

È possibile importare tutti gli identificatori definiti in un modulo con un'importazione di caratteri jolly del modulo

da importazione nome modulo *

Ciò rende tutti gli identificatori del modulo disponibili per l'uso nel codice. Importazione di un file
gli identificatori del modulo con un'importazione di caratteri jolly possono portare a piccoli errori: è considerato un file
pratica pericolosa che dovresti evitare. Considera i seguenti frammenti:

In [4]: ​e = "hello"

In [5]: dalla matematica import *

In [6]: e
Uscita [6]: 2.718281828459045

Inizialmente, assegniamo la stringa "hello" a una variabile denominata e. Dopo aver eseguito snippet

[5] tuttavia, la variabile e viene sostituita, forse per caso, con il modulo di matematica
costante e, che rappresenta il valore matematico in virgola mobile e .

B
C inding nomi per moduli e identificatori di modulo

Nomi di associazione per moduli e identificatori di modulo Pagina 156

A volte è utile importare un modulo e utilizzare un'abbreviazione per semplificarlo


il tuo codice. La clausola as dell'istruzione import consente di specificare il nome utilizzato per
fare riferimento agli identificatori del modulo. Ad esempio, in sezione 3.14 avremmo potuto importare
il modulo delle statistiche e accedere alla sua funzione di media come segue:

lecca qui per visualizzare l'immagine del codice

In [7]: importa le statistiche come statistiche

In [8]: voti = [ 85 , 93 , 45 , 87 , 93 ]

In [9]: stats.mean (voti)


Fuori [9]: 80.6

Come vedrai nei capitoli successivi, importa come viene spesso utilizzato per importare le librerie Python
con comode abbreviazioni, come le statistiche per il modulo delle statistiche. Come un altro
esempio, useremo il modulo numpy che tipicamente viene importato con

importa numpy come np

La documentazione della biblioteca menziona spesso nomi stenografici popolari.

In genere, quando si importa un modulo, è necessario utilizzare import o import come istruzioni,
quindi accedere al modulo tramite il nome del modulo o l'abbreviazione che segue l'as
parola chiave, rispettivamente. Ciò garantisce di non importare accidentalmente un identificatore
che è in conflitto con uno nel codice.

4.15 TRASFERIMENTO ARGOMENTI ALLE FUNZIONI: UN APPROFONDIMENTO


GUARDA
Diamo uno sguardo più da vicino a come gli argomenti vengono passati alle funzioni. In molti
linguaggi di programmazione, ci sono due modi per passare arguments- passbyvalue e
passbyreference (a volte chiamato callbyvalue e callbyreference ,
rispettivamente):

Con passbyvalue, la funzione chiamata riceve una copia del valore dell'argomento e
funziona esclusivamente con quella copia. Le modifiche alla copia della funzione non influiscono sul file
valore della variabile originale nel chiamante.

C
S
Pagina 157
Con passbyreference, la funzione chiamata può accedere al valore dell'argomento nel file
chiamante direttamente e modificare il valore se è mutabile.

Gli argomenti Python vengono sempre passati per riferimento . Alcune persone chiamano questo passby
3
riferimento all'oggetto, perché "tutto in Python è un oggetto " . Quando una chiamata di funzione
fornisce un argomento, Python copia il riferimento all'oggetto dell'argomento, non l'oggetto
stesso - nel parametro corrispondente. Questo è importante per le prestazioni. Funzioni
manipolano spesso oggetti di grandi dimensioni: spesso copiarli ne consumerebbe grandi quantità
di memoria del computer e prestazioni del programma notevolmente lente.

3
Anche le funzioni che hai definito in questo capitolo e le classi (tipi personalizzati) che utilizzerai
definire nei capitoli successivi sono oggetti in Python.

Indirizzi di memoria, riferimenti e "puntatori"

Interagisci con un oggetto tramite un riferimento, che dietro le quinte è l'oggetto


indirizzo (o posizione) nella memoria del computer, talvolta chiamato "puntatore" in altri
le lingue. Dopo un incarico come

x= 7

la variabile x non contiene effettivamente il valore 7. Piuttosto, contiene un riferimento a un file


oggetto contenente 7 archiviato altrove nella memoria. Potresti dire che x "punta a" (che
è, riferimenti) l'oggetto contenente 7, come nel diagramma seguente:
ID funzione incorporata e identità degli oggetti

Consideriamo come passiamo argomenti alle funzioni. Per prima cosa, creiamo il numero intero
variabile x menzionata sopra: a breve useremo x come argomento della funzione:

In [1]: x = 7

Ora x si riferisce (o "punta a") l'oggetto intero contenente 7. Non ci sono due oggetti separati
può risiedere allo stesso indirizzo in memoria, quindi ogni oggetto in memoria ha un unico
indirizzo . Sebbene non possiamo vedere l'indirizzo di un oggetto, possiamo usare la funzione id incorporata

Pagina 158
per ottenere un valore int univoco che identifica solo quell'oggetto finché rimane in
memoria (probabilmente otterrai un valore diverso quando lo esegui sul tuo computer):

In [2]: id (x)
Uscita [2]: 4350477840

4
Il risultato intero della chiamata di id è noto come identità dell'oggetto . Non ci sono due oggetti in

la memoria può avere la stessa identità . Useremo le identità degli oggetti per dimostrarlo
gli oggetti vengono passati per riferimento.

4
Secondo la documentazione di Python, a seconda dell'implementazione di Python
che stai usando, l'identità di un oggetto può essere l'effettivo indirizzo di memoria dell'oggetto, ma questo è
non richiesto.

Passaggio di un oggetto a una funzione


Definiamo una funzione cubo che mostri l'identità del suo parametro, quindi restituisca il
valore del parametro al cubo:

lecca qui per visualizzare l'immagine del codice

In [3]: def cube (numero):


...: print ( 'id (numero):' , id (numero))
...: numero di ritorno ** 3
...:

Quindi, chiamiamo cubo con l'argomento x, che si riferisce all'oggetto intero che contiene

7:

In [4]: ​cubo (x)


id (numero): 4350477840
Uscita [4]: ​343

L'identità visualizzata per il numero di parametro del cubo, 4350477840, è la stessa di


quello visualizzato per x in precedenza. Poiché ogni oggetto ha un'identità unica, sia il file
l'argomento x e il numero del parametro si riferiscono allo stesso oggetto durante l'esecuzione del cubo.
Quindi, quando il cubo funzione utilizza il numero di parametro nel suo calcolo, ottiene il valore di

numero dall'oggetto originale nel chiamante.

Test delle identità degli oggetti con l'operatore is


C
Pagina 159
Puoi anche provare che l'argomento e il parametro si riferiscono allo stesso oggetto con
L' operatore is di Python , che restituisce True se i suoi due operandi hanno la stessa identità :

lecca qui per visualizzare l'immagine del codice

In [5]: def cube (numero):


...: print ( 'number is x:' , number is x) # x è una variabile globale e
...: numero di ritorno ** 3
...:

In [6]: cubo (x)


il numero è x: vero
Uscita [6]: 343

Oggetti immutabili come argomenti

Quando una funzione riceve come argomento un riferimento a un immutabile (non modificabile)
oggetto, come int, float, stringa o tupla, anche se hai accesso diretto
all'oggetto originale nel chiamante, non è possibile modificare l'oggetto immutabile originale
valore. Per dimostrarlo, per prima cosa facciamo in modo che il cubo visualizzi l'id (numero) prima e dopo
assegnazione di un nuovo oggetto al numero di parametro tramite un'assegnazione aumentata:

lecca qui per visualizzare l'immagine del codice

In [7]: def cube (numero):


...: print ( 'id (numero) prima di modificare il numero:' , id (numero))
...: numero ** = 3
...: print ( 'id (numero) dopo aver modificato il numero:' , id (numero))
...: numero di ritorno
...:

In [8]: cubo (x)


id (numero) prima di modificare il numero: 4350477840
id (numero) dopo aver modificato il numero: 4396653744
Uscita [8]: 343

Quando chiamiamo cube (x), la prima istruzione print mostra che id (numero) inizialmente è
lo stesso di id (x) nello snippet [2]. I valori numerici non sono modificabili, quindi l'istruzione

numero ** = 3

crea effettivamente un nuovo oggetto contenente il valore al cubo, quindi assegna il valore di quell'oggetto
riferimento al numero di parametro. Ricordiamo che se non ci sono più riferimenti al file

C
Pagina 160
oggetto originale , verrà raccolto dalla spazzatura . Seconda istruzione print del cubo funzione
mostra l' identità del nuovo oggetto. Le identità degli oggetti devono essere univoche, quindi il numero deve
fare riferimento a un oggetto diverso . Per mostrare che x non è stato modificato, visualizziamo il suo valore e
ancora identità:

lecca qui per visualizzare l'immagine del codice

In [9]: print (f 'x = {x} ; id (x) = {id (x)} ' )


x = 7; id (x) = 4350477840

Oggetti mutabili come argomenti


Nel prossimo capitolo, lo mostreremo quando si fa riferimento a un oggetto mutabile come una lista
passato a una funzione, la funzione può modificare l'oggetto originale nel chiamante.

4.16 RICURSIONE
Scriviamo un programma per eseguire un famoso calcolo matematico. Considera il
fattoriale di un intero positivo n , che si scrive n ! e pronunciato " n fattoriale". Questo
è il prodotto

n · ( n - 1) · ( n - 2) ··· 1

con 1! uguale a 1 e 0! definito come 1. Ad esempio, 5! è il prodotto 5 · 4 · 3 · 2 · 1,


che è uguale a 120.

Approccio fattoriale iterativo

Puoi calcolarne 5! iterativamente con un'istruzione for, come in:

lecca qui per visualizzare l'immagine del codice

In [1]: fattoriale = 1

In [2]: in numero a gamma ( 5 , 0 , 1 ):


...: fattoriale * = numero
...:

In [3]: fattoriale
Uscita [3]: 120

Risoluzione ricorsiva dei problemi


C
Pagina 161
Gli approcci ricorsivi alla risoluzione dei problemi hanno diversi elementi in comune. Quando tu
chiama una funzione ricorsiva per risolvere un problema, in realtà è in grado di risolvere solo il file
casi più semplici , o casi base . Se chiami la funzione con un caso base , esso
restituisce immediatamente un risultato. Se chiami la funzione con un problema più complesso, esso
in genere divide il problema in due parti, una che la funzione sa come eseguire
e uno che non sa fare. Per rendere fattibile la ricorsione, quest'ultimo pezzo
deve essere una versione leggermente più semplice o più piccola del problema originale. Perché questo nuovo
problema assomiglia al problema originale, la funzione chiama una nuova copia di se stessa per funzionare
sul problema più piccolo, questo è indicato come una chiamata ricorsiva ed è anche chiamato
passo di ricorsione . Questo concetto di separare il problema in due porzioni più piccole è a
forma del divideandconquer approccio introdotto in precedenza nel libro.

Il passaggio di ricorsione viene eseguito mentre la chiamata della funzione originale è ancora attiva (ovvero, non lo è
terminata l'esecuzione). Può provocare molte più chiamate ricorsive man mano che la funzione si divide
ogni nuovo sottoproblema in due pezzi concettuali. Per la ricorsione alla fine
terminare, ogni volta che la funzione chiama se stessa con una versione più semplice dell'originale
problema, la sequenza di problemi sempre più piccoli deve convergere su un caso base .
Quando la funzione riconosce il caso base, restituisce un risultato alla copia precedente di
la funzione. Segue una sequenza di ritorni fino a quando la chiamata di funzione originale non restituisce
risultato finale al chiamante.

Approccio fattoriale ricorsivo

Puoi arrivare a una rappresentazione fattoriale ricorsiva osservando che n ! può essere scritto
come:
n ! = n · ( n - 1)!

Ad esempio, 5! è uguale a 5 · 4 !, come in:

5! = 5 · 4 · 3 · 2 · 1
5! = 5 · (4 · 3 · 2 · 1)
5! = 5 · (4!)

Visualizzazione della ricorsione

La valutazione di 5! procederà come mostrato di seguito. La colonna di sinistra mostra come il file
la successione di chiamate ricorsive procede fino a 1! (il caso base) viene valutato come 1, che
termina la ricorsione. La colonna di destra mostra i valori dal basso verso l'alto
restituito da ogni chiamata ricorsiva al suo chiamante fino a quando non viene calcolato il valore finale e

Pagina 162
restituito.

Implementazione di una funzione fattoriale ricorsiva


La sessione seguente utilizza la ricorsione per calcolare e visualizzare i fattoriali di
numeri interi da 0 a 10:

lecca qui per visualizzare l'immagine del codice

In [4]: def fattoriale (numero):


...: "" "Restituisce il fattoriale del numero." ""
...: se numero <= 1 :
...: ritorno 1
...: numero di ritorno * fattoriale (numero 1 ) # chiamata ricorsiva
...:

In [5]: per i in serie ( 11 ):


...: print (f ' {i} ! = {fattoriale (i)} ' )
...:
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
10! = 3628800
C
Pagina 163

La funzione fattoriale ricorsiva di Snippet [4] determina innanzitutto se il file terminating


il numero di condizione <= 1 è vero. Se questa condizione è vera (il caso base), fattoriale
restituisce 1 e non è necessaria un'ulteriore ricorsione. Se il numero è maggiore di 1, il secondo

L'istruzione return esprime il problema come prodotto di numero e ricorsivo


chiamata a fattoriale che valuta fattoriale (numero 1). Questo è un po '

problema più piccolo del calcolo originale, fattoriale (numero). Nota che
la funzione fattoriale deve ricevere un argomento non negativo . Non lo testiamo
Astuccio.

Il ciclo nello snippet [5] chiama la funzione fattoriale per i valori da 0 a

10. L'output mostra che i valori fattoriali crescono rapidamente. Python non limita le dimensioni
di un numero intero , a differenza di molti altri linguaggi di programmazione.

Ricorsione indiretta

Una funzione ricorsiva può chiamare un'altra funzione che, a sua volta, può richiamare
la funzione ricorsiva. Questo è noto come chiamata ricorsiva indiretta o indiretta
ricorsione . Ad esempio, la funzione A chiama la funzione B, che effettua una chiamata a
funzione A. Questa è ancora ricorsione perché la seconda chiamata alla funzione A viene effettuata mentre il
la prima chiamata alla funzione A è attiva. Cioè, la prima chiamata alla funzione A non è ancora terminata
in esecuzione (perché è in attesa che la funzione B restituisca un risultato) e non lo ha fatto
restituito al chiamante originale della funzione A.

Overflow dello stack e ricorsione infinita

Naturalmente, la quantità di memoria in un computer è limitata, quindi solo una certa quantità di
la memoria può essere utilizzata per memorizzare i record di attivazione nello stack di chiamate di funzione. Se di più
si verificano chiamate di funzione ricorsive che possono avere i loro record di attivazione memorizzati nello stack,
si verifica un errore irreversibile noto come overflow dello stack . Questo è tipicamente il risultato di infinito
ricorsione , che può essere causata dall'omissione del caso base o dalla scrittura del passaggio di ricorsione
in modo errato in modo che non converga sul case base. Questo errore è analogo a
problema di un ciclo infinito in una soluzione iterativa (non ricorsiva).

4.17 PROGRAMMAZIONE IN STILE FUNZIONALE


Come altri linguaggi popolari, come Java e C #, Python non è puramente funzionale
linguaggio. Piuttosto, offre funzionalità di "stile funzionale" che ti aiutano a scrivere codice che è
meno probabilità di contenere errori, più conciso e facile da leggere, eseguire il debug e modificare.
Anche i programmi in stile funzionale possono essere più facili da parallelizzare per ottenere prestazioni migliori

Pagina 164
processori multicore di oggi. Il grafico seguente elenca la maggior parte delle funzionalità chiave di Python
capacità di programmazione dello stile e mostra tra parentesi i capitoli in cui abbiamo
inizialmente ne coprono molti.

Argomenti di programmazione in stile funzionale

evitare effetti collaterali (4)


funzioni del generatore
valutazione pigra (5)
chiusure
ordine superiore
programmazione dichiarativa funzioni (5) liste di comprensione (5)

(4)
immutabilità (4) modulo operatore (5,
11, 16)
decoratori (10)
iterazione interna (4)
funzioni pure (4)
dizionario
iteratori (3)
comprensioni (6)
funzione range (3, 4)
modulo itertools
filtra / mappa / riduci (5)
(16) riduzioni (3, 5)

modulo functools
espressioni lambda impostare le comprensioni (6)
(5)
espressioni generatore (5)

Copriamo la maggior parte di queste funzionalità in tutto il libro, molte con esempi di codice e
altri da una prospettiva di alfabetizzazione. Hai già utilizzato lista, stringa e funzione incorporata
iteratori di intervallo con l'istruzione for e diverse riduzioni (funzioni sum, len,
min e max). Discutiamo di programmazione dichiarativa, immutabilità e interna
iterazione di seguito.

Cosa contro come

Man mano che le attività che svolgi diventano più complicate, il codice può diventare più difficile da leggere,
eseguire il debug e modificare e più probabile che contenga errori. Specificare come funziona il codice
può diventare complesso.

La programmazione in stile funzionale ti consente di dire semplicemente cosa vuoi fare. Ne nasconde molti

Pagina 165
dettagli su come eseguire ciascuna attività. In genere, il codice della libreria gestisce il come per te. Come
vedrai, questo può eliminare molti errori.

Considera l'istruzione for in molti altri linguaggi di programmazione. In genere, tu


deve specificare tutti i dettagli dell'iterazione controcontrollata: una variabile di controllo, la sua iniziale
value, come incrementarlo e una condizione di continuazione del ciclo che utilizza il controllo
variabile per determinare se continuare l'iterazione. Questo stile di iterazione è noto come
iterazione esterna ed è soggetto a errori. Ad esempio, potresti fornire un errore
condizione di inizializzazione, incremento o continuazione del ciclo. L'iterazione esterna muta (that
è, modifica) la variabile di controllo e la suite dell'istruzione for spesso ne modifica altri
anche variabili. Ogni volta che modifichi le variabili potresti introdurre errori.
La programmazione in stile funzionale enfatizza l' immutabilità . Cioè, evita le operazioni
che modificano i valori delle variabili. Diremo di più nel prossimo capitolo.

L'istruzione for e la funzione range di Python nascondono la maggior parte delle iterazioni controcontrollate
dettagli. Specificate quale intervallo di valori dovrebbe produrre e la variabile che dovrebbe
ricevere ogni valore così come viene prodotto. La gamma di funzioni sa come produrli

valori. Allo stesso modo, l'istruzione for sa come ottenere ogni valore da range e come
per interrompere l'iterazione quando non ci sono più valori. Specificare cosa , ma non come , è un file
aspetto importante dell'iterazione interna: un concetto chiave di programmazione in stile funzionale.

Le funzioni incorporate di Python sum, min e max usano ciascuna iterazione interna. Per totale
gli elementi della lista voti, dichiari semplicemente cosa vuoi fare, cioè

somma (voti). La funzione sum sa come scorrere l'elenco e aggiungerli


elemento al totale parziale. Indicare cosa vuoi fare invece di programmare
come farlo è noto come programmazione dichiarativa .

Funzioni pure

Nel linguaggio di programmazione funzionale puro ti concentri sulla scrittura di funzioni pure.Un puro
il risultato della funzione dipende solo dagli argomenti che le passi. Inoltre, dato un
argomento (o argomenti) particolare, una funzione pura produce sempre lo stesso risultato.
Ad esempio, il valore restituito dalla funzione incorporata sum dipende solo dall'iterabile passato
ad esso. Dato un elenco [1, 2, 3], sum restituisce sempre 6 indipendentemente da quante volte chiami
esso. Inoltre, una funzione pura non ha effetti collaterali . Ad esempio, anche se superi un
mutevole lista per pura funzione, l'elenco conterrà gli stessi valori prima e dopo la
chiamata di funzione. Quando chiami la funzione pura somma, non modifica il suo argomento.

lecca qui per visualizzare l'immagine del codice

d
C
Pagina 166
In [1]: valori = [ 1 , 2 , 3 ]

In [2]: somma (valori)


Fuori [2]: 6

In [3]: sum (values) # la stessa chiamata restituisce sempre lo stesso risultato


Fuori [3]: 6

In [4]: ​valori
Uscita [5]: [1, 2, 3]

Nel prossimo capitolo continueremo a utilizzare i concetti di programmazione in stile funzionale. Anche,
vedrai che le funzioni sono oggetti che puoi passare ad altre funzioni come dati.

4.18 INTRO A DATA SCIENCE: MISURE DI


DISPERSIONE
Nella nostra discussione sulle statistiche descrittive, abbiamo considerato le misure di centrale
tendenza: media, mediana e moda. Questi ci aiutano a classificare i valori tipici in un gruppo
—Come l'altezza media dei tuoi compagni di classe o l'auto acquistata più di frequente
marca (la modalità) in un determinato paese.

Quando parliamo di un gruppo, l'intero gruppo è chiamato popolazione .


A volte una popolazione è piuttosto numerosa, come le persone che probabilmente voteranno nei prossimi Stati Uniti
elezioni presidenziali, che è un numero superiore a 100.000.000 di persone. Per pratico
ragioni, le organizzazioni elettorali che cercano di prevedere chi diventerà il prossimo presidente
lavorare con piccoli sottoinsiemi accuratamente selezionati della popolazione noti come campioni . Molti
dei sondaggi nelle elezioni del 2016 avevano un campione di circa 1000 persone.

In questa sezione, continueremo a discutere le statistiche descrittive di base. Introduciamo


misure di dispersione (chiamate anche misure di variabilità ) che ti aiutano
capire quanto sono diffusi i valori. Ad esempio, in una classe di studenti, lì
può essere un gruppo di studenti la cui altezza è vicina alla media, con numeri più piccoli
di studenti che sono considerevolmente più bassi o più alti.

Per i nostri scopi, calcoleremo ogni misura di dispersione sia manualmente che con
funzioni dalle statistiche del modulo, utilizzando la seguente popolazione di 10 sixsided
rotoli di dado:

1, 3, 4, 2, 6, 5, 3, 4, 5, 2
V ariance

Varianza Pagina 167

5
Per determinare la varianza , iniziamo con la media di questi valori: 3,5. tu
ottenere questo risultato dividendo la somma dei valori nominali, 35, per il numero di rotoli, 10.
Successivamente, sottraiamo la media da ogni valore di dado (questo produce alcuni risultati negativi):

5
Per semplicità, stiamo ricalcolando la varianza della popolazione . C'è una sottile differenza
tra la varianza della popolazione e la varianza del campione . Invece di dividere per n
(il numero di tiri di dado nel nostro esempio), la varianza del campione divide per n 1. La differenza
è pronunciato per piccoli campioni e diventa insignificante come la dimensione del campione
aumenta. Il modulo di statistica fornisce le funzioni pvariance e

varianza per calcolare rispettivamente la varianza della popolazione e la varianza del campione.
Allo stesso modo, il modulo delle statistiche fornisce le funzioni pstdev e stdev
calcolare la deviazione standard della popolazione e la deviazione standard del campione,
rispettivamente.

2,5, 0,5, 0,5, 1,5, 2,5, 1,5, 0,5, 0,5, 1,5, 1,5

Quindi, quadriamo ciascuno di questi risultati (producendo solo positivi):

6.25, 0.25, 0.25, 2.25, 6.25, 2.25, 0.25, 0.25, 2.25, 2.25

Infine, calcoliamo la media di questi quadrati, che è 2,25 (22,5 / 10): questo è
la varianza della popolazione . Il quadrato della differenza tra il valore di ogni dado e il valore
La media di tutti i valori del dado enfatizza i valori anomali: i valori più lontani da
significare. Man mano che approfondiamo l'analisi dei dati, a volte vorremo prestare attenzione
attenzione ai valori anomali ea volte vorremo ignorarli. Il codice seguente usa
la funzione pvariance del modulo delle statistiche per confermare il nostro risultato manuale:

lecca qui per visualizzare l'immagine del codice

In [1]: statistiche sulle importazioni

In [2]: statistics.pvariance ([ 1 , 3 , 4 , 2 , 6 , 5 , 3 , 4 , 5 , 2 ])
Uscita [2]: 2.25

Deviazione standard

La deviazione standard è la radice quadrata della varianza (in questo caso, 1,5), che
attenua l'effetto dei valori anomali. Minore è la varianza e la deviazione standard

C
Pagina 168
sono, più i valori dei dati sono vicini alla media e minore è la dispersione complessiva (ovvero,
spread ) c'è tra i valori e la media. Il codice seguente calcola il
deviazione standard della popolazione con la funzione pstdev del modulo statistico ,
confermando il nostro risultato manuale:

lecca qui per visualizzare l'immagine del codice

In [3]: statistics.pstdev ([ 1 , 3 , 4 , 2 , 6 , 5 , 3 , 4 , 5 , 2 ])
Fuori [3]: 1.5

Il passaggio del risultato della funzione pvariance alla funzione sqrt del modulo matematico conferma
il nostro risultato di 1.5:

lecca qui per visualizzare l'immagine del codice

In [4]: importa matematica

In [5]: math.sqrt (statistics.pvariance ([ 1 , 3 , 4 , 2 , 6 , 5 , 3 , 4 , 5 , 2 ]))


Fuori [5]: 1.5

Vantaggio della deviazione standard della popolazione rispetto alla varianza della popolazione
Supponi di aver registrato le temperature di marzo Fahrenheit nella tua zona. Tu potresti
hanno 31 numeri come 19, 32, 28 e 35. Le unità di questi numeri sono gradi.
Quando si quadrano le temperature per calcolare la varianza della popolazione, le unità di
la varianza della popolazione diventa "gradi al quadrato". Quando prendi la radice quadrata di
la varianza della popolazione per calcolare la deviazione standard della popolazione, le unità una volta
di nuovo diventano gradi, che sono le stesse unità delle vostre temperature.

4.19 WRAP-UP
In questo capitolo abbiamo creato funzioni personalizzate. Abbiamo importato funzionalità da

moduli casuali e matematici. Abbiamo introdotto la generazione di numeri casuali e l'abbiamo usata per
simula il lancio di un dado a sei facce. Abbiamo impacchettato più valori in tuple per restituirne di più
di un valore da una funzione. Abbiamo anche decompresso una tupla per accedere ai suoi valori. Noi
discusso sull'uso dei moduli della libreria standard Python per evitare di “reinventare il
ruota."

Abbiamo creato funzioni con valori di parametro predefiniti e chiamate funzioni con parola chiave
argomenti. Abbiamo anche definito funzioni con elenchi di argomenti arbitrari. Abbiamo chiamato metodi
di oggetti. Abbiamo discusso di come l'ambito di un identificatore determina la posizione del tuo programma

C
Pagina 169
puoi usarlo.

Abbiamo presentato di più sull'importazione di moduli. Hai visto che gli argomenti sono passati
riferimento alle funzioni e come lo stack functioncall e gli stack frame supportano l'estensione
functioncallandreturn meccanismo. Abbiamo anche presentato una funzione ricorsiva e abbiamo iniziato
introducendo le capacità di programmazione in stile funzionale di Python. Abbiamo introdotto
elenco di base e funzionalità delle tuple negli ultimi due capitoli: nel prossimo capitolo, lo faremo
discuterli in dettaglio.

Infine, abbiamo continuato la nostra discussione sulle statistiche descrittive introducendo misure di
dispersione (varianza e deviazione standard) e calcolo con funzioni
dal modulo delle statistiche della Python Standard Library.

Per alcuni tipi di problemi, è utile che le funzioni chiamino se stesse. Un ricorsivo
funzione chiama se stessa, direttamente o indirettamente tramite un'altra funzione.
y
Pagina 170

le liste

5. Sequenze: elenchi e tuple


tory

Obiettivi
foto

In questo capitolo potrai:


arning Pat

Crea e inizializza elenchi e tuple.


fers & Dea

Fare riferimento a elementi di elenchi, tuple e stringhe.


hlights

Ordina e cerca elenchi e cerca tuple.


ttings

Passa elenchi e tuple a funzioni e metodi.


Supporto
Utilizza i metodi di elenco per eseguire manipolazioni comuni, come la ricerca di elementi,
Disconnessione
ordinare un elenco, inserire e rimuovere elementi.

Usa funzionalità di programmazione in stile funzionale Python aggiuntive, inclusi lambda


e le operazioni di programmazione in stile funzionale filtrano, mappano e riducono.

Usa le comprensioni degli elenchi in stile funzionale per creare elenchi in modo rapido e semplice e utilizzarli
espressioni del generatore per generare valori su richiesta.

Usa elenchi bidimensionali.

Migliora le tue capacità di analisi e presentazione con Seaborn e Matplotlib


librerie di visualizzazione.

Contorno

.1 Introduzione

.2 Elenchi

.3 Tuple
5
Pagina 171
.4 Sequenze di disimballaggio

.5 Sequence Slicing

.6 del Statement

.7 Passaggio di elenchi alle funzioni

.8 Ordinamento degli elenchi

.9 Ricerca di sequenze

.10 Altri metodi di elenco

.11 Simulazione di pile con elenchi

.12 Comprensioni degli elenchi

.13 Espressioni del generatore

.14 Filtra, mappa e riduci

.15 Altre funzioni di elaborazione delle sequenze

.16 Elenchi bidimensionali

.17 Introduzione alla scienza dei dati: simulazione e visualizzazioni statiche

.17.1 Esempi di grafici per 600, 60.000 e 6.000.000 di dadi

.17.2 Visualizzazione delle frequenze e delle percentuali di DieRoll

.18 WrapUp

5.1 INTRODUZIONE
Negli ultimi due capitoli, abbiamo introdotto brevemente l'elenco e i tipi di sequenza di tupla per
che rappresentano raccolte ordinate di oggetti. Le raccolte sono strutture di dati preconfezionate
costituito da elementi di dati correlati. Esempi di raccolte includono le tue canzoni preferite su
il tuo smartphone, la tua lista dei contatti, i libri di una biblioteca, le tue carte in un gioco di carte, il tuo
i giocatori della squadra sportiva preferita, le azioni in un portafoglio di investimenti, i malati di cancro
studio e lista della spesa. Le raccolte incorporate di Python ti consentono di archiviare e accedere

5
Pagina 172
dati in modo conveniente ed efficiente. In questo capitolo, discuteremo di elenchi e tuple in more
dettaglio.

Mostreremo liste comuni e manipolazioni di tuple. Vedrai che gli elenchi (che sono
modificabile) e le tuple (che non lo sono) hanno molte funzionalità comuni. Ciascuno può tenere
articoli dello stesso tipo o di diverso tipo. Gli elenchi possono essere ridimensionati dinamicamente secondo necessità,
in crescita e in contrazione al momento dell'esecuzione. Discutiamo monodimensionale e due
elenchi dimensionali.

Nel capitolo precedente, abbiamo dimostrato la generazione di numeri casuali e simulato


tirando un dado a sei facce. Concludiamo questo capitolo con la nostra prossima introduzione alla scienza dei dati
sezione, che utilizza le librerie di visualizzazione Seaborn e Matplotlib per interagire
sviluppare grafici a barre statici contenenti le frequenze dello stampo. Nell'introduzione di
Nella sezione Data Science, presenteremo una visualizzazione animata in cui il grafico a barre
cambia dinamicamente all'aumentare del numero di tiri di dado: vedrai la legge del grande
numeri "in azione".

5.2 ELENCHI
Qui, discutiamo gli elenchi in modo più dettagliato e spieghiamo come fare riferimento a un elenco particolare
elementi . Molte delle funzionalità mostrate in questa sezione si applicano a tutti i tipi di sequenza.

Creazione di un elenco

Gli elenchi in genere memorizzano dati omogenei , ovvero valori dello stesso tipo di dati.
Considera l'elenco c, che contiene cinque elementi interi:

lecca qui per visualizzare l'immagine del codice

In [1]: c = [ 45 , 6 , 0 , 72 , 1543 ]

In [2]: c
Uscita [2]: [45, 6, 0, 72, 1543]

Possono anche memorizzare dati eterogenei , ovvero dati di molti tipi diversi. Per
esempio, il seguente elenco contiene il nome di uno studente (una stringa), il cognome (a
stringa), media dei voti (un float) e anno di laurea (un int):

lecca qui per visualizzare l'immagine del codice

[ "Mary" , "Smith" , 3.57 , 2022 ]

UN
C accesso agli elementi di un elenco

Accesso agli elementi di un elenco Pagina 173

Si fa riferimento a un elemento della lista, scrivendo il nome della lista seguito dal dell'elemento dell'indice
(ovvero, il suo numero di posizione ) racchiuso tra parentesi quadre ([], noto come
operatore in abbonamento ). Il diagramma seguente mostra l'elenco c etichettato con il suo
nomi degli elementi:

Il primo elemento in una lista ha l'indice 0. Quindi, nella lista a cinque elementi c, il primo elemento
si chiama c [0] e l'ultimo è c [4]:

In [3]: c [ 0 ]
Uscita [3]: 45

In [4]: ​c [ 4 ]
Uscita [4]: ​1543

Determinazione della lunghezza di una lista

Per ottenere la lunghezza di una lista, usa la funzione len incorporata :


In [5]: len (c)
Fuori [5]: 5

Accesso agli elementi dalla fine della lista con indici negativi

È inoltre possibile accedere alle liste dalla fine utilizzando indici negativi :

Quindi, è possibile accedere all'ultimo elemento della lista c (c [4]) con c [1] e al suo primo elemento con

c [5]:

In [6]: c [ 1 ]
Uscita [6]: 1543

Pagina 174
In [7]: c [ 5 ]
Uscita [7]: 45

Gli indici devono essere numeri interi o espressioni intere

Un indice deve essere un'espressione intera o intera (o uno slice , come vedremo presto):

In [8]: a = 1

In [9]: b = 2

In [10]: c [a + b]
Fuori [10]: 72

L'utilizzo di un valore di indice non intero causa un'eccezione TypeError.

Le liste sono mutevoli

Gli elenchi sono modificabili: i loro elementi possono essere modificati:

lecca qui per visualizzare l'immagine del codice

In [11]: c [ 4 ] = 17

In [12]: c
Uscita [12]: [45, 6, 0, 72, 17]

Presto vedrai che puoi anche inserire ed eliminare elementi, modificando la lunghezza dell'elenco.

Alcune sequenze sono immutabili

Le sequenze di stringhe e tuple di Python sono immutabili: non possono essere modificate. Puoi
ottenere i singoli caratteri in una stringa, ma tentando di assegnare un nuovo valore a uno di
i caratteri causano un TypeError:

lecca qui per visualizzare l'immagine del codice

n [13]: s = "ciao"

In [14]: s [ 0 ]
Fuori [14]: 'h'

In [15]: s [ 0 ] = "H"
C

TypeError Traceback (la chiamata più recente per ultima) Pagina 175
<ipythoninput15812ef2514689> in <module> ()
> 1 s [ 0 ] = "H"

TypeError : l'oggetto 'str' non supporta l'assegnazione di elementi

tentativo di accedere a un elemento inesistente

L'uso di un elenco fuori intervallo, una tupla o un indice di stringa provoca un errore IndexError:

lecca qui per visualizzare l'immagine del codice

In [16]: c [ 100 ]

IndexError Traceback (la chiamata più recente last


ipythoninput169a31ea1e1a13> in <module> ()
> 1 c [ 100 ]

IndexError : elenca l'indice fuori intervallo

Utilizzo degli elementi dell'elenco nelle espressioni

Gli elementi della lista possono essere usati come variabili nelle espressioni:

In [17]: c [ 0 ] + c [ 1 ] + c [ 2 ]
Fuori [17]: 39

Aggiunta a un elenco con + =

Cominciamo con un elenco vuoto [], quindi usa un'istruzione for e + = per aggiungere i valori
Da 1 a 5 nell'elenco: l'elenco cresce dinamicamente per accogliere ogni elemento:

lecca qui per visualizzare l'immagine del codice

In [18]: a_list = []

In [19]: per numero di serie ( 1 , 6 ):


...: a_list + = [numero]
...:

In [20]: a_list
Fuori [20]: [1, 2, 3, 4, 5]

UN
C
<

Pagina 176
Quando l'operando sinistro di + = è un elenco, l'operando destro deve essere un iterabile ; in caso contrario, a

TypeError si verifica. Nella suite dello snippet [19], le parentesi quadre attorno al numero creano
un elenco di un elemento, che aggiungiamo a a_list. Se l'operando di destra contiene più file
elementi, + = li aggiunge tutti. Quanto segue aggiunge i caratteri di "Python" a
le lettere dell'elenco:

lecca qui per visualizzare l'immagine del codice

In [21]: lettere = []

In [22]: lettere + = "Python"


In [23]: lettere
Fuori [23]: ['P', 'y', 't', 'h', 'o', 'n']

Se l'operando di destra di + = è una tupla, anche i suoi elementi vengono aggiunti all'elenco. Più tardi in
nel capitolo, useremo il metodo list append per aggiungere elementi a un elenco.

Concatenazione di elenchi con +

È possibile concatenare due elenchi, due tuple o due stringhe utilizzando l'operatore +. Il
il risultato è una nuova sequenza dello stesso tipo contenente gli elementi dell'operando sinistro
seguito dagli elementi dell'operando destro. Le sequenze originali rimangono invariate:

lecca qui per visualizzare l'immagine del codice

In [24]: list1 = [ 10 , 20 , 30 ]

In [25]: list2 = [ 40 , 50 ]

In [26]: concatenated_list = list1 + list2

In [27]: concatenated_list
Uscita [27]: [10, 20, 30, 40, 50]

Si verifica un'eccezione TypeError se gli operandi dell'operatore + sono tipi di sequenza di differenza, per
Ad esempio, concatenare un elenco e una tupla è un errore.

Utilizzo di for e range per accedere a indici e valori dell'elenco

È inoltre possibile accedere agli elementi dell'elenco tramite i loro indici e l'operatore di abbonamento ([]):

lecca qui per visualizzare l'immagine del codice

C
Pagina 177
In [28]: for i in range (len (concatenated_list)):
...: print (f ' {i} : {concatenated_list [i]} ' )
...:
0:10
1:20
2:30
3:40
4:50

La funzione chiamata range (len (concatenated_list)) produce una sequenza di


numeri interi che rappresentano gli indici di concatenated_list (in questo caso, da 0 a 4). quando
in questo modo, è necessario assicurarsi che gli indici rimangano nell'intervallo. Presto lo mostreremo
un modo più sicuro per accedere agli indici e ai valori degli elementi utilizzando la funzione incorporata enumerate.

Operatori di confronto

Puoi confrontare interi elenchi elemento per elemento utilizzando gli operatori di confronto:

lecca qui per visualizzare l'immagine del codice

In [29]: a = [1, 2, 3]

In [30]: b = [1, 2, 3]

In [31]: c = [1, 2, 3, 4]

In [32]: a == b # True: gli elementi corrispondenti in entrambi sono uguali


Out [32]: Vero
In [33]: a == c # False: a e c hanno elementi e lunghezze differenti
Out [33]: Falso

In [34]: a <c # True: a ha meno elementi di c


Out [34]: Vero

In [35]: c> = b # Vero: gli elementi 02 sono uguali ma c ha più elementi


Out [35]: Vero

5.3 TUPLES
Come discusso nel capitolo precedente, le tuple sono immutabili e in genere vengono archiviate
dati eterogenei, ma i dati possono essere omogenei. La lunghezza di una tupla è il suo numero di
elementi e non possono cambiare durante l'esecuzione del programma.

Creazione di tuple
C
Creazione di tuple
Pagina 178
o crea una tupla vuota, usa parentesi vuote:

In [1]: student_tuple = ()

In [2]: student_tuple
Uscita [2]: ()

In [3]: len (student_tuple)


Uscita [3]: 0

Ricorda che puoi comprimere una tupla separando i suoi valori con virgole:

lecca qui per visualizzare l'immagine del codice

In [4]: ​student_tuple = 'John' , 'Green' , 3.3

In [5]: student_tuple
Uscita [5]: ('John', 'Green', 3.3)

In [6]: len (student_tuple)


Fuori [6]: 3

Quando esegui l'output di una tupla, Python ne mostra sempre il contenuto tra parentesi. Potresti
racchiudere un elenco di valori separati da virgole di una tupla con parentesi opzionali:

lecca qui per visualizzare l'immagine del codice

In [7]: another_student_tuple = ( 'Mary' , 'Red' , 3.3 )

In [8]: another_student_tuple
Uscita [8]: ('Mary', 'Red', 3.3)

Il codice seguente crea una tupla di un elemento:

lecca qui per visualizzare l'immagine del codice

In [9]: a_singleton_tuple = ( 'red' ,) # nota la virgola

In [10]: a_singleton_tuple
Fuori [10]: ('rosso',)

La virgola (,) che segue la stringa "red" identifica a_singleton_tuple come a


tupla: le parentesi sono facoltative. Se la virgola fosse omessa, le parentesi lo sarebbero

C
T
Pagina 179
essere ridondante e a_singleton_tuple farebbe semplicemente riferimento alla stringa 'red'
piuttosto che una tupla.

Accesso agli elementi della tupla

Gli elementi di una tupla, sebbene correlati, sono spesso di più tipi. Di solito non lo fai
iterare su di loro. Piuttosto, accedi a ciascuno individualmente. Come gli indici di lista, gli indici di tupla
inizia da 0. Il codice seguente crea time_tuple che rappresentano un'ora, un minuto e
secondo, visualizza la tupla, quindi utilizza i suoi elementi per calcolare il numero di secondi
da mezzanotte: si noti che eseguiamo un'operazione diversa con ogni valore nel file
tupla:

lecca qui per visualizzare l'immagine del codice

In [11]: time_tuple = ( 9 , 16 , 1 )

In [12]: time_tuple
Uscita [12]: (9, 16, 1)

In [13]: time_tuple [ 0 ] * 3600 + time_tuple [ 1 ] * 60 + time_tuple [ 2 ]


Uscita [13]: 33361

L'assegnazione di un valore a un elemento tupla causa un'eccezione TypeError.

Aggiunta di elementi a una stringa o tupla

Come con gli elenchi, l'istruzione di assegnazione aumentata + = può essere utilizzata con le stringhe e
tuple, anche se sono immutabili . Nel codice seguente, dopo i due
assegnazioni, tuple1 e tuple2 si riferiscono allo stesso oggetto tupla:

In [14]: tuple1 = ( 10 , 20 , 30 )

In [15]: tuple2 = tuple1

In [16]: tuple2
Uscita [16]: (10, 20, 30)

La concatenazione della tupla (40, 50) a tuple1 crea una nuova tupla, quindi assegna un file
riferimento ad esso alla variabile tuple1 — tuple2 si riferisce ancora alla tupla originale:

lecca qui per visualizzare l'immagine del codice

In [17]: tuple1 + = (40 , 50 )

C
Pagina 180
In [18]: tuple1
Uscita [18]: (10, 20, 30, 40, 50)

In [19]: tuple2
Uscita [19]: (10, 20, 30)

Per una stringa o una tupla, l'elemento a destra di + = deve essere rispettivamente una stringa o una tupla—
la miscelazione dei tipi causa un TypeError.

Aggiunta di tuple agli elenchi


Puoi usare + = per aggiungere una tupla a un elenco:

lecca qui per visualizzare l'immagine del codice

In [20]: numeri = [ 1 , 2 , 3 , 4 , 5 ]

In [21]: numeri + = ( 6 , 7 )

In [22]: numeri
Fuori [22]: [1, 2, 3, 4, 5, 6, 7]

Le tuple possono contenere oggetti mobili

Creiamo una student_tuple con un nome, un cognome e un elenco di voti:

lecca qui per visualizzare l'immagine del codice

In [23]: student_tuple = ( 'Amanda' , 'Blue' , [ 98 , 75 , 87 ])

Anche se la tupla è immutabile, il suo elemento di lista è mutabile:

lecca qui per visualizzare l'immagine del codice

In [24]: student_tuple [ 2 ] [ 1 ] = 85

In [25]: student_tuple
Uscita [25]: ('Amanda', 'Blue', [98, 85, 87])

Nel nome doubleubscripted student_tuple [2] [1], Python views

student_tuple [2] come elemento della tupla contenente l'elenco [98, 75, 87],
quindi utilizza [1] per accedere all'elemento dell'elenco contenente 75. L'assegnazione nello snippet [24]

C
Pagina 181
sostituisce quel grado con 85.

5.4 SEQUENZE DI DISIMBALLAGGIO


Il capitolo precedente ha introdotto lo spacchettamento delle tuple. Puoi decomprimere qualsiasi sequenza
elementi assegnando la sequenza a un elenco di variabili separato da virgole. UN
ValueError si verifica se il numero di variabili a sinistra del simbolo di assegnazione è
non identico al numero di elementi nella sequenza a destra:

lecca qui per visualizzare l'immagine del codice

In [1]: student_tuple = ( 'Amanda' , [ 98 , 85 , 87 ])

In [2]: first_name, grades = student_tuple

In [3]: first_name
Uscita [3]: "Amanda"

In [4]: ​voti
Uscita [4]: ​[98, 85, 87]

Il codice seguente decomprime una stringa, un elenco e una sequenza prodotta da intervallo:

lecca qui per visualizzare l'immagine del codice

In [5]: primo, secondo = "ciao"


In [6]: print (f ' {first} {second} ' )
Ciao

In [7]: numero1, numero2, numero3 = [2 , 3 , 5 ]

In [8]: print (f ' {number1} {number2} {number3} ' )


235

In [9]: numero1, numero2, numero3 = intervallo (10 , 40 , 10 )

In [10]: print (f ' {number1} {number2} {number3} ' )


10 20 30

Scambio di valori tramite imballaggio e disimballaggio

È possibile scambiare i valori di due variabili utilizzando la sequenza di compressione e decompressione:

lecca qui per visualizzare l'immagine del codice

C
Pagina 182
In [11]: numero1 = 99

In [12]: numero2 = 22

In [13]: numero1, numero2 = (numero2, numero1)

In [14]: print (f 'numero1 = {} number1 ; numero2 = {} numero2 ' )


numero1 = 22; numero2 = 99

Accesso sicuro a indici e valori con enumerazione di funzioni incorporate

In precedenza, abbiamo chiamato range per produrre una sequenza di valori di indice, quindi abbiamo aperto l'elenco
elementi in un ciclo for utilizzando i valori di indice e l'operatore di sottoscrizione ([]). Questo
è soggetto a errori perché potresti passare gli argomenti sbagliati a range. Se qualsiasi valore
prodotto da intervallo è un indice in uscita, utilizzarlo come indice provoca un

IndexError.

Il meccanismo preferito per accedere all'indice e al valore di un elemento è il builtin


funzione enumerate . Questa funzione riceve un iterabile e crea un iteratore che, per
ogni elemento, restituisce una tupla contenente l'indice e il valore dell'elemento. Il seguente
il codice usa l' elenco delle funzioni incorporate per creare un elenco contenente i risultati di enumerate:

lecca qui per visualizzare l'immagine del codice

In [15]: colors = [ "red" , "orange" , "yellow" ]

In [16]: list (enumerate (colors))


Out [16]: [(0, 'red'), (1, 'orange'), (2, 'yellow')]

Allo stesso modo la funzione incorporata tupla crea una tupla da una sequenza:

lecca qui per visualizzare l'immagine del codice

In [17]: tuple (enumerate (colors))


Out [17]: ((0, 'red'), (1, 'orange'), (2, 'yellow'))

Il seguente ciclo for decomprime ogni tupla restituita da enumerate nelle variabili

indice e valore e li visualizza:

lecca qui per visualizzare l'immagine del codice


In [18]: for index, value in enumerate (colors):

...: print (f ' {index} : {value} ' ) Pagina 183


...:
0: rosso
1: arancione
2: giallo

Creazione di un grafico a barre primitivo

Lo script seguente crea un grafico a barre primitivo di cui è composta la lunghezza di ciascuna barra
asterischi (*) ed è proporzionale al valore dell'elemento corrispondente della lista. Noi usiamo il
funzione enumerate per accedere in modo sicuro agli indici e ai valori dell'elenco. Per eseguire questo esempio,
passare alla cartella degli esempi ch05 di questo capitolo, quindi immettere:

ipython fig05_01.py

oppure, se sei già in IPython, usa il comando:

esegui fig05_01.py

lecca qui per visualizzare l'immagine del codice

1 # fig05_01.py
2 "" "Visualizzazione di un grafico a barre" ""
3 numeri = [ 19 , 3 , 15 , 7 , 11 ]
4
5 print ( '\ nCreazione di un grafico a barre da numeri:' )
6 print (f 'Indice { "Valore" :> 8 } Barra' )
7
8 per indice, valore in enumerate (numeri):
9 print (f ' {index:> 5 } {value:> 8 } { "*" * value} ' )

lecca qui per visualizzare l'immagine del codice

Creazione di un grafico a barre da numeri:


Barra dei valori dell'indice
0 19 *******************
1 3 ***
2 15 ***************
3 7 *******
4 11 ***********

L'istruzione for usa enumerate per ottenere l'indice e il valore di ogni elemento, quindi

C
Pagina 184
visualizza una riga formattata contenente l'indice, il valore dell'elemento e il corrispondente
barra degli asterischi. L'espressione

"*" * valore

crea una stringa composta da asterischi di valore. Quando viene utilizzato con una sequenza, il file
L'operatore di moltiplicazione (*) ripete la sequenza, in questo caso la stringa "*" - valore

volte. Più avanti in questo capitolo, utilizzeremo le librerie opensource Seaborn e Matplotlib
per visualizzare una visualizzazione del grafico a barre di qualità della pubblicazione.
5.5 SEQUENCE SLICING
È possibile suddividere sequenze per creare nuove sequenze dello stesso tipo contenenti sottoinsiemi di
gli elementi originali. Le operazioni di slice possono modificare le sequenze mutabili, quelle che lo fanno
non modificare una sequenza funziona in modo identico per elenchi, tuple e stringhe.

Specifica di una sezione con indici iniziale e finale


Creiamo una sezione composta dagli elementi agli indici da 2 a 5 di un elenco:

lecca qui per visualizzare l'immagine del codice

In [1]: numeri = [ 2 , 3 , 5 , 7 , 11 , 13 , 17 , 19 ]

In [2]: numeri [ 2 : 6 ]
Uscita [2]: [5, 7, 11, 13]

La sezione copia gli elementi dall'indice iniziale a sinistra dei due punti (2) fino a, ma
escluso, l' indice finale a destra dei due punti (6). L'elenco originale non lo è
modificato.

Specifica di una sezione con solo un indice finale

Se ometti l'indice iniziale, viene assunto 0. Quindi, i numeri di slice [: 6] sono equivalenti a
i numeri di slice [0: 6]:

lecca qui per visualizzare l'immagine del codice

In [3]: numeri [: 6 ]
Uscita [3]: [2, 3, 5, 7, 11, 13]

In [4]: ​numeri [ 0 : 6 ]

Uscita [4]: ​[2, 3, 5, 7, 11, 13] Pagina 185

Specifica di una sezione con solo un indice iniziale

Se ometti l'indice finale, Python assume la lunghezza della sequenza (8 qui), quindi snippet

La sezione di [5] contiene gli elementi dei numeri agli indici 6 e 7:

lecca qui per visualizzare l'immagine del codice

In [5]: numeri [ 6 :]
Uscita [5]: [17, 19]

In [6]: numbers [ 6 : len (numbers)]


Uscita [6]: [17, 19]

Specificare una sezione senza indici

L'omissione di entrambi gli indici di inizio e di fine copia l'intera sequenza:

lecca qui per visualizzare l'immagine del codice

In [7]: numeri [:]


Fuori [7]: [2, 3, 5, 7, 11, 13, 17, 19]

Sebbene le sezioni creino nuovi oggetti, le sezioni creano copie superficiali degli elementi, ovvero
copiano i riferimenti degli elementi ma non gli oggetti a cui puntano. Quindi, nello snippet
sopra, gli elementi della nuova lista si riferiscono agli stessi oggetti degli elementi della lista originale,
piuttosto che separare le copie. Nella "Programmazione ArrayOriented con NumPy"
capitolo, spiegheremo la copia profonda , che copia effettivamente gli oggetti referenziati
stessi e indicheremo quando è preferibile la copia profonda.

Affettare con passaggi

Il codice seguente usa un passaggio di 2 per creare una sezione con ogni altro elemento di

numeri:

In [8]: numeri [:: 2 ]


Uscita [8]: [2, 5, 11, 17]

Abbiamo omesso gli indici di inizio e di fine, quindi si assumono 0 e len (numeri),
rispettivamente.

S
C licing con indici e passaggi negativi

Affettare con indici e passaggi negativi Pagina 186

È possibile utilizzare un passaggio negativo per selezionare le sezioni in ordine inverso . Il codice seguente
crea in modo conciso un nuovo elenco in ordine inverso:

lecca qui per visualizzare l'immagine del codice

In [9]: numeri [:: 1 ]


Fuori [9]: [19, 17, 13, 11, 7, 5, 3, 2]

Questo è equivalente a:

lecca qui per visualizzare l'immagine del codice

In [10]: numeri [ 1 : 9 : 1 ]
Fuori [10]: [19, 17, 13, 11, 7, 5, 3, 2]

Modifica degli elenchi tramite le sezioni


È possibile modificare un elenco assegnandogli una porzione: il resto dell'elenco rimane invariato. Il
il codice seguente sostituisce i primi tre elementi dei numeri, lasciando il resto invariato:

lecca qui per visualizzare l'immagine del codice

In [11]: numeri [ 0 : 3 ] = [ "due" , "tre" , "cinque" ]

In [12]: numeri
Uscita [12]: ["due", "tre", "cinque", 7, 11, 13, 17, 19]

Quanto segue elimina solo i primi tre elementi di numeri assegnando un vuoto
list alla sezione a tre elementi:

lecca qui per visualizzare l'immagine del codice

In [13]: numeri [ 0 : 3 ] = []

In [14]: numeri
Uscita [14]: [7, 11, 13, 17, 19]

Quanto segue assegna gli elementi di una lista a una porzione di ogni altro elemento di numeri:
lecca qui per visualizzare l'immagine del codice

C
Pagina 187
In [15]: numeri = [ 2 , 3 , 5 , 7 , 11 , 13 , 17 , 19 ]

In [16]: numeri [:: 2 ] = [ 100 , 100 , 100 , 100 ]

In [17]: numeri
Fuori [17]: [100, 3, 100, 7, 100, 13, 100, 19]

In [18]: id (numeri)
Uscita [18]: 4434456648

Eliminiamo tutti gli elementi in numeri, lasciando vuoto l'elenco esistente :

lecca qui per visualizzare l'immagine del codice

In [19]: numeri [:] = []

In [20]: numeri
Fuori [20]: []

In [21]: id (numeri)
Uscita [21]: 4434456648

Eliminare il contenuto dei numeri (frammento [19]) è diverso dall'assegnarne uno nuovo
elenco vuoto [] (snippet [22]). Per dimostrarlo, mostriamo l'identità dei numeri dopo ciascuno
operazione. Le identità sono diverse, quindi rappresentano oggetti separati in memoria:

In [22]: numeri = []

In [23]: numeri
Uscita [23]: []

In [24]: id (numeri)
Uscita [24]: 4406030920

Quando assegni un nuovo oggetto a una variabile (come nello snippet [21]), lo farà l'oggetto originale
essere raccolti nella spazzatura se nessun'altra variabile vi fa riferimento.

5.6 DICHIARAZIONE DEL CANC


L' istruzione del può anche essere utilizzata per rimuovere elementi da un elenco e per eliminarli
variabili dalla sessione interattiva. Puoi rimuovere l'elemento in qualsiasi indice valido o
l'elemento (i) da qualsiasi slice valido.

Eliminazione dell'elemento in un indice di elenco specifico


C
Eliminazione dell'elemento in un indice di elenco specifico
Pagina 188
et crea una lista, quindi usa del per rimuovere il suo ultimo elemento:

lecca qui per visualizzare l'immagine del codice

In [1]: numbers = list (range ( 0 , 10 ))

In [2]: numeri
Uscita [2]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [3]: del numbers [ 1 ]

In [4]: ​numeri
Uscita [4]: ​[0, 1, 2, 3, 4, 5, 6, 7, 8]

Eliminazione di una sezione da un elenco

Quanto segue elimina i primi due elementi dell'elenco:

In [5]: del numeri [ 0 : 2 ]

In [6]: numeri
Fuori [6]: [2, 3, 4, 5, 6, 7, 8]

Di seguito viene utilizzato un passaggio nella sezione per eliminare ogni altro elemento dall'intero elenco:

In [7]: del numbers [:: 2 ]

In [8]: numeri
Uscita [8]: [3, 5, 7]

Eliminazione di una sezione che rappresenta l'intero elenco

Il codice seguente elimina tutti gli elementi dell'elenco:

In [9]: del numbers [:]

In [10]: numeri
Fuori [10]: []

Eliminazione di una variabile dalla sessione corrente

L'istruzione del può eliminare qualsiasi variabile. Eliminiamo i numeri dall'interattivo


session, quindi tenta di visualizzare il valore della variabile, causando un'eccezione NameError:

C
L
Pagina 189
lecca qui per visualizzare l'immagine del codice

In [11]: del numbers

In [12]: numeri

NameError Traceback (la chiamata più recente per ultima


ipythoninput12426f8401232b> in <module> ()
> 1 numeri

NameError : il nome "numeri" non è definito

5.7 PASSAGGIO DELLE LISTE ALLE FUNZIONI


Nell'ultimo capitolo abbiamo accennato al fatto che tutti gli oggetti vengono passati per riferimento e
ha dimostrato di passare un oggetto immutabile come argomento di una funzione. Qui discutiamo
ulteriori riferimenti esaminando cosa accade quando un programma passa un elenco modificabile
oggetto a una funzione.

Passaggio di un intero elenco a una funzione


Considera la funzione modify_elements, che riceve un riferimento a un elenco e
moltiplica ciascuno dei valori degli elementi della lista per 2:

lecca qui per visualizzare l'immagine del codice


In [1]: def modify_elements (elementi):
...: "" "" Moltiplica tutti i valori degli elementi negli elementi per 2. "" "
...: for i in range (len (items)):
...: elementi [i] * = 2
...:

In [2]: numeri = [ 10 , 3 , 7 , 1 , 9 ]

In [3]: modify_elements (numeri)

In [4]: ​numeri
Uscita [4]: ​[20, 6, 14, 2, 18]

Il parametro degli elementi della funzione modify_elements riceve un riferimento all'originale


list, quindi l'istruzione nella suite del ciclo modifica ogni elemento nell'oggetto list originale.

Passaggio di una tupla a una funzione

C
<

Pagina 190
Quando si passa una tupla a una funzione, tentando di modificare l'immutabile della tupla
elementi risulta in un TypeError:

lecca qui per visualizzare l'immagine del codice

In [5]: numbers_tuple = ( 10 , 20 , 30 )

In [6]: numbers_tuple
Uscita [6]: (10, 20, 30)

In [7]: modify_elements (numbers_tuple)

TypeError Traceback (la chiamata più recente per ultima


ipythoninput79339741cd595> in <module> ()
> 1 modify_elements (numbers_tuple)

<ipythoninput127acb8f8f44c> in modify_elements (elementi)


2 "" "" Moltiplica tutti i valori degli elementi negli elementi per 2. "" "
3 per i in range (len (articoli)):
> 4 elementi [i] * = 2
5
6

TypeError : l'oggetto 'tuple' non supporta l'assegnazione di elementi

Ricorda che le tuple possono contenere oggetti mutabili, come gli elenchi. Quegli oggetti possono ancora essere
modificato quando una tupla viene passata a una funzione.

Una nota per quanto riguarda i trackback

Il traceback precedente mostra i due frammenti che hanno portato a TypeError. Il primo è
chiamata di funzione di snippet [7]. Il secondo è la definizione della funzione di snippet [1]. Linea
i numeri precedono il codice di ogni snippet. Abbiamo dimostrato per lo più frammenti di una singola riga.
Quando si verifica un'eccezione in uno snippet di questo tipo, è sempre preceduta da> 1,
indicando che la riga 1 (l'unica riga dello snippet) ha causato l'eccezione. Snippet multilinea
come la definizione di modify_elements mostra i numeri di riga consecutivi che iniziano da 1.
La notazione> 4 sopra indica che l'eccezione si è verificata nella riga 4 di

modificare_elementi. Non importa quanto sia lungo il traceback, l'ultima riga di codice con

> ha causato l'eccezione.

5.8 ELENCHI DI SMISTAMENTO


L'ordinamento consente di disporre i dati in ordine crescente o decrescente.

S
C ortare un elenco in ordine crescente
<

Ordinamento di un elenco in ordine crescente Pagina 191

Il metodo di ordinamento elenco modifica un elenco per disporre i suoi elementi in ordine crescente:

lecca qui per visualizzare l'immagine del codice

In [1]: numeri = [ 10 , 3 , 7 , 1 , 9 , 4 , 2 , 8 , 5 , 6 ]

In [2]: numbers.sort ()

In [3]: numeri
Fuori [3]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Ordinamento di un elenco in ordine decrescente

Per ordinare un elenco in ordine decrescente, chiamare il metodo dell'elenco con la parola chiave opzionale
argomento inverso impostato su True (False è l'impostazione predefinita):

lecca qui per visualizzare l'immagine del codice

In [4]: ​numbers.sort (reverse = True )

In [5]: numeri
Uscita [5]: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

Funzione incorporata ordinata

La funzione incorporata ordinata restituisce un nuovo elenco contenente i suoi elementi ordinati
sequenza di argomenti: la sequenza originale non è modificata . Il codice seguente
mostra la funzione ordinata per un elenco, una stringa e una tupla:

lecca qui per visualizzare l'immagine del codice

In [6]: numeri = [ 10 , 3 , 7 , 1 , 9 , 4 , 2 , 8 , 5 , 6 ]

In [7]: ascending_numbers = ordinato (numeri)

In [8]: ascending_numbers
Fuori [8]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

In [9]: numeri
Fuori [9]: [10, 3, 7, 1, 9, 4, 2, 8, 5, 6]

In [10]: letters = "fadgchjebi"

In [11]: lettere_ascendenti = ordinate (lettere)

C
Pagina 192
In [12]: ascending_letters
Fuori [12]: ['a', 'b', 'c', 'd', 'e', ​'f', 'g', 'h', 'i', 'j']

In [13]: lettere
Uscita [13]: "fadgchjebi"

In [14]: colors = ( "red" , "orange" , "yellow" , "green" , "blue" )

In [15]: ascending_colors = ordinato (colori)

In [16]: ascending_colors
Uscita [16]: ["blu", "verde", "arancione", "rosso", "giallo"]
In [17]: colori
Fuori [17]: ("rosso", "arancione", "giallo", "verde", "blu")

Utilizzare l'argomento della parola chiave opzionale reverse con il valore True per ordinare gli elementi
in ordine decrescente.

5.9 RICERCA DELLE SEQUENZE


Spesso, ti consigliamo di determinare se una sequenza (come un elenco, una tupla o una stringa)
contiene un valore che corrisponde a un particolare valore chiave . La ricerca è il processo di
individuare una chiave.

Indice del metodo elenco

L' indice del metodo elenco accetta come argomento una chiave di ricerca, il valore da individuare nell'elenco,
quindi cerca nell'elenco dall'indice 0 e restituisce l'indice del primo elemento
che corrisponde alla chiave di ricerca:

lecca qui per visualizzare l'immagine del codice

In [1]: numeri = [ 3 , 7 , 1 , 4 , 2 , 8 , 5 , 6 ]

In [2]: numbers.index ( 5 )
Fuori [2]: 6

Si verifica un'eccezione ValueError se il valore che stai cercando non è nell'elenco.

Specificare l'indice iniziale di una ricerca

Utilizzando gli argomenti facoltativi dell'indice del metodo, è possibile cercare un sottoinsieme di elementi di una lista.
Puoi usare * = per moltiplicare una sequenza , ovvero aggiungere una sequenza a se stessa multipla

C
Pagina 193
volte. Dopo il seguente frammento, i numeri contengono due copie dell'elenco originale
Contenuti:

lecca qui per visualizzare l'immagine del codice

In [3]: numeri * = 2

In [4]: ​numeri
Uscita [4]: ​[3, 7, 1, 4, 2, 8, 5, 6, 3, 7, 1, 4, 2, 8, 5, 6]

Il codice seguente ricerca nell'elenco aggiornato il valore 5 a partire dall'indice 7 e


continuando fino alla fine dell'elenco:

In [5]: numbers.index ( 5 , 7 )
Uscita [5]: 14

Specificare gli indici di inizio e fine di una ricerca


Se si specificano gli indici iniziale e finale, l'indice esegue la ricerca dall'inizio
indice fino alla posizione dell'indice finale, ma esclusa. La chiamata all'indicizzazione in snippet

[5]:

numbers.index ( 5 , 7 )
assume la lunghezza dei numeri come terzo argomento opzionale ed è equivalente a:

lecca qui per visualizzare l'immagine del codice

numbers.index ( 5 , 7 , len (numeri))

Quanto segue cerca il valore 7 nell'intervallo di elementi con indici da 0 a 3:

lecca qui per visualizzare l'immagine del codice

In [6]: numbers.index ( 7 , 0 , 4 )
Fuori [6]: 1

Operatori in e non in

L'operatore verifica se l'iterabile dell'operando destro contiene il valore dell'operando sinistro:

C
Pagina 194
In [7]: 1000 in numeri
Fuori [7]: Falso

In [8]: 5 in numeri
Out [8]: Vero

Allo stesso modo, operator not in verifica se l'iterabile dell'operando destro non contiene
il valore dell'operando sinistro:

In [9]: 1000 non in numeri


Out [9]: Vero

In [10]: 5 non in numeri


Out [10]: Falso

Utilizzo dell'operatore in per impedire un ValueError

È possibile utilizzare l'operatore in per assicurarsi che le chiamate all'indice del metodo non abbiano come risultato

ValueErrors per le chiavi di ricerca che non sono nella sequenza corrispondente:

lecca qui per visualizzare l'immagine del codice

In [11]: chiave = 1000

In [12]: se chiave in numeri:


...: print (f 'trovato {key} all'indice {numbers.index (search_key)} ' )
...: altro :
...: print (f ' {key} non trovato' )
...:
1000 non trovato

Funzioni integrate qualsiasi e tutte

A volte devi semplicemente sapere se un elemento in un iterabile è True o

se tutti gli elementi sono veri. La funzione incorporata any restituisce True se qualsiasi elemento in
il suo argomento iterabile è True. La funzione incorporata restituisce tutto True se tutti gli elementi nella sua
argomenti iterabili sono True. Ricorda che i valori diversi da zero sono True e 0 è False. Non
anche gli oggetti iterabili vuoti restituiscono True, mentre qualsiasi iterabile vuoto restituisce

Falso. Le funzioni any and all sono ulteriori esempi di iterazione interna in
programmazione in stile funzionale.
5
C .10 ALTRI METODI DI ELENCO
Pagina 195
5.10 ALTRI METODI DI ELENCO
Gli elenchi hanno anche metodi che aggiungono e rimuovono elementi. Considera l'elenco
color_names:

lecca qui per visualizzare l'immagine del codice

In [1]: color_names = [ 'orange' , 'yellow' , 'green' ]

Inserimento di un elemento in un indice di elenco specifico


Il metodo insert aggiunge un nuovo elemento a un indice specificato. Il seguente inserisce "rosso" in
indice 0:

lecca qui per visualizzare l'immagine del codice

In [2]: color_names.insert ( 0 , "red" )

In [3]: color_names
Uscita [3]: ["rosso", "arancione", "giallo", "verde"]

Aggiunta di un elemento alla fine di un elenco

Puoi aggiungere un nuovo elemento alla fine di un elenco con il metodo append :

lecca qui per visualizzare l'immagine del codice

In [4]: ​color_names.append ( "blue" )

In [5]: color_names
In uscita [5]: ["rosso", "arancione", "giallo", "verde", "blu"]

Aggiunta di tutti gli elementi di una sequenza alla fine di un elenco

Usa il metodo list extended per aggiungere tutti gli elementi di un'altra sequenza alla fine di un elenco:

lecca qui per visualizzare l'immagine del codice

In [6]: color_names.extend ([ 'indigo' , 'violet' ])

In [7]: color_names
Fuori [7]: ["rosso", "arancione", "giallo", "verde", "blu", "indaco", "viola"]

C
Pagina 196
Questo è l'equivalente dell'uso di + =. Il codice seguente aggiunge tutti i caratteri di una stringa
quindi tutti gli elementi di una tupla in una lista:

lecca qui per visualizzare l'immagine del codice

In [8]: sample_list = []

In [9]: s = "abc"

In [10]: sample_list.extend (s)


In [11]: sample_list
Uscita [11]: ['a', 'b', 'c']

In [12]: t = ( 1 , 2 , 3 )

In [13]: sample_list.extend (t)

In [14]: sample_list
Uscita [14]: ['a', 'b', 'c', 1, 2, 3]

Piuttosto che creare una variabile temporanea, come t, per memorizzare una tupla prima di aggiungerla a
una lista, potresti voler passare direttamente una tupla da estendere. In questo caso, la tupla
le parentesi sono obbligatorie, perché extension si aspetta un argomento iterabile:

lecca qui per visualizzare l'immagine del codice

In [15]: sample_list.extend (( 4 , 5 , 6 )) # nota le parentesi extra

In [16]: sample_list
Fuori [16]: ['a', 'b', 'c', 1, 2, 3, 4, 5, 6]

Se si omettono le parentesi richieste si verifica un TypeError.

Rimozione della prima occorrenza di un elemento in un elenco


Il metodo remove elimina il primo elemento con un valore specificato: si verifica un'eccezione ValueError

se l'argomento di remove non è nell'elenco:

lecca qui per visualizzare l'immagine del codice

In [17]: color_names.remove ( 'green' )

In [18]: color_names
Fuori [18]: ["rosso", "arancione", "giallo", "blu", "indaco", "viola"]

C
Pagina 197

Svuotamento di un elenco

Per eliminare tutti gli elementi in un elenco, chiama il metodo clear :

In [19]: color_names.clear ()

In [20]: color_names
Fuori [20]: []

Questo è l'equivalente dell'assegnazione slice mostrata in precedenza

color_names [:] = []

Conteggio del numero di occorrenze di un elemento

Il conteggio del metodo List cerca il suo argomento e restituisce il numero di volte che lo è
trovato:

lecca qui per visualizzare l'immagine del codice

In [21]: risposte = [ 1 , 2 , 5 , 4 , 3 , 5 , 2 , 1 , 3 , 3 ,
...: 1, 4, 3, 3, 3, 2, 3, 3, 2, 2]
...:
In [22]: per i in serie ( 1 , 6 ):
...: print (f ' {i} compare {responses.count (i)} volte in responses'
...:
1 appare 3 volte nelle risposte
2 appare 5 volte nelle risposte
3 appare 8 volte nelle risposte
4 appare 2 volte nelle risposte
5 appare 2 volte nelle risposte

Inversione degli elementi di una lista

Il metodo List reverse inverte il contenuto di un elenco in posizione, invece di creare un file
copia invertita, come abbiamo fatto con una fetta in precedenza:

lecca qui per visualizzare l'immagine del codice

In [23]: color_names = [ 'red' , 'orange' , 'yellow' , 'green' , 'blue' ]

In [24]: color_names.reverse () Pagina 198

In [25]: color_names
Fuori [25]: ["blu", "verde", "giallo", "arancione", "rosso"]

Copia di un elenco

La copia del metodo elenco restituisce un nuovo elenco contenente una copia superficiale dell'elenco originale:

lecca qui per visualizzare l'immagine del codice

In [26]: copied_list = color_names.copy ()

In [27]: copied_list
Uscita [27]: ["blu", "verde", "giallo", "arancione", "rosso"]

Questo è equivalente all'operazione slice precedentemente dimostrata:

copied_list = color_names [:]

5.11 SIMULAZIONE DI PILE CON LISTE


Il capitolo precedente ha introdotto lo stack functioncall. Python non ha un file build
nel tipo di pila, ma puoi pensare a una pila come a un elenco vincolato. Si preme con lista
metodo append, che aggiunge un nuovo elemento alla fine della lista. Si apre utilizzando la lista
metodo pop senza argomenti, che rimuove e restituisce l'elemento alla fine del file
elenco.

Creiamo un elenco vuoto chiamato stack, inseriamo (aggiungici) due stringhe su di esso, quindi pop
le stringhe per confermare che sono state recuperate in ordine lastin, firstout (LIFO):

lecca qui per visualizzare l'immagine del codice

n [1]: stack = []

In [2]: stack.append ( 'red' )

In [3]: stack
Fuori [3]: ["rosso"]

In [4]: ​stack.append ( 'green' )


In [5]: stack
Uscita [5]: ["rosso", "verde"]

C
Pagina 199
In [6]: stack.pop ()
Uscita [6]: "verde"

In [7]: stack
Fuori [7]: ["rosso"]

In [8]: stack.pop ()
Fuori [8]: "rosso"

In [9]: stack
Fuori [9]: []

In [10]: stack.pop ()

IndexError Traceback (la chiamata più recente per ultima)


<ipythoninput1050ea7ec13fbe> in <module> ()
> 1 stack.pop ()

IndexError : pop da un elenco vuoto

o ogni frammento di pop, viene visualizzato il valore che pop rimuove e restituisce. Popping
da uno stack vuoto provoca un IndexError, proprio come accedere a un elenco inesistente

elemento con []. Per evitare un IndexError, assicurati che len (stack) sia maggiore di

0 prima di chiamare pop. Puoi esaurire la memoria se continui a spingere gli elementi più velocemente di
li fai scoppiare.

Puoi anche utilizzare un elenco per simulare un'altra raccolta popolare chiamata coda in cui
si inserisce sul retro e si cancella dal davanti. Gli elementi vengono recuperati dalle code in
ordine firstin, firstout (FIFO) .

5.12 COMPRENSIONI DELLA LISTA


Qui, si continua a discutere functionalstyle caratteristiche con list comprehension -a
notazione concisa e conveniente per creare nuovi elenchi. Le comprensioni di elenco possono sostituire
molte per le istruzioni che iterano su sequenze esistenti e creano nuovi elenchi, come:

lecca qui per visualizzare l'immagine del codice

In [1]: list1 = []

In [2]: per elemento in serie ( 1 , 6 ):


...: list1.append (elemento)
...:

In [3]: list1

F
C

Fuori [3]: [1, 2, 3, 4, 5] Pagina 200

Utilizzo della comprensione di un elenco per creare un elenco di numeri interi

Possiamo eseguire la stessa operazione in una singola riga di codice con una comprensione dell'elenco:

lecca qui per visualizzare l'immagine del codice

In [4]: list2 = [elemento per elemento in serie ( 1 , 6 )]


In [5]: list2
Uscita [5]: [1, 2, 3, 4, 5]

Come l'istruzione for dello snippet [2], la clausola for della lista di comprensione

per elemento in serie ( 1 , 6 )

itera sulla sequenza prodotta da range (1, 6). Per ogni articolo, l'elenco
comprensione valuta l'espressione a sinistra della clausola for e inserisce il
il valore dell'espressione (in questo caso, l'elemento stesso) nel nuovo elenco. Particolare di Snippet [4]
la comprensione avrebbe potuto essere espressa in modo più conciso utilizzando l'elenco delle funzioni:

list2 = list (range ( 1 , 6 ))

Mappatura: esecuzione di operazioni in un'espressione di comprensione della lista

Un'espressione di comprensione dell'elenco può eseguire attività, come calcoli, quella mappa
elementi a nuovi valori (possibilmente di diverso tipo). La mappatura è una funzionalità comune
operazione di programmazione dello stile che produce un risultato con lo stesso numero di elementi
come i dati originali mappati. La seguente comprensione associa ogni valore al suo
cubo con l'espressione item ** 3:

lecca qui per visualizzare l'immagine del codice

In [6]: list3 = [item ** 3 for item in range ( 1 , 6 )]

In [7]: list3
Uscita [7]: [1, 8, 27, 64, 125]

Filtraggio: elenca le comprensioni con clausole if

C
Pagina 201
Un'altra operazione di programmazione in stile funzionale comune è il filtraggio degli elementi in
seleziona solo quelli che corrispondono a una condizione. Questo in genere produce un elenco con meno
elementi rispetto ai dati filtrati. Per eseguire questa operazione in una lista di comprensione, utilizzare if
clausola . Quanto segue include in list4 solo i valori pari prodotti da for
clausola:

lecca qui per visualizzare l'immagine del codice

In [8]: elenco4 = [elemento per elemento in serie ( 1 , 11 ) se l'elemento% 2 == 0 ]

In [9]: list4
Fuori [9]: [2, 4, 6, 8, 10]

Comprensione delle liste che elabora gli elementi di un'altra lista


La clausola for può elaborare qualsiasi iterabile. Creiamo un elenco di stringhe minuscole e usiamo un file

comprensione dell'elenco per creare un nuovo elenco contenente le loro versioni maiuscole:

lecca qui per visualizzare l'immagine del codice

In [10]: colors = [ "red" , "orange" , "yellow" , "green" , "blue" ]

In [11]: colors2 = [item.upper () for item in colors]

In [12]: colors2
In uscita [12]: ["ROSSO", "ARANCIONE", "GIALLO", "VERDE", "BLU"]

In [13]: colori
Uscita [13]: ["rosso", "arancione", "giallo", "verde", "blu"]

5.13 ESPRESSIONI DEL GENERATORE


Un generatore di espressione è simile a un elenco di comprensione, ma crea un iterabile
oggetto generatore che produce valori su richiesta . Questo è noto come pigro
valutazione . Le comprensioni di elenchi utilizzano valutazioni avide: creano elenchi
immediatamente quando li esegui. Per un gran numero di elementi, la creazione di un elenco può
richiede tempo e memoria sostanziali. Quindi le espressioni del generatore possono ridurre i file
consumo di memoria e migliorare le prestazioni se l'intero elenco non è necessario in una volta.

Le espressioni del generatore hanno le stesse funzionalità delle comprensioni di elenco, ma tu


definirli tra parentesi invece che tra parentesi quadre. L'espressione del generatore in
snippet [2] quadrati e restituisce solo i valori dispari in numeri:

C
Pagina 202
lecca qui per visualizzare l'immagine del codice

In [1]: numeri = [ 10 , 3 , 7 , 1 , 9 , 4 , 2 , 8 , 5 , 6 ]

In [2]: per il valore in (x ** 2 per x in numeri se x% 2 ! = 0 ):


...: print (value, end = '' )
...:
9 49 1 81 25

Per mostrare che un'espressione del generatore non crea un elenco, assegniamo il precedente
l'espressione del generatore di snippet su una variabile e valuta la variabile:

lecca qui per visualizzare l'immagine del codice

In [3]: squares_of_odds = (x ** 2 for x in numbers if x% 2 ! = 0 )

In [3]: squares_of_odds
Uscita [3]: <oggetto generatore <genexpr> a 0x1085e84c0>

Il testo "oggetto generatore <genexpr>" indica che square_of_odds è un file


oggetto generatore creato da un'espressione generatore (genexpr).

5.14 FILTRO, MAPPA E RIDUCI


La sezione precedente ha introdotto diverse caratteristiche dello stile funzionale: elenco
comprensioni, filtraggio e mappatura. Qui mostriamo il filtro integrato e

funzioni map per il filtraggio e la mappatura, rispettivamente. Continuiamo a discutere


riduzioni in cui si elabora una raccolta di elementi in un singolo valore, ad esempio
il loro conteggio, totale, prodotto, medio, minimo o massimo.

Filtrare i valori di una sequenza con la funzione di filtro incorporata

Usiamo il filtro della funzione incorporata per ottenere i valori dispari in numeri:

lecca qui per visualizzare l'immagine del codice

In [1]: numeri = [ 10 , 3 , 7 , 1 , 9 , 4 , 2 , 8 , 5 , 6 ]

In [2]: def is_odd (x):


...: "" "Restituisce True solo se x è dispari." ""
...: restituisce x% 2 ! = 0
...:

In [3]: list (filter (is_odd, numbers)) Pagina 203


Uscita [3]: [3, 7, 1, 9, 5]

Come i dati, le funzioni Python sono oggetti che puoi assegnare a variabili, passare ad altre
funzioni e ritorno dalle funzioni. Funzioni che ricevono altre funzioni come
gli argomenti sono una capacità di stile funzionale chiamata funzioni di ordine superiore . Per
Ad esempio, il primo argomento del filtro deve essere una funzione che riceve un argomento e
restituisce True se il valore deve essere incluso nel risultato. La funzione is_odd restituisce

Vero se il suo argomento è dispari. La funzione di filtro chiama is_odd una volta per ogni valore in
il suo secondo argomento è iterabile (numeri). Le funzioni di ordine superiore possono anche restituire un file
funzione di conseguenza.

Il filtro della funzione restituisce un iteratore, quindi i risultati del filtro non vengono prodotti fino a quando non lo fai
itera attraverso di loro. Questo è un altro esempio di valutazione pigra. Nello snippet [3],
elenco di funzioni itera i risultati e crea un elenco che li contiene. Noi possiamo
ottenere gli stessi risultati di cui sopra utilizzando una lista di comprensione con una clausola if:

lecca qui per visualizzare l'immagine del codice

In [4]: ​[item for item in numbers if is_odd (item)]


Uscita [4]: ​[3, 7, 1, 9, 5]

Utilizzo di un lambda invece di una funzione

Per funzioni semplici come is_odd che restituiscono solo il valore di una singola espressione , puoi farlo
usa un'espressione lambda (o semplicemente una lambda ) per definire la funzione inline where
è necessario, in genere quando viene passato a un'altra funzione:

lecca qui per visualizzare l'immagine del codice

In [5]: list (filter ( lambda x: x% 2 ! = 0 , numbers))


Uscita [5]: [3, 7, 1, 9, 5]

Passiamo il valore di ritorno del filtro (un iteratore) all'elenco delle funzioni qui per convertire il file

risultati in un elenco e visualizzarli.

Un'espressione lambda è una funzione anonima , ovvero una funzione senza nome . Nel
la chiamata del filtro

lecca qui per visualizzare l'immagine del codice

C
Pagina 204
filtro ( lambda x: x% 2 ! = 0 , numeri)

il primo argomento è lambda

lambda x: x% 2 ! = 0

Un lambda inizia con la parola chiave lambda seguita da un parametro separato da virgole
elenco, due punti (:) e un'espressione. In questo caso, l'elenco dei parametri ha un parametro
denominato x. Un lambda restituisce implicitamente il valore della sua espressione. Quindi qualsiasi semplice funzione di
il modulo

lecca qui per visualizzare l'immagine del codice

def nome_funzione ( parameter_list ):


espressione di ritorno

può essere espresso come un lambda più conciso della forma

lecca qui per visualizzare l'immagine del codice

lambda parameter_list : espressione

Mappatura dei valori di una sequenza su nuovi valori

Usiamo la funzione mappa incorporata con un lambda per quadrare ogni valore in numeri:

lecca qui per visualizzare l'immagine del codice

In [6]: numeri
Fuori [6]: [10, 3, 7, 1, 9, 4, 2, 8, 5, 6]

In [7]: list (map ( lambda x: x ** 2 , numbers))


Uscita [7]: [100, 9, 49, 1, 81, 16, 4, 64, 25, 36]

Il primo argomento della mappa delle funzioni è una funzione che riceve un valore e ne restituisce uno nuovo
valore: in questo caso, un lambda che piazza il suo argomento. Il secondo argomento è un file
iterabile di valori da mappare. La mappa delle funzioni utilizza una valutazione lenta. Quindi, passiamo alla lista

funzione l'iteratore restituito dalla mappa. Questo ci consente di iterare e creare un file
elenco dei valori mappati. Ecco una comprensione dell'elenco equivalente:

C
Pagina 205
lecca qui per visualizzare l'immagine del codice

In [8]: [item ** 2 for item in numbers]


Uscita [8]: [100, 9, 49, 1, 81, 16, 4, 64, 25, 36]

Combinazione di filtro e mappa

È possibile combinare il filtro precedente e le operazioni di mappatura come segue:

lecca qui per visualizzare l'immagine del codice

In [9]: list (map ( lambda x: x ** 2 ,


...: filtro ( lambda x: x% 2! = 0 , numeri)))
...:
Uscita [9]: [9, 49, 1, 81, 25]

C'è molto da fare nello snippet [9], quindi diamo un'occhiata più da vicino. Innanzitutto, filtra
restituisce un iterabile che rappresenta solo i valori dispari dei numeri. Quindi la mappa restituisce un file
iterabile che rappresenta i quadrati dei valori filtrati. Infine, list utilizza l'iterabile di map
per creare l'elenco. Potresti preferire la seguente comprensione dell'elenco a quella precedente
frammento:

lecca qui per visualizzare l'immagine del codice


In [10]: [x ** 2 per x in numeri se x% 2 ! = 0 ]
Uscita [10]: [9, 49, 1, 81, 25]

Per ogni valore di x in numeri, l'espressione x ** 2 viene eseguita solo se il


la condizione x% 2! = 0 è vera.

Riduzione: somma degli elementi di una sequenza con somma

Come sapete, le riduzioni elaborano gli elementi di una sequenza in un unico valore. Hai
riduzioni eseguite con le funzioni integrate len, sum, min e max. Puoi anche farlo
creare riduzioni personalizzate utilizzando la funzione di riduzione del modulo functools. Vedere

ttps: //docs.python.org/3/library/functools.html per un esempio di codice.


Quando indaghiamo su big data e Hadoop in nel capitolo 16 , mostreremo MapReduce
programmazione, che si basa sul filtro, mappare e ridurre le operazioni funzionali
programmazione di stile.

5Ch .15 ALTRE FUNZIONI DI ELABORAZIONE DELLE SEQUENZE


Pagina 206
5.15 ALTRE FUNZIONI DI ELABORAZIONE DELLE SEQUENZE
Python fornisce altre funzioni incorporate per manipolare le sequenze.

Trovare i valori minimo e massimo utilizzando una funzione chiave

Abbiamo precedentemente mostrato le funzioni di riduzione incorporate min e max usando argomenti,
come int o elenchi di int. A volte dovrai trovare il minimo e
massimo di oggetti più complessi, come le stringhe. Considera quanto segue
confronto:

In [1]: "Red" < "orange"


Out [1]: vero

La lettera "R" "viene dopo" "o" nell'alfabeto, quindi potresti aspettarti che "Rosso" sia inferiore
di "arancione" e la condizione precedente è False. Tuttavia, le stringhe vengono confrontate
dai valori numerici sottostanti dei loro caratteri e le lettere minuscole sono più alte
valori numerici rispetto alle lettere maiuscole. Puoi confermarlo con la funzione incorporata
ord , che restituisce il valore numerico di un carattere:

In [2]: ord ( 'R' )


Uscita [2]: 82

In [3]: ord ( 'o' )


Uscita [3]: 111

Considera i colori dell'elenco, che contiene stringhe con lettere maiuscole e minuscole:

lecca qui per visualizzare l'immagine del codice

In [4]: ​colors = [ "Red" , "orange" , "Yellow" , "green" , "Blue" ]

Supponiamo di voler determinare le stringhe minime e massime utilizzando


ordine alfabetico , non numerico (lessicografico). Se disponiamo i colori
in ordine alfabetico

lecca qui per visualizzare l'immagine del codice


"Blu" , "verde" , "arancione" , "Rosso" , "Giallo"

puoi vedere che "Blu" è il minimo (cioè il più vicino all'inizio del file

C
Pagina 207
alfabeto) e "Giallo" è il massimo (cioè più vicino alla fine dell'alfabeto).

Poiché Python confronta le stringhe utilizzando valori numerici, devi prima convertirli
stringa in tutte le lettere minuscole o tutte maiuscole. Allora anche i loro valori numerici
rappresentano l' ordine alfabetico . I seguenti snippet abilitano min e max a
determinare le stringhe minime e massime in ordine alfabetico:

lecca qui per visualizzare l'immagine del codice

In [5]: min (colori, chiave = lambda s: s.lower ())


Uscita [5]: "Blu"

In [6]: max (colori, chiave = lambda s: s.lower ())


Uscita [6]: "Giallo"

L'argomento della parola chiave chiave deve essere una funzione un parametro che restituisce un valore. Nel
in questo caso, è un lambda che chiama il metodo della stringa lower per ottenere le lettere minuscole di una stringa
versione. Le funzioni min e max chiamano la funzione dell'argomento chiave per ogni elemento e
utilizzare i risultati per confrontare gli elementi.

Iterazione all'indietro attraverso una sequenza

La funzione incorporata invertita restituisce un iteratore che consente di iterare su un file


i valori della sequenza all'indietro. La seguente comprensione dell'elenco crea un nuovo elenco
contenente i quadrati dei valori dei numeri in ordine inverso:

lecca qui per visualizzare l'immagine del codice

In [7]: numeri = [ 10 , 3 , 7 , 1 , 9 , 4 , 2 , 8 , 5 , 6 ]

In [7]: reversed_numbers = [item for item in reversed (numbers)]

In [8]: reversed_numbers
Uscita [8]: [36, 25, 64, 4, 16, 81, 1, 49, 9, 100]

Combinazione di iterabili in tuple di elementi corrispondenti

La funzione zip incorporata ti consente di iterare su più iterabili di dati contemporaneamente


tempo. La funzione riceve come argomenti un numero qualsiasi di iterabili e restituisce un file
iteratore che produce tuple contenenti gli elementi con lo stesso indice in ciascuna. Per
esempio, la chiamata a zip dello snippet [11] produce le tuple ('Bob', 3.5), ('Sue',

4.0) e ('Amanda', 3.75) costituito dagli elementi all'indice 0, 1 e 2 di ciascuno

C
Pagina 208
elenco, rispettivamente:

lecca qui per visualizzare l'immagine del codice

In [9]: names = [ "Bob" , "Sue" , "Amanda" ]

In [10]: grade_point_averages = [ 3.5 , 4.0 , 3.75 ]

In [11]: for name, gpa in zip (names, grade_point_averages):


...: print (f 'Name = {name} ; GPA = {gpa} ' )
...:
Nome = Bob; GPA = 3.5
Nome = Sue; GPA = 4.0
Nome = Amanda; GPA = 3.75

Spacchettiamo ogni tupla in name e gpa e le visualizziamo. Funzione zip più corta
argomento determina il numero di tuple prodotte. Qui entrambi hanno la stessa lunghezza.

5.16 ELENCHI BIDIMENSIONALI


Gli elenchi possono contenere altri elenchi come elementi. Un uso tipico di tale annidato (o
multidimensionali) serve a rappresentare tabelle di valori costituite da informazioni
disposti in righe e colonne . Per identificare un particolare elemento della tabella, ne specifichiamo due
indici: per convenzione, il primo identifica la riga dell'elemento, il secondo quella dell'elemento
colonna.

Gli elenchi che richiedono due indici per identificare un elemento sono chiamati elenchi bidimensionali
(o elenchi con doppio indice o elenchi con doppio script ). Gli elenchi multidimensionali possono
avere più di due indici. Qui, introduciamo elenchi bidimensionali.

Creazione di un elenco bidimensionale

Considera un elenco bidimensionale con tre righe e quattro colonne (cioè un elenco 3by4)
che potrebbe rappresentare i voti di tre studenti che hanno sostenuto ciascuno quattro esami in un corso:

lecca qui per visualizzare l'immagine del codice

In [1]: a = [[ 77 , 68 , 86 , 73 ], [ 96 , 87 , 89 , 81 ], [ 70 , 90 , 86 , 81 ]]

Scrivere l'elenco come segue rende più chiara la sua struttura tabulare di righe e colonne:

lecca qui per visualizzare l'immagine del codice

C
Pagina 209
a = [[ 77 , 68 , 86 , 73 ], # voti del primo studente
[ 96 , 87 , 89 , 81 ], # voti del secondo studente
[ 70 , 90 , 86 , 81 ]] # voti del terzo studente

Illustrare un elenco bidimensionale

Il diagramma seguente mostra l'elenco a, con le sue righe e colonne di valori del voto d'esame:

Identificazione degli elementi in un elenco bidimensionale

Il diagramma seguente mostra i nomi degli elementi della lista a:


Ogni elemento è identificato da un nome nella forma a [ i ] [ j ]: a è il nome della lista e i
e j sono gli indici che identificano in modo univoco la riga e la colonna di ogni elemento,
rispettivamente. I nomi degli elementi nella riga 0 hanno tutti 0 come primo indice. L'elemento
i nomi nella colonna 3 hanno tutti 3 come secondo indice.

Nell'elenco bidimensionale a:

77, 68, 86 e 73 inizializzano a [0] [0], a [0] [1], a [0] [2] e a [0] [3],
rispettivamente,

96, 87, 89 e 81 inizializzano a [1] [0], a [1] [1], a [1] [2] e a [1] [3],

Pagina 210
rispettivamente, e

70, 90, 86 e 81 inizializzano a [2] [0], a [2] [1], a [2] [2] e a [2] [3],
rispettivamente.

Una lista con m righe e n colonne è chiamata lista mbyn e ha m × n elementi.

L'istruzione for annidata seguente restituisce le righe del precedente twodimensional


elenca una riga alla volta:

lecca qui per visualizzare l'immagine del codice

In [2]: per la riga in a:


...: per articolo nella riga:
...: print (item, end = '' )
...: Stampa()
...:
77 68 86 73
96 87 89 81
70 90 86 81

Come vengono eseguiti i cicli annidati


Modifichiamo il ciclo annidato per visualizzare il nome dell'elenco e gli indici di riga e di colonna
e valore di ogni elemento:

lecca qui per visualizzare l'immagine del codice

In [3]: for i, row in enumerate (a):


...: per j, elemento in enumerate (riga):
...: print (f 'a [ {i} ] [ {j} ] = {item} ' , end = '' )
...: Stampa()
...:
a [0] [0] = 77 a [0] [1] = 68 a [0] [2] = 86 a [0] [3] = 73
a [1] [0] = 96 a [1] [1] = 87 a [1] [2] = 89 a [1] [3] = 81
a [2] [0] = 70 a [2] [1] = 90 a [2] [2] = 86 a [2] [3] = 81

L'istruzione for esterna esegue un'iterazione sulle righe dell'elenco bidimensionale una riga alla volta
tempo. Durante ogni iterazione dell'istruzione for esterna, l'istruzione for interna
itera su ogni colonna nella riga corrente. Quindi nella prima iterazione del ciclo esterno,
la riga 0 è

[ 77 , 68 , 86 , 73 ]

C
Pagina 211
e il ciclo annidato itera attraverso i quattro elementi di questa lista a [0] [0] = 77, a [0]

[1] = 68, a [0] [2] = 86 e a [0] [3] = 73.

Nella seconda iterazione del ciclo esterno, la riga 1 è

[ 96 , 87 , 89 , 81 ]

e il ciclo annidato itera attraverso i quattro elementi di questa lista a [1] [0] = 96, a [1]

[1] = 87, a [1] [2] = 89 e a [1] [3] = 81.

Nella terza iterazione del ciclo esterno, la riga 2 è

[ 70 , 90 , 86 , 81 ]

e il ciclo annidato itera attraverso i quattro elementi di questa lista a [2] [0] = 70, a [2]

[1] = 90, a [2] [2] = 86 e a [2] [3] = 81.

Nel capitolo "Programmazione ArrayOriented con NumPy", tratteremo NumPy


la raccolta ndarray della libreria e la raccolta DataFrame della libreria Pandas. Questi
consentono di manipolare raccolte multidimensionali in modo più conciso e
convenientemente rispetto alle manipolazioni di elenchi bidimensionali che hai visto in questa sezione.

5.17 INTRO A DATA SCIENCE: SIMULAZIONE E


VISUALIZZAZIONI STATICHE
Le sezioni Intro to Data Science degli ultimi capitoli hanno discusso descrittive di base
statistiche. Qui ci concentriamo sulle visualizzazioni, che ti aiutano a "conoscere" i tuoi dati.
Le visualizzazioni offrono un modo potente per comprendere i dati che va oltre la semplice
guardando i dati grezzi.

Per la visualizzazione utilizziamo due librerie di visualizzazione opensource, Seaborn e Matplotlib


grafici a barre statici che mostrano i risultati finali di una simulazione di rollio su sei lati. Il
La libreria di visualizzazione di Seaborn è costruita sulla libreria di visualizzazione Matplotlib
e semplifica molte operazioni di Matplotlib. Useremo aspetti di entrambe le librerie, perché
alcune delle operazioni di Seaborn restituiscono oggetti dalla libreria Matplotlib. Nel prossimo
della sezione Introduzione alla scienza dei dati del capitolo, renderemo le cose "vive" con la dinamica
visualizzazioni .

5.17.1 Esempi di grafici per 600, 60.000 e 6.000.000 di dadi

Pagina 212
La schermata qui sotto mostra un grafico a barre verticali che riassume per 600 tiri di dado
le frequenze con cui appare ciascuna delle sei facce e le loro percentuali di
totale. Seaborn si riferisce a questo tipo di grafico come grafico a barre :
Qui ci aspettiamo circa 100 occorrenze di ciascuna faccia della matrice. Tuttavia, con un file così piccolo
numero di rotoli, nessuna delle frequenze è esattamente 100 (sebbene molte siano vicine) e
la maggior parte delle percentuali non è prossima al 16,667% (circa 1/6). Mentre eseguiamo il file
simulazione per 60.000 tiri di dado, le barre diventeranno di dimensioni molto più vicine. A 6.000.000
rotoli di dado, sembreranno avere esattamente le stesse dimensioni. Questo è il " aw di grandi numeri "a
lavoro. Il prossimo capitolo mostrerà le lunghezze delle barre che cambiano dinamicamente.

Discuteremo come controllare l'aspetto e i contenuti della trama, tra cui:

il titolo del grafico all'interno della finestra (Rolling a SixSided Die 600 Times),

le etichette descrittive Die valore per l' x l'asse e la frequenza per la y dell'asse,

il testo visualizzato sopra ogni barra, che rappresenta la frequenza e la percentuale di


rotoli totali e

i colori della barra.

lT
Pagina 213
Useremo varie opzioni predefinite di Seaborn. Ad esempio, Seaborn determina il testo
etichette lungo l' x asse dai valori faccia della filiera 1-6 e le etichette di testo lungo la y asse
dalle frequenze effettive del die. Dietro le quinte, Matplotlib determina le posizioni
e le dimensioni delle barre, in base alle dimensioni della finestra e alle magnitudini dei valori
le barre rappresentano. Posiziona anche le etichette numeriche dell'asse di frequenza in base a
le frequenze effettive dello stampo rappresentate dalle barre. Ci sono molte altre funzionalità che puoi
personalizzare. Dovresti modificare questi attributi in base alle tue preferenze personali.

La prima schermata qui sotto mostra i risultati di 60.000 tiri di dado: immagina di provarci
fallo a mano. In questo caso, ci aspettiamo circa 10.000 di ogni faccia. Il secondo schermo
l'acquisizione di seguito mostra i risultati per 6.000.000 di rotoli, sicuramente qualcosa che non faresti mai
a mano! In questo caso, ci aspettiamo circa 1.000.000 di ogni faccia e le barre della frequenza
sembrano essere identici in lunghezza (sono vicini ma non esattamente della stessa lunghezza). Nota
che con più tiri di dado, le percentuali di frequenza sono molto più vicine al previsto
16,667%.
5.17.2 Visualizzazione delle frequenze e delle percentuali dei dadi
In questa sezione, svilupperai interattivamente i grafici a barre mostrati nella sezione precedente.

Avvio di IPython per lo sviluppo interattivo di Matplotlib

IPython ha il supporto integrato per lo sviluppo interattivo di grafici Matplotlib, che tu


anche bisogno di sviluppare grafici Seaborn. Avvia semplicemente IPython con il comando:

ipython matplotlib

Importazione delle librerie


Per prima cosa, importiamo le librerie che useremo:

Pagina 214
lecca qui per visualizzare l'immagine del codice

In [1]: importa matplotlib.pyplot come plt

In [2]: importa numpy come np

In [3]: importa casuale

In [4]: importa seaborn come sns

1. Il modulo matplotlib.pyplot contiene i grafici della libreria Matplotlib


capacità che utilizziamo. Questo modulo in genere viene importato con il nome plt.

2. La libreria NumPy (Numerical Python) include la funzione univoca che useremo


per riassumere i tiri di dado. Il modulo numpy viene tipicamente importato come np.

3. Il modulo random contiene le funzioni di generazione di numeri casuali di Python.

4. Il modulo seaborn contiene le capacità grafiche della libreria Seaborn che utilizziamo.

Questo modulo in genere viene importato con il nome sns. Cerca perché questo curioso
è stata scelta l'abbreviazione.

Rotolamento del dado e calcolo delle frequenze del dado

Quindi, usiamo una comprensione dell'elenco per creare un elenco di 600 valori di dado casuali, quindi usiamo
La funzione unica di NumPy per determinare i valori di roll univoci (molto probabilmente tutti e sei
possibili valori nominali) e le loro frequenze:

lecca qui per visualizzare l'immagine del codice

In [5]: rolls = [random.randrange ( 1 , 7 ) for i in range ( 600 )]

In [6]: values, frequencies = np.unique (rolls, return_counts = True )

La libreria NumPy fornisce la raccolta ndarray ad alte prestazioni , che è


1
in genere molto più veloce degli elenchi . Sebbene non usiamo ndarray direttamente qui, il file
La funzione unica di NumPy prevede un argomento ndarray e restituisce un ndarray. Se
passi un elenco (come i rotoli), NumPy lo converte in un ndarray per prestazioni migliori.
Il ndarray restituito da univoco lo assegneremo semplicemente a una variabile per essere utilizzato da un file
Funzione di plottaggio Seaborn.

1
Eseguiremo un confronto delle prestazioni in capitolo 7 in cui discutiamo di ndarray in

C
Pagina 215
profondità.

Specificando l'argomento della parola chiave return_counts = True indica a univoco di contare ciascuno

numero di occorrenze del valore univoco. In questo caso, unique restituisce una tupla di due uno
ndarrays dimensionali contenenti i valori univoci ordinati e il corrispondente
frequenze, rispettivamente. Spacchettiamo gli ndarrays della tupla nei valori delle variabili
e frequenze. Se return_counts è False, lo è solo l'elenco di valori univoci
restituito.

Creazione del grafico a barre iniziale

Creiamo il titolo del grafico a barre, impostiamo il suo stile, quindi rappresentiamo graficamente le facce e le frequenze del dado:

lecca qui per visualizzare l'immagine del codice

In [7]: title = f'Rolling a SixSided Die {len (rolls) :,} Times '

In [8]: sns.set_style ( 'whitegrid' )

In [9]: assi = sns.barplot (x = valori, y = frequenze, tavolozza ='brillante' )

La stringa di snippet [7] include il numero di tiri di dado nel titolo del grafico a barre. La virgola
(,) identificatore di formato in

{len (rotoli) :,}

visualizza il numero con i separatori delle migliaia , quindi 60000 verrebbe visualizzato come
60.000.

Per impostazione predefinita, Seaborn traccia i grafici su uno sfondo bianco semplice, ma ne fornisce diversi
stili tra cui scegliere ('darkgrid', 'whitegrid', 'dark', 'white' e

"zecche"). Snippet [8] specifica lo stile "whitegrid", che mostra il grigio chiaro
linee orizzontali nel grafico a barre verticali. Questi ti aiutano a vedere più facilmente come è ogni barra
l'altezza corrisponde alle etichette numeriche di frequenza sul lato sinistro del grafico a barre.

Snippet [9] rappresenta graficamente le frequenze del dado utilizzando la funzione barplot di Seaborn . Quando tu
esegui questo frammento, appare la seguente finestra (perché hai avviato IPython con
l'opzione matplotlib):

C
Pagina 216
Seaborn interagisce con Matplotlib per visualizzare le barre creando un Matplotlib Axes
oggetto, che gestisce il contenuto che appare nella finestra. Dietro le quinte,
Seaborn utilizza un oggetto Matplotlib Figure per gestire la finestra in cui verranno visualizzati gli assi

apparire. I primi due argomenti della funzione barplot sono ndarrays contenenti l' asse x
e i valori dell'asse y , rispettivamente. Abbiamo utilizzato l'argomento della parola chiave della tavolozza opzionale per
scegliere la tavolozza dei colori predefinita di Seaborn "brillante". È possibile visualizzare le opzioni della tavolozza
a:

ttps: //seaborn.pydata.org/tutorial/color_palettes.html

Funzione barplot restituisce l'oggetto Axes che ha configurato. Lo assegniamo al


assi variabili in modo da poterlo utilizzare per configurare altri aspetti del nostro grafico finale. Eventuali modifiche

che fai al grafico a barre dopo questo punto apparirà immediatamente quando esegui il
snippet corrispondente.

Impostazione del titolo della finestra e l'etichettatura del x - e y -Axes

I prossimi due frammenti aggiungono del testo descrittivo al grafico a barre:

lecca qui per visualizzare l'immagine del codice

In [10]: axes.set_title (titolo)


Fuori [10]: Testo (0,5,1, 'Lanciare un dado a sei facce 600 volte')

C
h

Pagina 217
In [11]: axes.set (xlabel = 'Die Value' , ylabel = 'Frequency' )
Uscita [11]: [Testo (92.6667,0.5, 'Frequenza'), Testo (0.5,58.7667, 'Valore matrice')]

Snippet [10] utilizza il metodo set_title dell'oggetto axes per visualizzare la stringa del titolo
centrato sopra la trama. Questo metodo restituisce un oggetto Text contenente il titolo e il relativo
posizione nella finestra, che IPython visualizza semplicemente come output per conferma. tu
può ignorare gli Out [] negli snippet sopra.

Lo snippet [11] aggiunge etichette a ciascun asse. Il metodo set riceve argomenti di parole chiave per
le proprietà dell'oggetto Axes da impostare. Il metodo visualizza il testo xlabel lungo la x
l'asse e il testo dell'etichetta lungo l' asse ye restituisce un elenco di oggetti di testo
contenente le etichette e le relative posizioni. Il grafico a barre ora appare come segue:
Finalizzazione del grafico a barre
I due snippet successivi completano il grafico facendo spazio per il testo sopra ogni barra,
quindi visualizzandolo:

lecca qui per visualizzare l'immagine del codice

In [12]: axes.set_ylim (top = max (frequenze) * 1.10 )

Uscita [12]: (0,0, 122,10000000000001) Pagina 218

In [13]: per bar, frequenza in zip (axes.patches, frequenze):


...: text_x = bar.get_x () + bar.get_width () / 2.0
...: text_y = bar.get_height ()
...: text = f ' {frequency :,} \ n {frequency / len (rolls): .3 %} '
...: axes.text (text_x, text_y, text,
...: fontsize = 11 , ha = 'center' , va = 'bottom' )
...:

Per fare spazio al testo sopra le barre, lo snippet [12] ridimensiona l' asse y del 10%. Noi
ha scelto questo valore tramite la sperimentazione. Il metodo set_ylim dell'oggetto Axes ne ha molti
argomenti di parole chiave opzionali. Qui, usiamo solo top per modificare il valore massimo
rappresentato dall'asse y . Abbiamo moltiplicato la frequenza massima per 1,10 per garantire che il file
L' asse y è più alto del 10% rispetto alla barra più alta.

Infine, lo snippet [13] mostra il valore di frequenza di ciascuna barra e la percentuale del totale
rotoli. La collezione di toppe dell'oggetto assi contiene forme colorate bidimensionali
che rappresentano le barre della trama. L'istruzione for usa zip per scorrere il file

patch e i corrispondenti valori di frequenza. Ogni iterazione viene decompressa in bar


e la frequenza restituita da una delle tuple zip. La suite dell'istruzione for funziona come
segue:

La prima istruzione calcola la coordinata x centrale dove apparirà il testo. Noi


calcola questo come la somma della coordinata x sinistra della barra (bar.get_x ()) e
metà della larghezza della barra (bar.get_width () / 2.0).

La seconda istruzione ottiene la coordinata y dove apparirà il testo


—Bar.get_y () rappresenta la parte superiore della barra.

La terza istruzione crea una stringa doppia contenente la frequenza di quella barra e il
percentuale corrispondente del totale dei tiri di dado.

L'ultima istruzione chiama il metodo di testo dell'oggetto Axes per visualizzare il testo sopra
bar. I primi due argomenti di questo metodo specificano la posizione x – y del testo e il terzo
argomento è il testo da visualizzare. L'argomento della parola chiave ha specifica l' orizzontale
allineamento: abbiamo centrato il testo orizzontalmente attorno alla coordinata x . La parola chiave
l'argomento va specifica l' allineamento verticale: abbiamo allineato la parte inferiore del testo
con alla coordinata y . Il grafico a barre finale è mostrato di seguito:

Pagina 219

Rolling Again e aggiornamento del grafico a barre: Presentazione di IPython Magics

Ora che hai creato un bel grafico a barre, probabilmente vorrai provare un numero diverso di file
rotoli di dado. Innanzitutto, cancella il grafico esistente chiamando la funzione cla (clear axes) di Matplotlib:

In [14]: plt.cla ()

IPython fornisce comandi speciali chiamati magics per eseguire comodamente


vari compiti. Usiamo la magia% Recall per ottenere lo snippet [5], che ha creato il file

roll list e inserisci il codice al successivo prompt In []:

lecca qui per visualizzare l'immagine del codice

In [15]:% richiama 5

In [16]: rolls = [random.randrange ( 1 , 7 ) for i in range ( 600 )]

Ora puoi modificare lo snippet per cambiare il numero di rotoli a 60000, quindi premere Invio

per creare un nuovo elenco:

lecca qui per visualizzare l'immagine del codice

C
In [16]: rolls = [random.randrange ( 1 , 7 ) for i in range ( 60000 )] Pagina 220

Quindi, richiama gli snippet da [6] a [13]. Visualizza tutti gli snippet nel file
intervallo nel successivo prompt In []. Premi Invio per rieseguire questi snippet:

lecca qui per visualizzare l'immagine del codice

In [17]:% richiamare 6 13
In [18]: values, frequencies = np.unique (rolls, return_counts =True )
...: title = f 'Lanciare un dado a sei facce {len (rolls) :,} Times'
...: sns.set_style ( 'whitegrid' )
...: assi = sns. barplot (x = valori, y = frequenze, tavolozza ='luminoso' )
...: axes.set_title (titolo)
...: axes.set (xlabel = 'Die Value' , ylabel = 'Frequency' )
...: axes.set_ylim (top = max (frequenze) * 1.10 )
...: per bar, frequenza in zip (axes.patches, frequenze):
...: text_x = bar.get_x () + bar.get_width () / 2.0
...: text_y = bar.get_height ()
...: text = f ' {frequency :,} \ n {frequency / len (roll): .3 %}'
...: axes.text (text_x, text_y, text,
...: fontsize = 11 , ha = 'center' , va = 'bottom' )
...:

Il grafico a barre aggiornato è mostrato di seguito:

C Salvataggio di frammenti su un file con% save Magic

Salvataggio di frammenti su un file con% save Magic Pagina 221

Dopo aver creato una trama in modo interattivo, potresti voler salvare il codice in un file così
può trasformarlo in uno script ed eseguirlo in futuro. Usiamo la % save magic per salvare
frammenti da 1 a 13 in un file denominato RollDie.py. IPython indica il file a cui
le righe sono state scritte, quindi visualizza le righe salvate:

lecca qui per visualizzare l'immagine del codice

In [19]: Salva% RollDie.py 1 13


I seguenti comandi sono stati scritti nel file `RollDie.py`:
importa matplotlib.pyplot come plt
importa numpy come np
importazione casuale
importare seaborn come sns
rolls = [random.randrange (1, 7) for i in range (600)]
valori, frequenze = np.unique (rolls, return_counts = True)
title = f'Rolling a SixSided Die {len (rolls) :,} Times '
sns.set_style ("whitegrid")
axes = sns.barplot (valori, frequenze, palette = 'bright')
axes.set_title (titolo)
axes.set (xlabel = 'Die Value', ylabel = 'Frequency')
axes.set_ylim (top = max (frequenze) * 1.10)
per bar, frequenza in zip (axes.patches, frequenze):
text_x = bar.get_x () + bar.get_width () / 2.0
text_y = bar.get_height ()
text = f '{frequenza:,} \ n {frequenza / len (rotoli) :. 3%}'
axes.text (text_x, text_y, testo,
fontsize = 11, ha = 'center', va = 'bottom')

Argomenti della riga di comando; Visualizzazione di un grafico da uno script

Con gli esempi di questo capitolo viene fornita una versione modificata del file RollDie.py
salvato sopra. Abbiamo aggiunto commenti e due modifiche in modo da poter eseguire lo script
con un argomento che specifica il numero di tiri di dado, come in:

ipython RollDie.py 600

Il modulo sys della libreria standard Python consente a uno script di ricevere la riga di comando
argomenti passati al programma. Questi includono il nome dello script e qualsiasi file
valori che appaiono alla sua destra quando si esegue lo script. Il modulo sys's

La lista argv contiene gli argomenti. Nel comando precedente, argv [0] è la stringa
"RollDie.py" e argv [1] è la stringa "600". Per controllare il numero di tiri di dado
con il valore dell'argomento della riga di comando, abbiamo modificato l'istruzione che crea il file
elenco rotoli come segue:

C
Pagina 222
lecca qui per visualizzare l'immagine del codice

rolls = [random.randrange ( 1 , 7 ) for i in range (int (sys.argv [ 1 ]))]

Notare che abbiamo convertito la stringa argv [1] in un int.

Matplotlib e Seaborn non visualizzano automaticamente il grafico


quando lo crei in uno script. Quindi alla fine dello script abbiamo aggiunto quanto segue
chiamata alla funzione show di Matplotlib , che mostra la finestra contenente il grafico:

plt. mostra ()

5.18 WRAP-UP
Questo capitolo ha presentato maggiori dettagli sulla lista e le sequenze di tuple. Hai creato elenchi,
accedeva ai loro elementi e ne determinava la lunghezza. Hai visto che gli elenchi sono mutabili, quindi
puoi modificare il loro contenuto, inclusa la crescita e la riduzione degli elenchi come il tuo
i programmi vengono eseguiti. Hai visto che l'accesso a un elemento inesistente provoca un
IndexError. Hai usato le istruzioni per scorrere gli elementi dell'elenco.

Abbiamo discusso delle tuple, che come le liste sono sequenze, ma sono immutabili. Hai disimballato un file
elementi della tupla in variabili separate. Hai usato enumerate per creare un iterabile di
tuple, ciascuna con un indice di lista e il valore dell'elemento corrispondente.

Hai imparato che tutte le sequenze supportano lo slicing, che crea nuove sequenze con
sottoinsiemi degli elementi originali. Hai utilizzato l'istruzione del per rimuovere elementi da
elenca ed elimina le variabili dalle sessioni interattive. Abbiamo passato elenchi, elementi di elenco e
sezioni di elenchi a funzioni. Hai visto come cercare e ordinare gli elenchi e come cercare
tuple. Abbiamo utilizzato metodi di elenco per inserire, aggiungere e rimuovere elementi e per invertire un file
elementi della lista e liste di copia.

Abbiamo mostrato come simulare stack con elenchi. Abbiamo utilizzato l'elenco conciso comprensivo
notazione per creare nuovi elenchi. Abbiamo utilizzato metodi incorporati aggiuntivi per sommare gli elementi della lista,
scorrere all'indietro in un elenco, trovare i valori minimo e massimo, filtrare i valori
e mappare i valori su nuovi valori. Abbiamo mostrato come gli elenchi annidati possono rappresentarne due
tabelle dimensionali in cui i dati sono disposti in righe e colonne. Hai visto come sono nidificati
for loops elabora elenchi bidimensionali.

Il capitolo si è concluso con una sezione Intro to Data Science che ha presentato un dado

C
Pagina 223
simulazione di rollio e visualizzazioni statiche. Un esempio di codice dettagliato ha utilizzato Seaborn
e le librerie di visualizzazione Matplotlib per creare una visualizzazione statica del grafico a barre del file
risultati finali della simulazione. Nella prossima sezione Intro to Data Science, usiamo un dierolling
simulazione con una visualizzazione dinamica del grafico a barre per rendere la trama "viva".

Nel prossimo capitolo, "Dizionari e insiemi", continueremo la nostra discussione su Python


collezioni incorporate. Useremo dizionari per archiviare raccolte non ordinate di valori-chiave
coppie che mappano chiavi immutabili a valori, proprio come un dizionario convenzionale mappa le parole
alle definizioni. Useremo i set per memorizzare raccolte non ordinate di elementi unici.

Nel capitolo "Programmazione ArrayOriented con NumPy", discuteremo di NumPy


raccolta ndarray in modo più dettagliato. Vedrai che mentre le liste vanno bene per piccole quantità
di dati, non sono efficienti per le grandi quantità di dati che incontrerai nei big data
applicazioni di analisi. In questi casi, il ndarray altamente ottimizzato della libreria NumPy
raccolta dovrebbe essere utilizzata. ndarray ( array n dimensionale) può essere molto più veloce di
elenchi. Eseguiremo test di profilatura Python per vedere quanto sia più veloce. Come vedrai, NumPy
include anche molte funzionalità per manipolare in modo conveniente ed efficiente array di
molte dimensioni. Nelle applicazioni di analisi dei big data, le richieste di elaborazione possono essere
enorme, quindi tutto ciò che possiamo fare per migliorare le prestazioni è importante. Nel
nostro " ig Data: Hadoop, Spark, NoSQL e IoT ”, utilizzerai uno dei più
2
database bigdata popolari ad alte prestazioni: MongoDB.

2
Il nome del database è radicato nella parola humongous.

https://avxhm.se/blogs/hill0

r
B
Pagina 224

laylist

6. Dizionari e set
storia
Obiettivi
opiche

In questo capitolo potrai:


guadagnando Pat

Utilizza i dizionari per rappresentare raccolte non ordinate di coppie chiave-valore.


ffers & Dea

Usa set per rappresentare raccolte non ordinate di valori univoci.


ighlights

Crea, inizializza e fai riferimento a elementi di dizionari e set.


ettings

Scorri le chiavi, i valori e le coppie chiave-valore di un dizionario.


Supporto
Aggiungi, rimuovi e aggiorna le coppie chiave-valore di un dizionario.
Disconnessione

Utilizza il dizionario e imposta gli operatori di confronto.

Combina set con operatori e metodi set.

Utilizza gli operatori in e not in per determinare se un dizionario contiene una chiave o un insieme

contiene un valore.

Utilizzare le operazioni sugli insiemi modificabili per modificare il contenuto di un insieme.

Usa le comprensioni per creare dizionari e set in modo rapido e conveniente.

Scopri come creare visualizzazioni dinamiche.

Migliora la tua comprensione della mutabilità e dell'immutabilità.

Contorno

.1 Introduzione

.2 Dizionari

6
Pagina 225
.2.1 Creazione di un dizionario

.2.2 Iterazione in un dizionario

.2.3 Operazioni di base del dizionario

.2.4 Chiavi e valori dei metodi del dizionario

.2.5 Confronti del dizionario

.2.6 Esempio: Dizionario dei voti degli studenti

.2.7 Esempio: conteggio parole

.2.8 Aggiornamento del metodo del dizionario

.2.9 Comprensioni del dizionario

.3 Insiemi

.3.1 Confronto di insiemi

.3.2 Operazioni matematiche sugli insiemi


.3.3 Operatori e metodi degli insiemi modificabili

.3.4 Imposta comprensioni

.4 Introduzione alla scienza dei dati: visualizzazioni dinamiche

.4.1 Come funziona la visualizzazione dinamica

.4.2 Implementazione di una visualizzazione dinamica

.5 WrapUp

6.1 INTRODUZIONE
Abbiamo discusso tre raccolte di sequenze incorporate: stringhe, elenchi e tuple. Ora noi
considera le raccolte incorporate non sequenze: dizionari e set. Un dizionario è
una raccolta non ordinata che memorizza le coppie chiave-valore a cui mappano le chiavi immutabili
valori, proprio come un dizionario convenzionale associa le parole alle definizioni. Un set è un file

6
Pagina 226
raccolta non ordinata di elementi immutabili unici .

6.2 DIZIONARI
Un dizionario associa le chiavi ai valori. Ogni chiave viene mappata a un valore specifico. Il
la tabella seguente contiene esempi di dizionari con le relative chiavi, tipi di chiave, valori e
tipi di valore:

Chiave
Chiavi Valori Tipo di valore
genere

Paese Internet
Nomi dei paesi str str
codici

Numeri decimali int numeri romani str

Agricolo
stati str elenco di str
prodotti

tupla di int e
Pazienti ospedalieri str Segni vitali
galleggia

Giocatori di baseball str Medie di battuta galleggiante

Metrico
str Abbreviazioni str
misurazioni
Codici inventario str Quantità in magazzino int

U nique Keys

nique Keys Pagina 227

Le chiavi di un dizionario devono essere immutabili (come stringhe, numeri o tuple) e univoche
(cioè, nessun duplicato). Più chiavi possono avere lo stesso valore, ad esempio due differenti
codici di inventario che hanno la stessa quantità in magazzino.

6.2.1 Creazione di un dizionario


È possibile creare un dizionario racchiudendo tra parentesi graffe, {}, un elenco separato da virgole di
coppie chiave-valore, ciascuna della forma chiave : valore . Puoi creare un dizionario vuoto con

{}.

Creiamo un dizionario con le chiavi del paese di origine "Finlandia", "Sud Africa"

e "Nepal" e i valori corrispondenti dei codici di paese Internet "fi", "za" e

'np':

lecca qui per visualizzare l'immagine del codice

In [1]: country_codes = { 'Finland' : 'fi' , 'South Africa' : 'za' ,


...: 'Nepal' : 'np' }
...:

In [2]: country_codes
Uscita [2]: {'Finland': 'fi', 'South Africa': 'za', 'Nepal': 'np'}

Quando produci un dizionario, il suo elenco di coppie chiave-valore separato da virgole è sempre
racchiuso tra parentesi graffe. Poiché i dizionari sono raccolte non ordinate , il file display
order può differire dall'ordine in cui le coppie chiave-valore sono state aggiunte a
dizionario. Nell'output dello snippet [2] le coppie chiave-valore vengono visualizzate nell'ordine in cui sono

sono stati inseriti, ma non scrivere codice che dipende dall'ordine delle coppie chiave-valore.

Determinare se un dizionario è vuoto


La funzione incorporata len restituisce il numero di coppie chiave-valore in un dizionario:

In [3]: len (country_codes)


Fuori [3]: 3

Puoi usare un dizionario come condizione per determinare se è vuoto: una dizione non vuota
ary restituisce True:

lecca qui per visualizzare l'immagine del codice

U
C
Pagina 228
In [4]: if country_codes:
...: print ( 'country_codes non è vuoto' )
...: altro :
...: print ( 'country_codes è vuoto' )
...:
country_codes non è vuoto

Un dizionario vuoto restituisce False. Per dimostrarlo, nel codice seguente abbiamo
chiama il metodo clear per eliminare le coppie chiave-valore del dizionario, quindi nello snippet [6] we
richiama e riesegui lo snippet [4]:

lecca qui per visualizzare l'immagine del codice

In [5]: country_codes.clear ()

In [6]: if country_codes:
...: print ( 'country_codes non è vuoto' )
...: altro :
...: print ( 'country_codes è vuoto' )
...:
country_codes è vuoto

6.2.2 Iterazione in un dizionario


Il seguente dizionario associa le stringhe monthname ai valori int che rappresentano il file
numero di giorni nel mese corrispondente. Tieni presente che più chiavi possono avere l'estensione
stesso valore:

lecca qui per visualizzare l'immagine del codice

In [1]: days_per_month = { 'January' : 31 , 'February' : 28 , 'March' : 31 }

In [2]: days_per_month
Uscita [2]: {'Gennaio': 31, 'Febbraio': 28, 'Marzo': 31}

Anche in questo caso, la rappresentazione di stringa del dizionario mostra le coppie chiave-valore nel file
ordine di inserzione, ma questo non è garantito perché i dizionari non sono ordinati . Bene
mostra come elaborare le chiavi in ordine ordinato più avanti in questo capitolo.

L'istruzione for seguente esegue l'iterazione delle coppie chiave-valore di days_per_month.

Gli elementi del metodo Dictionary restituiscono ciascuna coppia chiave-valore come una tupla, che viene decompressa

mese e giorni:

C
Pagina 229
lecca qui per visualizzare l'immagine del codice

In [3]: per mese, giorni in days_per_month.items ():


...: print (f " {month} has {days} days" )
...:
Gennaio ha 31 giorni
Febbraio ha 28 giorni
Marzo ha 31 giorni

6.2.3 Operazioni di base del dizionario


Per questa sezione, iniziamo creando e visualizzando il dizionario

numeri romani. Forniamo intenzionalmente il valore errato 100 per la chiave "X",
che correggeremo a breve:

lecca qui per visualizzare l'immagine del codice

In [1]: roman_numerals = { 'I' : 1 , 'II' : 2 , 'III' : 3 , 'V' : 5 , 'X' : 100 }

In [2]: roman_numerals
Fuori [2]: {'I': 1, 'II': 2, 'III': 3, 'V': 5, 'X': 100}
Accesso al valore associato a una chiave
Otteniamo il valore associato alla chiave 'V':

In [3]: roman_numerals [ 'V' ]


Fuori [3]: 5

Aggiornamento del valore di una coppia chiave-valore esistente


Puoi aggiornare il valore associato a una chiave in un'istruzione di assegnazione, cosa che facciamo qui
per sostituire il valore errato associato alla chiave "X":

lecca qui per visualizzare l'immagine del codice

In [4]: ​roman_numerals [ 'X' ] = 10

In [5]: roman_numerals
Uscita [5]: {'I': 1, 'II': 2, 'III': 3, 'V': 5, 'X': 10}

Aggiunta di una nuova coppia chiave-valore


C
Pagina 230
L'assegnazione di un valore a una chiave inesistente inserisce la coppia chiave-valore nel dizionario:

lecca qui per visualizzare l'immagine del codice

In [6]: roman_numerals [ 'L' ] = 50

In [7]: roman_numerals
Uscita [7]: {'I': 1, 'II': 2, 'III': 3, 'V': 5, 'X': 10, 'L': 50}

Le chiavi stringa fanno distinzione tra maiuscole e minuscole. L'assegnazione a una chiave inesistente inserisce un nuovo valore-chiave
paio. Questo potrebbe essere ciò che intendi o potrebbe essere un errore logico.

Rimozione di una coppia chiave-valore

Puoi eliminare una coppia chiave-valore da un dizionario con l'istruzione del:

lecca qui per visualizzare l'immagine del codice

In [8]: del roman_numerals [ 'III' ]

In [9]: roman_numerals
Fuori [9]: {'I': 1, 'II': 2, 'V': 5, 'X': 10, 'L': 50}

È inoltre possibile rimuovere una coppia chiave-valore con il metodo pop del dizionario , che restituisce
il valore per la chiave rimossa:

lecca qui per visualizzare l'immagine del codice

In [10]: roman_numerals.pop ( 'X' )


Fuori [10]: 10

In [11]: roman_numerals
Fuori [11]: {'I': 1, 'II': 2, 'V': 5, 'L': 50}

Tentativo di accesso a una chiave inesistente

L'accesso a una chiave inesistente produce un KeyError:

lecca qui per visualizzare l'immagine del codice


n [12]: roman_numerals [ 'III' ]

KeyError Traceback (la chiamata più recente per ultima)

<ipythoninput12ccd50c7f0c8b> in <module> () Pagina 231


> 1 roman_numerals ['III']

KeyError : "III"

Puoi prevenire questo errore usando il metodo del dizionario get , che normalmente restituisce il suo
valore corrispondente dell'argomento. Se quella chiave non viene trovata, ottieni restituisce None. IPython
non mostra nulla quando None viene restituito nello snippet [13]. Se specifichi un file

secondo argomento da ottenere, restituisce quel valore se la chiave non viene trovata:

lecca qui per visualizzare l'immagine del codice

In [13]: roman_numerals.get ( 'III' )

In [14]: roman_numerals.get ( 'III' , 'III non nel dizionario' )


Out [14]: "III non nel dizionario"

In [15]: roman_numerals.get ( 'V' )


Fuori [15]: 5

Verifica se un dizionario contiene una chiave specificata

Gli operatori in e non in possono determinare se un dizionario contiene una chiave specificata:

lecca qui per visualizzare l'immagine del codice

In [16]: "V" in roman_numerals


Out [16]: Vero

In [17]: "III" in roman_numerals


Out [17]: Falso

In [18]: "III" non in roman_numerals


Out [18]: Vero

6.2.4 Chiavi e valori dei metodi del dizionario

In precedenza, abbiamo utilizzato gli elementi del metodo del dizionario per scorrere le tuple di un dizionario

coppie chiave-valore. Allo stesso modo, è possibile utilizzare chiavi e valori dei metodi per eseguire l'iterazione
solo le chiavi o i valori di un dizionario, rispettivamente:

lecca qui per visualizzare l'immagine del codice

Y
C
Pagina 232
In [1]: months = { 'January' : 1 , 'February' : 2 , 'March' : 3 }

In [2]: per month_name in months.keys ():


...: print (month_name, end = '' )
...:
Gennaio febbraio marzo

In [3]: per month_number in months.values ​():


...: print (month_number, end = '' )
...:
123

Visualizzazioni dizionario

Gli elementi, le chiavi e i valori dei metodi del dizionario restituiscono ciascuno una visualizzazione dei dati di un dizionario.
Quando si iterazioni su una vista , si “vede” attuali contenuti-it del dizionario fa non
disporre di una propria copia dei dati.

Per mostrare che le viste non mantengono le proprie copie dei dati di un dizionario, iniziamo
salvare la vista restituita dalle chiavi nella variabile months_view, quindi scorrere
esso:

lecca qui per visualizzare l'immagine del codice

In [4]: ​months_view = months.keys ()

In [5]: per la chiave in months_view:


...: print (key, end = '' )
...:
Gennaio febbraio marzo

Successivamente, aggiungiamo una nuova coppia chiave-valore a mesi e visualizziamo il dizionario aggiornato:

lecca qui per visualizzare l'immagine del codice

In [6]: mesi ["dicembre"] = 12

In [7]: mesi
In uscita [7]: {'Gennaio': 1, 'Febbraio': 2, 'Marzo': 3, 'Dicembre': 12}

Ora, iteriamo di nuovo su months_view. La chiave che abbiamo aggiunto sopra è davvero
visualizzato:

lecca qui per visualizzare l'immagine del codice

C
Pagina 233
In [8]: per la chiave in months_view:
...: print (key, end = '' )
...:
Gennaio febbraio marzo dicembre

Non modificare un dizionario durante l'iterazione di una vista. Secondo la Sezione 4.10.1
1
della documentazione della libreria standard di Python, otterrai un RuntimeError o
il ciclo potrebbe non elaborare tutti i valori della vista.

1
ttps: //docs.python.org/3/library/stdtypes.html#dictionary
iewobjects .

Conversione di chiavi, valori e coppie chiave-valore del dizionario in elenchi

Occasionalmente potresti aver bisogno di elenchi di chiavi, valori o coppie chiave-valore di un dizionario. Per
ottenere tale elenco, passare la vista restituita da chiavi, valori o elementi al builtin

funzione lista. La modifica di questi elenchi non modifica il dizionario corrispondente:

lecca qui per visualizzare l'immagine del codice

In [9]: list (months.keys ())


In uscita [9]: ['Gennaio', 'Febbraio', 'Marzo', 'Dicembre']
In [10]: list (months.values ​())
Uscita [10]: [1, 2, 3, 12]

In [11]: list (months.items ())


Out [11]: [('January', 1), ('February', 2), ('March', 3), ('December', 12]

le chiavi in ​ordine ordinato

Per elaborare le chiavi in ordine ordinato , è possibile utilizzare la funzione incorporata ordinata come segue:

lecca qui per visualizzare l'immagine del codice

In [12]: per month_name in ordinato (months.keys ()):


...: print (month_name, end = '' )
...:
Febbraio dicembre gennaio marzo

6.2.5 Confronti di dizionari

P
C
hv
Pagina 234
Gli operatori di confronto == e! = Possono essere utilizzati per determinare se due
i dizionari hanno contenuti identici o diversi. Viene valutato un confronto uguale (==)

su True se entrambi i dizionari hanno le stesse coppie chiave-valore, indipendentemente dall'ordine in


quali coppie chiave-valore sono state aggiunte a ciascun dizionario:

lecca qui per visualizzare l'immagine del codice

In [1]: country_capitals1 = { "Belgium" : "Brussels" ,


...: 'Haiti' : 'PortauPrince' }
...:

In [2]: country_capitals2 = { 'Nepal' : 'Kathmandu' ,


...: 'Uruguay' : 'Montevideo' }
...:

In [3]: country_capitals3 = { 'Haiti' : 'PortauPrince' ,


...: "Belgium" : "Brussels" }
...:

In [4]: ​country_capitals1 == country_capitals2


Fuori [4]: ​Falso

In [5]: country_capitals1 == country_capitals3


Out [5]: Vero

In [6]: country_capitals1! = Country_capitals2


Out [6]: Vero

6.2.6 Esempio: Dizionario dei voti degli studenti


Il seguente script rappresenta il libro dei voti di un insegnante come un dizionario che mappa
il nome di ogni studente (una stringa) a un elenco di numeri interi contenente i voti di quello studente
tre esami. In ogni iterazione del ciclo che visualizza i dati (righe 13-17), noi
decomprimere una coppia chiave-valore nelle variabili nome e voti contenenti uno studente

nome e l'elenco corrispondente di tre gradi. La riga 14 usa la funzione incorporata sum to
totalizza i voti di un dato studente, quindi la riga 15 calcola e visualizza la media di quello studente
dividendo il totale per il numero di voti per quello studente (len (voti)). Righe 16–

17 tengono traccia del totale dei voti di tutti e quattro gli studenti e del numero di voti per tutti
gli studenti, rispettivamente. La riga 19 stampa la media della classe di tutti i voti degli studenti
tutti gli esami.
lecca qui per visualizzare l'immagine del codice

1 # fig06_01.py
2 "" "Usare un dizionario per rappresentare il registro dei voti di un insegnante." ""

3 grade_book = { Pagina 235


4 "Susan" : [ 92 , 85 , 100 ],
5 "Eduardo": [ 83 , 95 , 79 ],
6 "Azizi" : [ 91 , 89 , 82 ],
7 "Pantipa" : [ 97 , 91 , 92 ]
8 }
9
10 all_grades_total = 0
11 all_grades_count = 0
12
13 per nome, voti in grade_book.items ():
14 totale = somma (voti)
15 print (f 'La media per {nome} è {total / len (voti): .2 f} ' )
16 all_grades_total + = total
17 all_grades_count + = len (voti)
18
19 print (f "La media della classe è: {all_grades_total / all_grades_count: .2 f}

lecca qui per visualizzare l'immagine del codice

La media per Susan è 92,33


La media per Eduardo è 85,67
La media per Azizi è 87,33
La media per Pantipa è 93,33
La media della classe è: 89.67

2
6.2.7 Esempio: conteggio parole
2
Tecniche come il conteggio della frequenza delle parole vengono spesso utilizzate per analizzare le opere pubblicate.
Ad esempio, alcune persone credono che le opere di William Shakespeare potrebbero effettivamente farlo
sono stati scritti da Sir Francis Bacon, Christopher Marlowe o altri. Confrontando il
le frequenze delle parole delle loro opere con quelle di Shakespeare possono rivelare lo stile di scrittura
analogie. Vedremo altre tecniche di analisi documentale nel linguaggio naturale
Capitolo Processing (NLP).

Il seguente script crea un dizionario per contare il numero di occorrenze di ciascuno


parola in una stringa. Le righe 4-5 creano una stringa di testo che divideremo in parole: un processo
noto come tokenizzazione di una stringa . Python concatena automaticamente le stringhe separate
da spazi tra parentesi. La riga 7 crea un dizionario vuoto. Le chiavi del dizionario
saranno le parole univoche ei suoi valori saranno conteggi interi di quante volte ciascuno
la parola appare nel testo.

C
Pagina 236
lecca qui per visualizzare l'immagine del codice

1 # fig06_02.py
2 "" "Tokenizzazione di una stringa e conteggio di parole uniche." ""
3
4 text = ( 'questo è un testo di esempio con più parole'
5 "questo è più testo di esempio con alcune parole diverse" )
6
7 word_counts = {}
8
9 # conta le occorrenze di ogni parola unica
10 per la parola in text.split ():
11 if word in word_counts:
12 word_counts [word] + = 1 # aggiorna la coppia di valori chiave esistente
13 altro :
14 word_counts [word] = 1 # inserisce una nuova coppia di valori-chiave
15
16 print (f ' { "WORD" : < 12 } COUNT' )
17
18 per parola, conta in ordinato (word_counts.items ()):
19 print (f ' {word: < 12 } {count} ' )
20
21 print ( '\ nNumero di parole univoche:' , len (word_counts))

lecca qui per visualizzare l'immagine del codice

CONTE DI PAROLE
diverso 1
è2
più 1
campione 2
diversi 1
alcuni 1
testo 2
questo 2
con 2
parole 2
Numero di parole uniche: 10

La riga 10 tokenizza il testo chiamando il metodo di stringa split , che separa le parole

utilizzando l'argomento stringa delimitatore del metodo. Se non fornisci un argomento,


split usa uno spazio. Il metodo restituisce un elenco di token (ovvero le parole nel testo).
Le righe 10-14 scorrono l'elenco di parole. Per ogni parola, la riga 11 determina
se quella parola (la chiave) è già nel dizionario. In tal caso, la riga 12 lo incrementa

conteggio delle parole, altrimenti la riga 14 inserisce una nuova coppia chiave-valore per quella parola con un

C
Pagina 237
conteggio iniziale di 1.

Le righe 16–21 riassumono i risultati in una tabella a due colonne contenente ogni parola e la sua
conteggio corrispondente. L'istruzione for nelle righe 18 e 19 itera attraverso il

coppie chiave-valore del dizionario. Decomprime ogni chiave e valore nella parola delle variabili
e contare, quindi li visualizza in due colonne. La riga 21 mostra il numero di unici
parole.

Collezioni del modulo libreria standard Python

La libreria standard Python contiene già la funzionalità di conteggio che noi


implementato usando il dizionario e il ciclo nelle righe 10-14. Il modulo

collezioni contiene il tipo Counter , che riceve un iterabile e riepiloga


i suoi elementi. Reimplementiamo lo script precedente in meno righe di codice con

Contatore:

lecca qui per visualizzare l'immagine del codice

In [1]: dalle collezioni importa Counter

In [2]: text = ( "questo è un testo di esempio con diverse parole"


...: "questo è più testo di esempio con alcune parole diverse" )
...:
In [3]: counter = Counter (text.split ())

In [4]: per parola, conta in ordinato (counter.items ()):


...: print (f ' {word: < 12 } {count} ' )
...:
diverso 1
è2
più 1
campione 2
diversi 1
alcuni 1
testo 2
questo 2
con 2
parole 2

In [5]: print ( 'Numero di chiavi univoche:' , len (counter.keys ()))


Numero di chiavi univoche: 10

Snippet [3] crea il contatore, che riepiloga l'elenco delle stringhe restituite da

text.split (). Nello snippet [4], gli elementi del metodo Counter restituiscono ogni stringa e il relativo
conteggio associato come tupla. Usiamo la funzione incorporata ordinata per ottenere un elenco di queste tuple

C
Pagina 238
in ordine crescente. Per impostazione predefinita, ordinato ordina le tuple in base ai loro primi elementi. Se quelli
sono identici, quindi esamina il secondo elemento e così via. L'istruzione for itera
sull'elenco ordinato risultante, visualizzando ogni parola e conteggio in due colonne.

6.2.8 Aggiornamento del metodo del dizionario

È possibile inserire e aggiornare le coppie chiave-valore utilizzando l' aggiornamento del metodo del dizionario . Primo,
creiamo un dizionario country_codes vuoto:

In [1]: country_codes = {}

La seguente chiamata di aggiornamento riceve un dizionario di coppie chiave-valore da inserire o aggiornare:

lecca qui per visualizzare l'immagine del codice

In [2]: country_codes.update ({ 'South Africa' : 'za' })

In [3]: country_codes
In uscita [3]: {'South Africa': 'za'}

L'aggiornamento del metodo può convertire gli argomenti delle parole chiave in coppie chiave-valore da inserire. Il
la chiamata successiva converte automaticamente il nome del parametro Australia nella stringa

key "Australia" e associa il valore "ar" a tale chiave:

lecca qui per visualizzare l'immagine del codice

In [4]: ​country_codes.update (Australia = 'ar' )

In [5]: country_codes
Fuori [5]: {'South Africa': 'za', 'Australia': 'ar'}

Lo snippet [4] ha fornito un codice paese errato per l'Australia. Correggiamo questo

utilizzando un altro argomento di parola chiave per aggiornare il valore associato a "Australia":

lecca qui per visualizzare l'immagine del codice


In [6]: country_codes.update (Australia = 'au' )

In [7]: country_codes
Fuori [7]: {'South Africa': 'za', 'Australia': 'au'}

C
Pagina 239
L'aggiornamento del metodo può anche ricevere un oggetto iterabile contenente coppie chiave-valore, come
un elenco di tuple a due elementi.

6.2.9 Comprensioni del dizionario


Le comprensioni del dizionario forniscono una comoda notazione per la generazione rapida
dizionari, spesso mappando un dizionario a un altro. Ad esempio, in un dizionario
con valori univoci , puoi invertire le coppie chiave-valore:

lecca qui per visualizzare l'immagine del codice

In [1]: months = { 'January' : 1 , 'February' : 2 , 'March' : 3 }

In [2]: months2 = {number: name for name, number in months.items ()}

In [3]: months2
Uscita [3]: {1: 'gennaio', 2: 'febbraio', 3: 'marzo'}

Le parentesi graffe delimitano una comprensione del dizionario e l'espressione a sinistra di


La clausola for specifica una coppia chiave-valore nel formato chiave : valore . La comprensione
itera attraverso months.items (), decomprimendo ogni coppia chiave-valore tupla nel file
nome e numero delle variabili. L'espressione numero: nome inverte la chiave e
valore, in modo che il nuovo dizionario associ i numeri dei mesi ai nomi dei mesi.

E se i mesi contenessero valori duplicati ? Dato che queste diventano le chiavi in ​mesi2,
il tentativo di inserire una chiave duplicata aggiorna semplicemente il valore della chiave esistente. Quindi se

Originariamente "febbraio" e "marzo" erano entrambi mappati a 2, come avrebbe fatto il codice precedente
hanno prodotto

{1: 'January', 2: 'March'}

Una comprensione del dizionario può anche mappare i valori di un dizionario a nuovi valori. Il
la seguente comprensione converte un dizionario di nomi ed elenchi di voti in un file
dizionario dei nomi e medie dei voti. Le variabili k e v comunemente significano
chiave e valore :

lecca qui per visualizzare l'immagine del codice

In [4]: ​grades = { 'Sue' : [ 98 , 87 , 94 ], 'Bob' : [ 84 , 95 , 91 ]}

In [5]: grades2 = {k: sum (v) / len (v) for k, v in grades.items ()}

C
Pagina 240
In [6]: gradi2
Uscita [6]: {'Sue': 93.0, 'Bob': 90.0}

La comprensione scompatta ogni tupla restituita da grades.items () in k (il


nome) ev (l'elenco dei voti). Quindi, la comprensione crea una nuova coppia chiave-valore

con la chiave k e il valore di sum (v) / len (v), che media gli elementi della lista.
6.3 SET
Un set è una raccolta non ordinata di valori univoci . I set possono contenere solo immutabili
oggetti, come stringhe, int, float e tuple che contengono solo elementi immutabili.
Sebbene i set siano iterabili, non sono sequenze e non supportano l'indicizzazione e
affettare con parentesi quadre, []. I dizionari inoltre non supportano la suddivisione in sezioni.

Creazione di un set con parentesi graffe


Il codice seguente crea un set di stringhe denominate colors:

lecca qui per visualizzare l'immagine del codice

In [1]: colors = { 'red' , 'orange' , 'yellow' , 'green' , 'red' , 'blue' }

In [2]: colori
In uscita [2]: {"blue", "green", "orange", "red", "yellow"}

Notare che la stringa duplicata "rossa" è stata ignorata (senza causare un errore). Un
un uso importante dei set è l' eliminazione dei duplicati , che è automatica quando si crea un file
impostato. Inoltre, i valori del set risultante non vengono visualizzati nello stesso ordine in cui erano
elencato nello snippet [1]. Sebbene i nomi dei colori siano visualizzati in ordine ordinato, i set lo sono
non ordinato . Non dovresti scrivere codice che dipende dall'ordine dei loro elementi.

Determinazione della lunghezza di un set

È possibile determinare il numero di elementi in un set con la funzione len incorporata:

In [3]: len (colori)


Fuori [3]: 5

Verificare se un valore è in un set

È possibile verificare se un set contiene un valore particolare utilizzando in e not in

C
Pagina 241
operatori:

lecca qui per visualizzare l'immagine del codice

In [4]: "rosso" nei colori


Out [4]: ​vero

In [5]: "viola" nei colori


Fuori [5]: Falso

In [6]: "viola" non nei colori


Out [6]: Vero

Iterazione attraverso un set


Gli insiemi sono iterabili, quindi puoi elaborare ogni elemento dell'insieme con un ciclo for:

lecca qui per visualizzare l'immagine del codice

In [7]: per il colore nei colori:


...: print (color.upper (), end = '' )
...:
ROSSO VERDE GIALLO BLU ARANCIONE
Gli insiemi non sono ordinati , quindi non c'è alcun significato per l'ordine di iterazione.

Creazione di un set con la funzione set incorporato

È possibile creare un set da un'altra raccolta di valori utilizzando la funzione set incorporata
—Qui creiamo un elenco che contiene diversi valori interi duplicati e utilizziamo tale elenco come

argomento di set:

lecca qui per visualizzare l'immagine del codice

In [8]: numeri = elenco (intervallo ( 10 )) + elenco (intervallo ( 5 ))

In [9]: numeri
Uscita [9]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4]

In [10]: set (numeri)


Fuori [10]: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

Se è necessario creare un set vuoto, è necessario utilizzare la funzione set con empty

parentesi, piuttosto che parentesi graffe vuote, {}, che rappresentano un dizionario vuoto:

C
Pagina 242
In [11]: set ()
Uscita [11]: set ()

Python mostra un set vuoto come set () per evitare confusione con la stringa di Python

rappresentazione di un dizionario vuoto ({}).

Frozenset: un tipo di set immutabile


I set sono mutabili -È possibile aggiungere e rimuovere elementi, ma insieme elementi deve essere
immutabile . Pertanto, un insieme non può avere altri insiemi come elementi. Un frozenset è un file
insieme immutabile : non può essere modificato dopo averlo creato, quindi un insieme può contenere congelamenti
come elementi. La funzione incorporata frozenset crea un frozenset da qualsiasi iterabile.

6.3.1 Confronto di insiemi


Vari operatori e metodi possono essere utilizzati per confrontare gli insiemi. I seguenti set contengono
gli stessi valori, quindi == restituisce True e! = restituisce False.

lecca qui per visualizzare l'immagine del codice

In [1]: { 1 , 3 , 5 } == { 3 , 5 , 1 }
Out [1]: vero

In [2]: { 1 , 3 , 5 }! = { 3 , 5 , 1 }
Fuori [2]: Falso

L'operatore <verifica se l'insieme alla sua sinistra è un sottoinsieme appropriato di quello alla sua destra
- cioè, tutti gli elementi nell'operando di sinistra sono nell'operando di destra e gli insiemi lo sono
non uguale:

lecca qui per visualizzare l'immagine del codice

In [3]: { 1 , 3 , 5 } <{ 3 , 5 , 1 }
Fuori [3]: Falso

In [4]: ​{ 1 , 3 , 5 } <{ 7 , 3 , 5 , 1 }
Out [4]: ​vero
L'operatore <= verifica se l'insieme alla sua sinistra è un sottoinsieme improprio di quello alla sua
a destra, ovvero tutti gli elementi nell'operando di sinistra si trovano nell'operando di destra e negli insiemi
potrebbe essere uguale:

C
Pagina 243
lecca qui per visualizzare l'immagine del codice

In [5]: { 1 , 3 , 5 } <= { 3 , 5 , 1 }
Out [5]: Vero

In [6]: { 1 , 3 } <= { 3 , 5 , 1 }
Out [6]: Vero

Puoi anche verificare la presenza di un sottoinsieme non corretto con il metodo set issubset :

lecca qui per visualizzare l'immagine del codice

In [7]: { 1 , 3 , 5 } .issubset ({ 3 , 5 , 1 })
Out [7]: Vero

In [8]: { 1 , 2 } .issubset ({ 3 , 5 , 1 })
Fuori [8]: Falso

L'operatore> verifica se l'insieme alla sua sinistra è un superset appropriato di quello alla sua
right, ovvero tutti gli elementi nell'operando di destra si trovano nell'operando di sinistra e in quello di sinistra
operando ha più elementi:

lecca qui per visualizzare l'immagine del codice

In [9]: { 1 , 3 , 5 }> { 3 , 5 , 1 }
Fuori [9]: Falso

In [10]: { 1 , 3 , 5 , 7 }> { 3 , 5 , 1 }
Out [10]: Vero

L'operatore> = verifica se l'insieme alla sua sinistra è un superset errato di quello a


è a destra, ovvero tutti gli elementi nell'operando di destra si trovano nell'operando di sinistra e il
gli insiemi potrebbero essere uguali:

lecca qui per visualizzare l'immagine del codice

In [11]: { 1 , 3 , 5 }> = { 3 , 5 , 1 }
Out [11]: Vero

In [12]: { 1 , 3 , 5 }> = { 3 , 1 }
Out [12]: Vero

In [13]: { 1 , 3 }> = { 3 , 1 , 7 }
Out [13]: Falso

C
Pagina 244

Puoi anche verificare la presenza di un superset improprio con il metodo set issuperset :

lecca qui per visualizzare l'immagine del codice

In [14]: { 1 , 3 , 5 } .issuperset ({ 3 , 5 , 1 })
Out [14]: Vero
In [15]: { 1 , 3 , 5 } .issuperset ({ 3 , 2 })
Out [15]: Falso

L'argomento per issubset o issuperset può essere qualsiasi iterabile. Quando uno di questi

metodi riceve un argomento iterabile non impostato, prima converte l'iterabile in un insieme, quindi
esegue l'operazione.

6.3.2 Operazioni matematiche sugli insiemi


Questa sezione presenta gli operatori matematici del tipo di insieme |, & e ^ e il

metodi corrispondenti.

Unione

L' unione di due set è un set composto da tutti gli elementi unici di entrambi i set. tu
può calcolare l'unione con il | operatore o con il metodo union del tipo set :

lecca qui per visualizzare l'immagine del codice

In [1]: { 1 , 3 , 5 } | { 2 , 3 , 4 }
Fuori [1]: {1, 2, 3, 4, 5}

In [2]: { 1 , 3 , 5 } .union ([ 20 , 20 , 3 , 40 , 40 ])
Fuori [2]: {1, 3, 5, 20, 40}

Gli operandi degli operatori di insieme binario, come |, devono essere entrambi set. Il corrispondente
I metodi set possono ricevere qualsiasi oggetto iterabile come argomento: abbiamo passato una lista. Quando un
Il metodo set matematico riceve un argomento iterabile non impostato, prima converte il file
iterabile a un insieme, quindi applica l'operazione matematica. Anche in questo caso, sebbene i nuovi set '
le rappresentazioni di stringa mostrano i valori in ordine crescente, non dovresti scrivere codice
dipende da questo.

Intersezione

L' intersezione di due insiemi è un insieme costituito da tutti gli elementi unici che i due

C
Pagina 245
i set hanno in comune. Puoi calcolare l'intersezione con l' operatore & o con

il metodo di intersezione del tipo di set :

lecca qui per visualizzare l'immagine del codice

In [3]: { 1 , 3 , 5 } e { 2 , 3 , 4 }
Fuori [3]: {3}

In [4]: ​{ 1 , 3 , 5 } .intersection ([ 1 , 2 , 2 , 3 , 3 , 4 , 4 ])
Fuori [4]: ​{1, 3}

Differenza

La differenza tra due insiemi è un insieme costituito dagli elementi nell'operando di sinistra
che non si trovano nell'operando corretto. Puoi calcolare la differenza con l' operatore

o con il metodo della differenza del tipo impostato :

lecca qui per visualizzare l'immagine del codice

In [5]: { 1 , 3 , 5 } { 2 , 3 , 4 }
Fuori [5]: {1, 5}

In [6]: { 1 , 3 , 5 , 7 } .difference ([ 2 , 2 , 3 , 3 , 4 , 4 ])
Uscita [6]: {1, 5, 7}

Differenza simmetrica

La differenza simmetrica tra due insiemi è un insieme costituito dagli elementi di


entrambi i set che non sono in comune tra loro. Puoi calcolare il simmetrico
differenza con l' operatore ^ o con symmetric_difference del tipo set

metodo:

lecca qui per visualizzare l'immagine del codice

In [7]: { 1 , 3 , 5 } ^ { 2 , 3 , 4 }
Fuori [7]: {1, 2, 4, 5}

In [8]: { 1 , 3 , 5 , 7 } .symmetric_difference ([ 2 , 2 , 3 , 3 , 4 , 4 ])
Fuori [8]: {1, 2, 4, 5, 7}

Disarticolare

Due insiemi sono disgiunti se non hanno elementi comuni. Puoi determinare

C
Pagina 246
questo con il metodo isdisjoint del tipo set :

lecca qui per visualizzare l'immagine del codice

In [9]: { 1 , 3 , 5 } .isdisjoint ({ 2 , 4 , 6 })
Out [9]: Vero

In [10]: { 1 , 3 , 5 } .isdisjoint ({ 4 , 6 , 1 })
Out [10]: Falso

6.3.3 Operatori e metodi degli insiemi modificabili


Gli operatori e i metodi presentati nella sezione precedente risultano ciascuno in un nuovo insieme.
Qui discutiamo operatori e metodi che modificano un insieme esistente .

Operazioni matematiche sugli insiemi mutevoli


Come l'operatore |, l' assegnazione aumentata di unione | = esegue un'operazione di unione impostata,

ma | = modifica il suo operando sinistro:

lecca qui per visualizzare l'immagine del codice

In [1]: numeri = { 1 , 3 , 5 }

In [2]: numeri | = { 2 , 3 , 4 }

In [3]: numeri
Fuori [3]: {1, 2, 3, 4, 5}

Allo stesso modo, il metodo di aggiornamento del tipo di set esegue un'operazione di unione che modifica il set
su cui è chiamato, l'argomento può essere qualsiasi iterabile:

lecca qui per visualizzare l'immagine del codice

In [4]: ​numbers.update (range ( 10 ))

In [5]: numeri
Uscita [5]: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
Gli altri metodi degli insiemi modificabili sono:

assegnazione aumentata di intersezione & =

C
Pagina 247
assegnazione aumentata di differenza =

assegnazione aumentata a differenza simmetrica ^ =

ei metodi corrispondenti con argomenti iterabili sono:

intersection_update

differenziale_update

symmetric_difference_update

Metodi per aggiungere e rimuovere elementi

Il metodo set add inserisce il suo argomento se l'argomento non è già nel set;
in caso contrario, il set rimane invariato:

lecca qui per visualizzare l'immagine del codice

In [6]: numbers.add ( 17 )

In [7]: numbers.add ( 3 )

In [8]: numeri
Fuori [8]: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 17}

Il metodo set remove rimuove il suo argomento dal set: si verifica un'eccezione KeyError se il
il valore non è nel set:

lecca qui per visualizzare l'immagine del codice

In [9]: numbers.remove ( 3 )

In [10]: numeri
Fuori [10]: {0, 1, 2, 4, 5, 6, 7, 8, 9, 17}

Il metodo discard rimuove anche il suo argomento dall'insieme ma non causa un


eccezione se il valore non è nel set.

Puoi anche rimuovere un elemento set arbitrario e restituirlo con pop , ma i set lo sono
non ordinato, quindi non sai quale elemento verrà restituito:

C
Pagina 248
lecca qui per visualizzare l'immagine del codice

In [11]: numbers.pop ()
Uscita [11]: 0

In [12]: numeri
Fuori [12]: {1, 2, 4, 5, 6, 7, 8, 9, 17}
Un KeyError si verifica se il set è vuoto quando chiami pop.

Infine, il metodo clear svuota il set su cui è chiamato:

In [13]: numbers.clear ()

In [14]: numeri
Uscita [14]: set ()

6.3.4 Imposta comprensioni


Come le comprensioni del dizionario, definisci le comprensioni degli insiemi tra parentesi graffe. Facciamo
creare un nuovo set contenente solo i valori pari univoci nei numeri dell'elenco:

lecca qui per visualizzare l'immagine del codice

In [1]: numeri = [ 1 , 2 , 2 , 3 , 4 , 5 , 6 , 6 , 7 , 8 , 9 , 10 , 10 ]

In [2]: evens = {item for item in numbers if item% 2 == 0 }

In [3]: pari
Uscita [3]: {2, 4, 6, 8, 10}

6.4 INTRO ALLA DATA SCIENCE: DYNAMIC


VISUALIZZAZIONI
La sezione Intro to Data Science del capitolo precedente ha introdotto la visualizzazione. Noi
simulava il lancio di un dado a sei facce e utilizzava la visualizzazione di Seaborn e Matplotlib
librerie per creare un grafico a barre statiche di qualità della pubblicazione che mostri le frequenze e
percentuali di ogni valore di lancio. In questa sezione, facciamo "prendere vita" le cose con
visualizzazioni dinamiche .

La legge dei grandi numeri

C
Pagina 249
hen abbiamo introdotto la generazione randomnumber, abbiamo detto che if random

la funzione randrange del modulo produce effettivamente numeri interi a caso, quindi ogni numero
nell'intervallo specificato ha la stessa probabilità (o probabilità) di essere scelto ogni volta
la funzione viene chiamata. Per un dado a sei facce, ogni valore da 1 a 6 dovrebbe verificarsi un ottavo
th
del tempo, quindi la probabilità che uno qualsiasi di questi valori si verifichi è 1/6 o circa
16,667%.

Nella sezione successiva, creiamo ed eseguiamo un dierolling dinamico (cioè animato )


script di simulazione. In generale, vedrai che più tiri tentiamo, più vicini ciascuno
la percentuale del valore del dado sul totale dei tiri arriva al 16,667% e l'altezza delle barre
gradualmente diventare più o meno lo stesso. Questa è una manifestazione della legge dei grandi numeri .

6.4.1 Come funziona la visualizzazione dinamica


Le trame prodotte con Seaborn e Matplotlib nell'Intro ai dati del capitolo precedente
La sezione Scienza ti aiuta ad analizzare i risultati per un numero fisso di tiri di dado dopo il
la simulazione viene completata. Questa sezione migliora quel codice con Matplotlib

l'animazione del modulo FuncAnimation funzione, che aggiorna il grafico a barre


dinamicamente . Vedrai le barre, le frequenze e le percentuali "prendere vita",
aggiornamento continuo man mano che si verificano i rulli.
Fotogrammi di animazione

FuncAnimation guida un'animazione framebyframe . Ogni fotogramma dell'animazione


specifica tutto ciò che dovrebbe cambiare durante un aggiornamento della trama. Stringendo insieme
molti di questi aggiornamenti nel tempo creano l'effetto di animazione. Tu decidi cosa ciascuno
frame viene visualizzato con una funzione definita dall'utente e passata a FuncAnimation.

Ogni fotogramma dell'animazione:

lancia i dadi un numero di volte specificato (da 1 a quante ne desideri), aggiornando


frequenze del dado con ogni lancio,

cancella la trama attuale,

creare un nuovo set di barre che rappresentano le frequenze aggiornate e

creare nuova frequenza e testo percentuale per ogni barra.

In genere, la visualizzazione di più fotogrammi al secondo produce un'animazione più fluida. Per
Ad esempio, i videogiochi con elementi in rapido movimento cercano di visualizzare almeno 30 fotogrammi per

W
Pagina 250
secondo e spesso di più. Sebbene tu specifichi il numero di millisecondi tra
fotogrammi di animazione, il numero effettivo di fotogrammi al secondo può essere influenzato dal file
quantità di lavoro che esegui in ogni fotogramma e la velocità del processore del tuo computer.
Questo esempio mostra un fotogramma di animazione ogni 33 millisecondi, cedendo
circa 30 (1000/33) fotogrammi per secondo. Prova valori più grandi e più piccoli per vedere
come influenzano l'animazione. La sperimentazione è importante per sviluppare il meglio
visualizzazioni.

Esecuzione di RollDieDynamic.py

Nella sezione Intro to Data Science del capitolo precedente, abbiamo sviluppato il file static
visualizzazione interattiva in modo da poter vedere come il codice aggiorna il grafico a barre mentre lo fai
eseguire ogni istruzione. Il grafico a barre effettivo con le frequenze e le percentuali finali
è stato disegnato una sola volta.

Per questa visualizzazione dinamica, i risultati dello schermo si aggiornano frequentemente in modo che tu possa vedere
l'animazione. Molte cose cambiano continuamente: le lunghezze delle barre, i
frequenze e percentuali sopra le barre, la spaziatura e le etichette sugli assi e il
numero totale di tiri di dado mostrato nel titolo della trama. Per questo motivo, presentiamo questo
visualizzazione come un copione, piuttosto che svilupparlo interattivamente.

Lo script accetta due argomenti della riga di comando:

number_of_frames: il numero di frame di animazione da visualizzare. Questo valore


determina il numero totale di volte in cui FuncAnimation aggiorna il grafico. Per

ogni fotogramma dell'animazione, FuncAnimation chiama una funzione definita dall'utente (in this
esempio, update) per specificare come modificare il grafico.

rolls_per_frame: il numero di volte in cui tirare il dado in ogni fotogramma dell'animazione.


Useremo un ciclo per tirare il dado questo numero di volte, quindi riassumeremo i risultati
aggiorna il grafico con barre e testo che rappresentano le nuove frequenze.

Per capire come utilizziamo questi due valori, considera il seguente comando:

ipython RollDieDynamic.py 6000 1


In questo caso, FuncAnimation chiama la nostra funzione di aggiornamento 6000 volte, lanciando un dado
per frame per un totale di 6000 rotoli. Ciò consente di vedere le barre, le frequenze e
le percentuali si aggiornano un tiro alla volta. Sul nostro sistema, questa animazione ha richiesto circa 3,33
minuti (6000 fotogrammi / 30 fotogrammi al secondo / 60 secondi al minuto) per mostrarti

Pagina 251
solo 6000 tiri di dado.

La visualizzazione dei fotogrammi dell'animazione sullo schermo è un input-output relativamente lento


funzionamento rispetto ai rotoli di dado, che avvengono sulla super veloce CPU del computer
velocità. Se tiriamo un solo dado per fotogramma di animazione, non saremo in grado di eseguire un grande
numero di rotoli in un ragionevole lasso di tempo. Inoltre, per piccoli numeri di rotoli, sei
è improbabile che le percentuali di dadi convergono sul loro previsto 16,667% dei tiri totali.

Per vedere la legge dei grandi numeri in azione, puoi aumentare la velocità di esecuzione di
tirando il dado più volte per fotogramma dell'animazione. Considera il seguente comando:

ipython RollDieDynamic.py 10000600

In questo caso, FuncAnimation chiamerà la nostra funzione di aggiornamento 10.000 volte, eseguendo
600 rotoli per cornice per un totale di 6.000.000 rotoli. Sul nostro sistema, ci sono voluti circa 5,55
minuti (10.000 fotogrammi / 30 fotogrammi al secondo / 60 secondi al minuto), ma
visualizzato circa 18.000 rulli al secondo (30 fotogrammi al secondo * 600 rulli
perframe), così abbiamo potuto vedere rapidamente le frequenze e le percentuali convergere sui loro
valori attesi di circa 1.000.000 di rotoli per faccia e 16,667% per faccia.

Sperimenta con il numero di rotoli e fotogrammi finché non senti che il programma è
aiutandoti a visualizzare i risultati nel modo più efficace. È divertente e istruttivo guardarlo
esegui e modificalo finché non sei soddisfatto della qualità dell'animazione.

Esecuzioni di esempio

Abbiamo acquisito le seguenti quattro schermate durante ciascuna delle due esecuzioni di esempio. Nel
il primo, le schermate mostrano il grafico dopo appena 64 tiri di dado, poi di nuovo dopo 604 di
6000 tiri di dado totali. Esegui questo script dal vivo per vedere nel tempo come si aggiornano le barre
dinamicamente. Nella seconda esecuzione, le catture dello schermo mostrano il grafico dopo 7200
tiri di dado e di nuovo dopo 166.200 dei 6.000.000 di tiri. Con più rotoli, puoi
vedere le percentuali che si avvicinano ai valori attesi del 16,667% come previsto dal
legge dei grandi numeri.

Pagina 252
.4.2 Implementazione di una visualizzazione dinamica
Lo script che presentiamo in questa sezione utilizza le stesse funzionalità di Seaborn e Matplotlib
mostrato nella sezione Intro to Data Science del capitolo precedente. Abbiamo riorganizzato il codice
da utilizzare con le capacità di animazione di Matplotlib .

Importazione del modulo di animazione Matplotlib

Ci concentriamo principalmente sulle nuove funzionalità utilizzate in questo esempio. La riga 3 importa il file
Modulo di animazione Matplotlib.

lecca qui per visualizzare l'immagine del codice

1 # RollDieDynamic.py

6
C

2 "" "Rappresentazione grafica dinamica delle frequenze dei lanci di dadi." "" Pagina 253
3 da matplotlib importazione di animazione
4 importa matplotlib.pyplot come plt
5 importazione casuale
6 import Seaborn come sns
7 import sys
8

Aggiornamento delle funzioni

Le righe 9–27 definiscono la funzione di aggiornamento che FuncAnimation chiama una volta per animazione

telaio. Questa funzione deve fornire almeno un argomento. Le righe 9-10 mostrano il file
inizio della definizione della funzione. I parametri sono:

frame_number: il valore successivo dall'argomento frames di FuncAnimation,


di cui parleremo tra poco. Sebbene FuncAnimation richieda l'aggiornamento
funzione per avere questo parametro, non lo usiamo in questa funzione di aggiornamento.

tiri: il numero di tiri di dado per fotogramma dell'animazione.

facce: i valori delle facce della fustella utilizzati come etichette lungo l' asse x del grafico .
frequenze: l'elenco in cui riassumiamo le frequenze dello stampo.

Discuteremo il resto del corpo della funzione nelle prossime sottosezioni.

lecca qui per visualizzare l'immagine del codice

9 aggiornamento def (frame_number, roll, faces, frequencies):


10 "" "Configura i contenuti del grafico a barre per ogni fotogramma dell'animazione." ""

Aggiornamento delle funzioni: lancio del dado e aggiornamento dell'elenco delle frequenze

Le linee 12-13 tirano i tempi di lancio del dado e incrementano le frequenze appropriate

elemento per ogni rotolo. Nota che sottraiamo 1 dal valore del dado (da 1 a 6) prima
incrementando l'elemento frequenze corrispondenti, come vedrai, frequenze

è un elenco di sei elementi (definito nella riga 36), quindi i suoi indici vanno da 0 a 5.

lecca qui per visualizzare l'immagine del codice

11 # lancia il dado e aggiorna le frequenze


12 per i in gamma (rotoli):

13 frequenze [random.randrange ( 1 , 7 ) 1 ] + = 1 Pagina 254


14

Aggiornamento delle funzioni: configurazione del grafico a barre e del testo

Linea 16 in aggiornamento chiamate di funzione del modulo matplotlib.pyplot CLA (assi chiare)

per rimuovere gli elementi del grafico a barre esistenti prima di disegnarne di nuovi per il file
fotogramma di animazione corrente. Abbiamo discusso il codice nelle righe 17–27 nel precedente
sezione Intro to Data Science del capitolo. Le righe 17-20 creano le barre, impostano il grafico a barre
titolo, impostare le x ed y asse etichette e scalare la trama per fare spazio per la frequenza e
testo percentuale sopra ogni barra. Le righe 23–27 visualizzano la frequenza e il testo percentuale.

lecca qui per visualizzare l'immagine del codice

15 # riconfigurare il grafico per le frequenze del die aggiornate


16 plt.cla () # cancella i vecchi contenuti della figura corrente
17 assi = sns. barplot (facce, frequenze, tavolozza = 'luminoso' ) # ne bar
18 axes.set_title (f 'Die Frequencies for {sum (frequencies) :,} Rolls' )
19 assi.set (xlabel = 'Die Value' , ylabel = 'Frequency' )
20 assi.set_ylim (top = max (frequenze) * 1.10 ) # scala asse y dello 0%
21
22 # frequenza di visualizzazione e percentuale sopra ogni patch (barra)
23 per bar, frequenza in zip (axes.patches, frequenze):
24 text_x = bar.get_x () + bar.get_width () / 2.0
25 text_y = bar.get_height ()
26 text = f ' {frequenza :,} \ n {frequenza / somma (frequenze) :. 3%}
27 assi.text (text_x, text_y, text, ha = 'center' , va = 'bottom' )
28

Variabili utilizzate per configurare il grafico e mantenere lo stato

Le righe 30 e 31 utilizzano l'elenco argv del modulo sys per ottenere la riga di comando dello script

argomenti. La riga 33 specifica lo stile "whitegrid" di Seaborn. La linea 34 chiama il

funzione figure del modulo matplotlib.pyplot per ottenere l'oggetto Figure in cui

FuncAnimation visualizza l'animazione. L'argomento della funzione è il titolo della finestra.


Come vedrai presto, questo è uno degli argomenti obbligatori di FuncAnimation. La riga 35 crea

un elenco contenente i valori delle facce 1–6 della fustella da visualizzare sull'asse x del grafico. La riga 36 crea
l'elenco delle frequenze a sei elementi con ogni elemento inizializzato a 0: lo aggiorniamo
i conteggi della lista con ogni tiro di dado.

lecca qui per visualizzare l'immagine del codice

29 # legge gli argomenti della riga di comando per il numero di frame e roll per frame

30 number_of_frames = int (sys.argv [ 1 ]) Pagina 255


31 rolls_per_frame = int (sys.argv [ 2 ])
32
33 sns.set_style ( 'whitegrid' ) # sfondo bianco con griglie grigie
34 figure = plt. Figure ( 'Rotolare un dado a sei facce' ) # Figura per l'animazione
35 valori = lista (intervallo ( 1 , 7 )) # facce dado per la visualizzazione sull'asse x
36 frequenze = [ 0 ] * 6 # elenco di sei elementi delle frequenze del dado
37

allingando la funzione FuncAnimation del modulo di animazione

Le righe 39–41 chiamano la funzione FuncAnimation del modulo di animazione Matplotlib a


aggiorna dinamicamente il grafico a barre. La funzione restituisce un oggetto che rappresenta il file
animazione. Sebbene non venga utilizzato in modo esplicito, è necessario memorizzare il riferimento al file
animazione; in caso contrario, Python termina immediatamente l'animazione e restituisce il suo file
memoria al sistema.

lecca qui per visualizzare l'immagine del codice

38 # configura e avvia l'animazione che richiama l'aggiornamento della funzione


39 die_animation = animation.FuncAnimation (
40 cifre, aggiorna, ripeti = False , frames = number_of_frames, interva =
41 farg = (rolls_per_frame, valori, frequenze))
42
43 plt. Mostra () # finestra di visualizzazione

FuncAnimation ha due argomenti obbligatori:

figura: l'oggetto Figura in cui visualizzare l'animazione e

aggiornamento: la funzione da chiamare una volta per fotogramma dell'animazione.

In questo caso, passiamo anche i seguenti argomenti di parole chiave opzionali:

ripeti: Falso termina l'animazione dopo il numero di fotogrammi specificato. Se

True (impostazione predefinita), quando l'animazione viene completata, viene riavviata dall'inizio.

frames : il numero totale di frame di animazione, che controlla quante volte


FunctAnimation chiama update. Passare un numero intero equivale a passare un file
intervallo: ad esempio, 600 significa intervallo (600). FuncAnimation passa un valore
da questo intervallo come primo argomento in ogni chiamata da aggiornare.

C
C
Pagina 256
intervallo : il numero di millisecondi (33, in questo caso) tra l'animazione
frame (il valore predefinito è 200). Dopo ogni chiamata per l'aggiornamento, FuncAnimation attende 33
millisecondi prima di effettuare la chiamata successiva.

fargs (abbreviazione di " function arguments") - Una tupla di altri argomenti da passare a
funzione specificata nel secondo argomento di FuncAnimation. Gli argomenti tu
specificati nella tupla fargs corrispondono ai parametri di aggiornamento roll, faces e
frequenze (riga 9).

Per un elenco degli altri argomenti facoltativi di FuncAnimation, vedere

ttps: //matplotlib.org/api/_as_gen/matplotlib.animation.FuncAnimation.html

Infine, la riga 43 mostra la finestra.

6.5 WRAP-UP
In questo capitolo, abbiamo discusso il dizionario di Python e le raccolte di set. Abbiamo detto cosa a
dizionario è e ha presentato diversi esempi. Abbiamo mostrato la sintassi delle coppie chiave-valore
e ha mostrato come usarli per creare dizionari con elenchi di chiavi separati da virgole–
coppie di valori tra parentesi graffe, {}. Hai anche creato dizionari con dizionario

comprensioni.

Hai utilizzato le parentesi quadre, [], per recuperare il valore corrispondente a una chiave e per inserire
e aggiorna le coppie chiave-valore. Hai anche utilizzato l'aggiornamento del metodo del dizionario per modificare un file

valore associato alla chiave. Hai ripetuto le chiavi, i valori e gli elementi di un dizionario.

Hai creato serie di valori immutabili univoci. Hai confrontato i set con il confronto
operatori, insiemi combinati con operatori e metodi di insieme, valori di insiemi modificati con l'estensione
operazioni sugli insiemi mutabili e insiemi creati con comprensioni di insiemi Hai visto che i set lo sono
mutevole. I Frozenset sono immutabili, quindi possono essere usati come elementi set e Frozenset.

Nella sezione Introduzione alla scienza dei dati, abbiamo continuato la nostra introduzione alla visualizzazione di
presentando la simulazione del dierolling con un grafico a barre dinamico per rendere la legge del grande
numeri "prendono vita". Inoltre, alle funzionalità Seaborn e Matplotlib mostrate in
Nella sezione Intro to Data Science del capitolo precedente, abbiamo utilizzato FuncAnimation di Matplotlib
funzione per controllare un'animazione frameebyframe. FuncAnimation ha chiamato una funzione we

definito che specifica cosa visualizzare in ogni fotogramma dell'animazione.

Pagina 257
Nel prossimo capitolo, discuteremo della programmazione orientata agli array con il popolare NumPy
biblioteca. Come vedrai, la raccolta ndarray di NumPy può contenere fino a due ordini di
magnitude più veloce rispetto all'esecuzione di molte delle stesse operazioni con il builtin di Python
elenchi. Questa potenza tornerà utile per le odierne applicazioni Big Data.
io
Pagina 258

Playlist

storia . Programmazione orientata agli array con NumPy


Obiettivi
opiche

In questo capitolo potrai:


guadagnando Pat

Scopri come gli array differiscono dagli elenchi.


ffers & Dea

Usa gli ndarrays ad alte prestazioni del modulo numpy.


ighlights

Confronta le prestazioni di elenco e ndarray con IPython% timeit magic.


ettings

Usa ndarrays per archiviare e recuperare i dati in modo efficiente.


Supporto

Crea e inizializza ndarrays.


Disconnessione

Fare riferimento ai singoli elementi ndarray.

Scorri tra gli ndarrays.

Crea e manipola ndarrays multidimensionali.

Eseguire comuni manipolazioni ndarray.

Crea e manipola i panda in serie monodimensionali e bidimensionali

DataFrames.

Personalizza gli indici di serie e DataFrame.

Calcola le statistiche descrittive di base per i dati in una serie e in un DataFrame.


Personalizza la precisione del numero in virgola mobile nella formattazione dell'output dei panda.

Contorno

7
Pagina 259
.1 Introduzione

.2 Creazione di array da dati esistenti

.3 attributi array

.4 Riempimento di array con valori specifici

.5 Creazione di array da intervalli

.6 Prestazioni tra elenchi e array: presentazione di% timeit

.7 Operatori di array

.8 Metodi di calcolo NumPy

.9 Funzioni universali

.10 Indicizzazione e sezionamento

.11 Visualizzazioni: copie poco profonde

.12 Copie profonde

.13 Rimodellamento e trasposizione

.14 Introduzione alla scienza dei dati: panda Series e DataFrame

.14.1 Serie panda

.14.2 DataFrame

.15 WrapUp

7.1 INTRODUZIONE
La libreria NumPy (Numerical Python) è apparsa per la prima volta nel 2006 ed è la preferita
Implementazione di array Python. Offre un elevato rendimento, riccamente funzionale n
tipo di array dimensionale chiamato ndarray , a cui da questo punto in avanti faremo riferimento con

il suo sinonimo, array. NumPy è una delle tante librerie opensource che il
La distribuzione di Anaconda Python viene installata. Le operazioni sugli array sono fino a due ordini di

7
Pagina 260
magnitudo più veloce di quelle sugli elenchi. In un mondo bigdata in cui le applicazioni possono funzionare
enormi quantità di elaborazione su grandi quantità di dati basati su array, questa prestazione
il vantaggio può essere critico. Secondo libraries.io, oltre 450 librerie Python

dipendono da NumPy. Molte popolari biblioteche di data science come Pandas, SciPy
(Scientific Python) e Keras (per il deep learning) sono basati o dipendono da NumPy.
In questo capitolo, esploriamo le funzionalità di base dell'array. Gli elenchi possono avere più file
dimensioni. In genere si elaborano elenchi multidimensionali con loop o elenchi nidificati
comprensioni con clausole for multiple. Un punto di forza di NumPy è "orientato all'array"

programmazione ", che utilizza la programmazione in stile funzionale con iterazione interna a
rendere le manipolazioni degli array concise e dirette, eliminando i tipi di bug
ciò può verificarsi con l' iterazione esterna di cicli programmati esplicitamente.

Nella sezione Intro to Data Science di questo capitolo, iniziamo la nostra introduzione multisezione
alla libreria panda che utilizzerai in molti dei capitoli dei case study di data science. Grande
le applicazioni dati spesso necessitano di raccolte più flessibili rispetto agli array di NumPy—
raccolte che supportano tipi di dati misti, indicizzazione personalizzata, dati mancanti, dati
non strutturati in modo coerente e dati che devono essere manipolati in forme
appropriato per i database e i pacchetti di analisi dei dati utilizzati. Ti presenteremo
panda arraylike serie unidimensionale e DataFrame bidimensionali e
iniziare a dimostrare le loro potenti capacità. Dopo aver letto questo capitolo, lo sarai
familiarità con quattro raccolte simili ad array: elenchi, array, serie e DataFrame.

Aggiungeremo un quinto - tensori - nel capitolo "Apprendimento profondo".

7.2 CREAZIONE DI ARRAY DA DATI ESISTENTI


La documentazione di NumPy consiglia di importare il modulo numpy come np in modo che
puoi accedere ai suoi membri con "np.":

In [1]: importa numpy come np

Il modulo numpy fornisce varie funzioni per la creazione di array. Qui usiamo il

funzione array , che riceve come argomento un array o un'altra raccolta di file
elementi e restituisce un nuovo array contenente gli elementi dell'argomento. Passiamo a
elenco:

lecca qui per visualizzare l'immagine del codice

In [2]: numbers = np.array ([ 2 , 3 , 5 , 7 , 11 ])

C
Pagina 261
La funzione array copia il contenuto del suo argomento nell'array. Diamo un'occhiata al file
tipo di oggetto restituito dall'array di funzioni e visualizzarne il contenuto:

lecca qui per visualizzare l'immagine del codice

In [3]: digitare (numeri)


Out [3]: numpy.ndarray

In [4]: ​numeri
Uscita [4]: ​array ([2, 3, 5, 7, 11])

Nota che il tipo è numpy.ndarray, ma tutti gli array vengono visualizzati come "array". quando
emettendo un array, NumPy separa ogni valore dal successivo con una virgola e a
spazio e rightaligns tutti i valori usando la stessa larghezza del campo. Determina il campo
larghezza in base al valore che occupa il maggior numero di posizioni dei caratteri. Nel
in questo caso, il valore 11 occupa le due posizioni dei caratteri, quindi tutti i valori lo sono

formattato in campi a due caratteri. Ecco perché c'è uno spazio iniziale tra [e

2.

Argomenti multidimensionali
La funzione array copia le dimensioni del suo argomento. Creiamo un array da un file
elenco due volte per tre colonne:

lecca qui per visualizzare l'immagine del codice

In [5]: np.array ([[ 1 , 2 , 3 ], [ 4 , 5 , 6 ]])


Fuori [5]:
matrice ([[1, 2, 3],
[4, 5, 6]])

NumPy autoformatta gli array, in base al loro numero di dimensioni, allineando il file

colonne all'interno di ogni riga.

7.3 ARRAY ATTRIBUTI


Un oggetto array fornisce attributi che consentono di scoprire informazioni su di esso
struttura e contenuti. In questa sezione useremo i seguenti array:

lecca qui per visualizzare l'immagine del codice

C
Pagina 262
In [1]: importa numpy come np

In [2]: numeri interi = np.array ([[ 1 , 2 , 3 ], [ 4 , 5 , 6 ]])

In [3]: numeri interi


Fuori [3]:
matrice ([[1, 2, 3],
[4, 5, 6]])

In [4]: ​floats = np.array ([ 0.0 , 0.1 , 0.2 , 0.3 , 0.4 ])

In [5]: floats
Uscita [5]: array ([0., 0.1, 0.2, 0.3, 0.4])

NumPy non visualizza gli 0 finali a destra del separatore decimale in virgola mobile
valori.

Determinazione del tipo di elemento di un array

La funzione array determina il tipo di elemento di un array dagli elementi del suo argomento.
Puoi controllare il tipo di elemento con l' attributo dtype di un array :

lecca qui per visualizzare l'immagine del codice

In [6]: integers.dtype
Uscita [6]: dtype ('int64') # int32 su alcune piattaforme

In [7]: floats.dtype
Uscita [7]: dtype ('float64')

Come vedrai nella prossima sezione, varie funzioni di creazione di array ricevono un dtype
argomento della parola chiave in modo da poter specificare il tipo di elemento di un array.

Per motivi di prestazioni, NumPy è scritto nel linguaggio di programmazione C e utilizza


Tipi di dati di C. Per impostazione predefinita, NumPy memorizza interi come valori int64 di tipo NumPy—

che corrispondono a interi a 64 bit (8 byte) in C e memorizzano i numeri in virgola mobile


come valori float64 di tipo NumPy, che corrispondono a 64 bit (8 byte) mobili

valori in punti in C.Nei nostri esempi, più comunemente vedrai i tipi int64,
float64, bool (per Boolean) e object per dati non numerici (come le stringhe). Il
l'elenco completo dei tipi supportati è a

ttps: //docs.scipy.org/doc/numpy/user/basics.types.html .

Determinazione delle dimensioni di un array

hC
Pagina 263
L'attributo ndim contiene il numero di dimensioni e l'attributo di un array

shape contiene una tupla che specifica le dimensioni di un array:

lecca qui per visualizzare l'immagine del codice

In [8]: integers.ndim
Fuori [8]: 2

In [9]: floats.ndim
Fuori [9]: 1

In [10]: integers.shape
Uscita [10]: (2, 3)

In [11]: floats.shape
Uscita [11]: (5,)

Qui, gli interi hanno 2 righe e 3 colonne (6 elementi) e float è uno


dimensionale, quindi lo snippet [11] mostra una tupla di un elemento (indicata dalla virgola)

contenente il numero di elementi float (5).

Determinazione del numero di elementi e della dimensione degli elementi di un array

È possibile visualizzare il numero totale di elementi di un array con la dimensione dell'attributo e l' estensione
numero di byte richiesti per memorizzare ogni elemento con itemize :

lecca qui per visualizzare l'immagine del codice

In [12]: integers.size
Fuori [12]: 6

In [13]: integers.itemsize # 4 se il compilatore C usa int a 32 bit


Uscita [13]: 8

In [14]: floats.size
Fuori [14]: 5

In [15]: floats.itemsize
Fuori [15]: 8

Si noti che la dimensione dei numeri interi è il prodotto dei valori della tupla della forma, due righe di

tre elementi ciascuno per un totale di sei elementi. In ogni caso, la dimensione dell'articolo è 8 perché

interi contiene valori int64 e float contiene valori float64, ciascuno dei quali
occupano 8 byte.

io
C terating Attraverso gli elementi di un array multidimensionale

Iterazione attraverso gli elementi di un array multidimensionale Pagina 264

Generalmente manipolerai gli array usando una programmazione concisa in stile funzionale
tecniche. Tuttavia, poiché gli array sono iterabili , è possibile utilizzare l'iterazione esterna se

ti piacerebbe:
lecca qui per visualizzare l'immagine del codice

In [16]: per riga in numeri interi:


...: per colonna nella riga:
...: print (colonna, fine = '' )
...: Stampa()
...:
123
456

È possibile iterare attraverso un array multidimensionale come se fosse monodimensionale da


usando il suo attributo flat :

lecca qui per visualizzare l'immagine del codice

In [17]: for i in integers.flat:


...: print (i, end = '' )
...:
123456

7.4 RIEMPIMENTO DI ARRAY CON VALORI SPECIFICI


NumPy fornisce funzioni zeri , uno e full per la creazione di array contenenti 0,

1s o un valore specificato, rispettivamente. Per impostazione predefinita, zero e uno creano array
contenente valori float64. Mostreremo come personalizzare il tipo di elemento

momentaneamente. Il primo argomento di queste funzioni deve essere un numero intero o una tupla di
numeri interi che specificano le dimensioni desiderate. Per un numero intero, ogni funzione restituisce uno
matrice dimensionale con il numero di elementi specificato:

lecca qui per visualizzare l'immagine del codice

In [1]: importa numpy come np

In [2]: np.zeros ( 5 )
Uscita [2]: array ([0., 0., 0., 0., 0.])

C
Pagina 265
Per una tupla di numeri interi, queste funzioni restituiscono un array multidimensionale con l'estensione
dimensioni specificate. È possibile specificare il tipo di elemento dell'array con gli zeri e

argomento della parola chiave dtype della funzione one:

lecca qui per visualizzare l'immagine del codice

In [3]: np.ones (( 2 , 4 ), dtype = int)


Fuori [3]:
matrice ([[1, 1, 1, 1],
[1, 1, 1, 1]])

L'array restituito da full contiene elementi con il valore del secondo argomento e

genere:

lecca qui per visualizzare l'immagine del codice

In [4]: ​np.full (( 3 , 5 ), 13 )
Fuori [4]:
matrice ([[13, 13, 13, 13, 13],
[13, 13, 13, 13, 13],
[13, 13, 13, 13, 13]])
7.5 CREAZIONE DI ARRAY DA GAMME
NumPy fornisce funzioni ottimizzate per la creazione di array da intervalli. Ci concentriamo su
semplici intervalli interi e in virgola mobile equidistanti, ma NumPy supporta anche
1
intervalli non lineari.

1
ttps: //docs.scipy.org/doc/numpy/reference/routines.array
reation.html .

Creazione di intervalli interi con arange

Usiamo la funzione arange di NumPy per creare intervalli interi, in modo simile all'utilizzo di builtin
gamma di funzioni. In ogni caso, arange determina prima il numero dell'array risultante

di elementi, alloca la memoria, quindi memorizza l'intervallo di valori specificato nel file

Vettore:

lecca qui per visualizzare l'immagine del codice

In [1]: importa numpy come np

cC
h
In [2]: np.arange ( 5 ) Pagina 266
Uscita [2]: array ([0, 1, 2, 3, 4])

In [3]: np.arange ( 5 , 10 )
Uscita [3]: array ([5, 6, 7, 8, 9])

In [4]: ​np.arange ( 10 , 1 , 2 )
Uscita [4]: ​array ([10, 8, 6, 4, 2])

Sebbene sia possibile creare array passando intervalli come argomenti, utilizzare sempre arange

poiché è ottimizzato per gli array. Presto mostreremo come determinare il tempo di esecuzione di
varie operazioni in modo da poter confrontare le loro prestazioni.

Creazione di intervalli in virgola mobile con linspace

Puoi produrre intervalli di virgola mobile equidistanti con linspace di NumPy

funzione. I primi due argomenti della funzione specificano i valori iniziale e finale in
l'intervallo e il valore finale è incluso nella matrice. La parola chiave facoltativa

l'argomento num specifica il numero di valori equidistanti da produrre: questo


il valore predefinito dell'argomento è 50:

lecca qui per visualizzare l'immagine del codice

In [5]: np.linspace ( 0.0 , 1.0 , num = 5 )


Uscita [5]: array ([0., 0.25, 0.5, 0.75, 1.])

Rimodellare un array

Puoi anche creare un array da un intervallo di elementi, quindi utilizzare il metodo array

rimodellare per trasformare la matrice unidimensionale in una matrice multidimensionale. Andiamo


creare un array contenente i valori da 1 a 20, quindi rimodellarlo in quattro
righe per cinque colonne:

lecca qui per visualizzare l'immagine del codice

In [6]: np.arange ( 1 , 21 ) .reshape ( 4 , 5 )


Fuori [6]:
matrice ([[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20]])

Notare le chiamate al metodo concatenate nello snippet precedente. Innanzitutto, arange produce un file

C
Pagina 267
matrice contenente i valori 1–20. Quindi chiamiamo reshape su quell'array per ottenere il 4
by5 array visualizzato.

Puoi rimodellare qualsiasi matrice, a condizione che la nuova forma abbia lo stesso numero di file
elementi come l'originale. Quindi un array monodimensionale a sei elementi può diventare un 3by2

o 2by3 array e viceversa, ma tentando di rimodellare un array di 15 elementi in un file


4by4 array (16 elementi) provoca un ValueError.

Visualizzazione di array di grandi dimensioni

Quando si visualizza un array, se ci sono 1000 o più elementi, NumPy lascia il centro

righe, colonne o entrambe dall'output. I seguenti frammenti generano 100.000


elementi. Il primo caso mostra tutte e quattro le righe ma solo la prima e le ultime tre dei file
25.000 colonne. La notazione ... rappresenta i dati mancanti. Il secondo caso mostra
la prima e l'ultima tre delle 100 righe e le prime e le ultime tre delle 1000 colonne:

lecca qui per visualizzare l'immagine del codice

In [7]: np.arange ( 1 , 100001 ) .reshape ( 4 , 25000 )


Fuori [7]:
matrice ([[1, 2, 3, ..., 24998, 24999, 25000],
[25001, 25002, 25003, ..., 49998, 49999, 50000],
[50001, 50002, 50003, ..., 74998, 74999, 75000],
[75001, 75002, 75003, ..., 99998, 99999, 100000]])

In [8]: np.arange ( 1 , 100001 ) .reshape ( 100 , 1000 )


Fuori [8]:
matrice ([[1, 2, 3, ..., 998, 999, 1000],
[1001, 1002, 1003, ..., 1998, 1999, 2000],
[2001, 2002, 2003, ..., 2998, 2999, 3000],
...,
[97001, 97002, 97003, ..., 97998, 97999, 98000],
[98001, 98002, 98003, ..., 98998, 98999, 99000],
[99001, 99002, 99003, ..., 99998, 99999, 100000]])

7.6 ELENCO VS. PRESTAZIONI DI ARRAY: INTRODUZIONE


% TIMEIT
La maggior parte delle operazioni sugli array viene eseguita molto più velocemente delle operazioni sugli elenchi corrispondenti.
Per dimostrare, useremo il comando magico IPython % timeit , che moltiplicherà il
durata media delle operazioni. Tieni presente che i tempi visualizzati sul tuo sistema possono variare
da quello che mostriamo qui.

T
C iming la creazione di una lista contenente i risultati di 6.000.000 di dadi

Cronometrare la creazione di un elenco contenente i risultati di 6.000.000 di dadi Pagina 268

Abbiamo dimostrato di lanciare un dado a sei facce 6.000.000 di volte. Qui, usiamo il random

la funzione randrange del modulo con una lista di comprensione per creare una lista di sei milioni

il dado rotola e calcola l'operazione utilizzando% timeit. Nota che abbiamo usato la linea
carattere di continuazione (\) per dividere l'istruzione nello snippet [2] su due righe:
lecca qui per visualizzare l'immagine del codice

In [1]: importa casuale

In [2]:% timeit rolls_list = \


...: [random.randrange ( 1 , 7 ) for i in range ( 0 , 6_000_000 )]
6,29 s ± 119 ms per loop (media ± dev. Std. Di 7 analisi, 1 loop ciascuna)

Per impostazione predefinita,% timeit esegue un'istruzione in un ciclo e lo esegue sette volte. Se
non indichi il numero di loop,% timeit sceglie un valore appropriato. Nel nostro

test, operazioni che in media hanno richiesto più di 500 millisecondi ripetute solo una volta,
e le operazioni che hanno richiesto meno di 500 millisecondi sono state ripetute 10 volte o più.

Dopo aver eseguito l'istruzione,% timeit mostra l' esecuzione media dell'istruzione

tempo, così come la deviazione standard di tutte le esecuzioni. In media,% timeit


indica che sono stati necessari 6,29 secondi per creare l'elenco con una deviazione standard di 119
millisecondi (ms). In totale, lo snippet precedente ha impiegato circa 44 secondi per eseguire il file

snippet sette volte.

Cronometrare la creazione di una matrice contenente i risultati di 6.000.000 di die


rotoli

Ora, usiamo la funzione randint dal modulo numpy.random per creare un file

serie di 6.000.000 di dado

lecca qui per visualizzare l'immagine del codice

In [3]: importa numpy come np

In [4]:% timeit rolls_array = np.random.randint ( 1 , 7 , 6_000_000 )


72,4 ms ± 635 µs per loop (media ± dev. Std. Di 7 analisi, 10 loop ciascuna)

In media,% timeit indica che ci sono voluti solo 72,4 millisecondi con uno standard
deviazione di 635 microsecondi (µs) per creare l'array. In totale, lo snippet precedente

ha impiegato poco meno di mezzo secondo per essere eseguito sul nostro computer, circa 1/100 del tempo

C
Pagina 269
snippet [2] richiesto per l'esecuzione. L'operazione è due ordini di grandezza più veloce con

Vettore!

60.000.000 e 600.000.000 di dadi

Ora creiamo un array di 60.000.000 di tiri di dado:

lecca qui per visualizzare l'immagine del codice

In [5]:% timeit rolls_array = np.random.randint ( 1 , 7 , 60_000_000 )


873 ms ± 29,4 ms per loop (media ± dev. Std. Di 7 analisi, 1 loop ciascuna)

In media, sono stati necessari solo 873 millisecondi per creare l'array.

Infine, facciamo 600.000.000 milioni di tiri di dado:

lecca qui per visualizzare l'immagine del codice

In [6]:% timeit rolls_array = np.random.randint ( 1 , 7 , 600_000_000 )


10,1 s ± 232 ms per loop (media ± dev. Std. Di 7 analisi, 1 loop ciascuna)
Ci sono voluti circa 10 secondi per creare 600.000.000 di elementi con NumPy contro circa 6
secondi per creare solo 6.000.000 di elementi con una comprensione della lista.

Sulla base di questi studi sui tempi, è possibile vedere chiaramente perché gli array sono preferiti agli elenchi

per operazioni ad alta intensità di calcolo. Negli studi di casi di data science, inseriremo il file
mondi ad alta intensità di big data e AI. Vedremo come l'hardware intelligente,
software, comunicazioni e progetti di algoritmi si combinano per soddisfare le esigenze spesso enormi
sfide informatiche delle applicazioni odierne.

Personalizzazione delle iterazioni% timeit

Il numero di iterazioni all'interno di ogni ciclo% timeit e il numero di cicli sono

personalizzabile con le opzioni n e r. Quanto segue esegue lo snippet [4]


2
istruzione tre volte per ciclo ed esegue il ciclo due volte:

2
Per la maggior parte dei lettori, l'uso delle impostazioni predefinite di% timeit dovrebbe andare bene.

lecca qui per visualizzare l'immagine del codice

In [7]:% timeit n 3 r 2 rolls_array = np.random.randint ( 1 , 7 , 6_000_000 )


85,5 ms ± 5,32 ms per loop (media ± dev. Std. Di 2 analisi, 3 loop ciascuna)

C
Pagina 270

Altri IPython Magics

IPython fornisce dozzine di magie per una varietà di attività: per un elenco completo, vedere il
3
Documentazione di IPython magics. Eccone alcuni utili:

ttp: //ipython.readthedocs.io/en/stable/interactive/magics.html .

% di carico per leggere il codice in IPython da un file locale o da un URL.

% salva per salvare i frammenti in un file.

% run per eseguire un file .py da IPython.

% di precisione per modificare la precisione in virgola mobile predefinita per gli output IPython.

% cd per cambiare directory senza dover prima uscire da IPython.

% edit per avviare un editor esterno, utile se è necessario apportare modifiche più complesse
frammenti.

% history per visualizzare un elenco di tutti gli snippet e i comandi che hai eseguito nel file
sessione IPython corrente.

7.7 OPERATORI ARRAY


NumPy fornisce molti operatori che ti consentono di scrivere semplici espressioni che
eseguire operazioni su interi array. Qui, dimostriamo l'aritmetica tra

matrici e valori numerici e tra matrici della stessa forma.

Operazioni aritmetiche con array e valori numerici individuali

Per prima cosa, eseguiamo operazioni aritmetiche per elementi con array e valori numerici utilizzando
operatori aritmetici e assegnazioni aumentate. Vengono applicate le operazioni elementwise
a ogni elemento, quindi lo snippet [4] moltiplica ogni elemento per 2 e lo snippet [5] cubi
ogni elemento. Ciascuno restituisce un nuovo array contenente il risultato:

lecca qui per visualizzare l'immagine del codice

In [1]: importa numpy come np

hC
Pagina 271
In [2]: numbers = np.arange ( 1 , 6 )

In [3]: numeri
Uscita [3]: array ([1, 2, 3, 4, 5])

In [4]: ​numeri * 2
Uscita [4]: ​array ([2, 4, 6, 8, 10])

In [5]: numeri ** 3
Uscita [5]: array ([1, 8, 27, 64, 125])

In [6]: numbers # numbers è invariato dagli operatori aritmetici


Uscita [6]: array ([1, 2, 3, 4, 5])

Il frammento [6] mostra che gli operatori aritmetici non hanno modificato i numeri. Operatori +
e * sono commutativi , quindi lo snippet [4] potrebbe anche essere scritto come 2 * numeri.

Le assegnazioni aumentate modificano ogni elemento nell'operando sinistro.

lecca qui per visualizzare l'immagine del codice

In [7]: numeri + = 10

In [8]: numeri
Uscita [8]: array ([11, 12, 13, 14, 15])

Trasmissione

Normalmente, le operazioni aritmetiche richiedono come operandi due array della stessa dimensione
e forma . Quando un operando è un valore singolo, chiamato scalare , NumPy esegue il
calcoli elementwise come se lo scalare fosse un array della stessa forma dell'altro
operando, ma con il valore scalare in tutti i suoi elementi. Questo si chiama trasmissione .
Gli snippet [4], [5] e [7] utilizzano ciascuno questa funzionalità. Ad esempio, lo snippet [4] è
equivalente a:

lecca qui per visualizzare l'immagine del codice

numeri * [ 2 , 2 , 2 , 2 , 2 ]

La trasmissione può anche essere applicata tra array di diverse dimensioni e forme,

consentendo alcune manipolazioni concise e potenti. Mostreremo più esempi di


trasmissione più avanti nel capitolo, quando introdurremo le funzioni universali di NumPy.

UN
C Operazioni ritmetiche tra array

Operazioni aritmetiche tra array Pagina 272

È possibile eseguire operazioni aritmetiche e assegnazioni aumentate tra array


della stessa forma. Moltiplichiamo i numeri degli array unidimensionali e

numbers2 (creato di seguito) che contengono ciascuno cinque elementi:


lecca qui per visualizzare l'immagine del codice

In [9]: numbers2 = np.linspace ( 1.1 , 5.5 , 5 )

In [10]: numbers2
Uscita [10]: array ([1.1, 2.2, 3.3, 4.4, 5.5])

In [11]: numeri * numeri2


Uscita [11]: array ([12.1, 26.4, 42.9, 61.6, 82.5])

Il risultato è un nuovo array formato moltiplicando gli array per elemento in ciascuno
operando: 11 * 1.1, 12 * 2.2, 13 * 3.3, ecc. Aritmetica tra array di numeri interi

e i numeri in virgola mobile danno come risultato una matrice di numeri in virgola mobile.

Confronto di array

È possibile confrontare array con valori individuali e con altri array. Confronti
vengono eseguite elementwise . Tali confronti producono matrici di valori booleani in

il cui valore True o False di ogni elemento indica il risultato del confronto:

lecca qui per visualizzare l'immagine del codice

In [12]: numeri
Uscita [12]: array ([11, 12, 13, 14, 15])

In [13]: numeri> = 13
Out [13]: array ([False, False, True, True, True])

In [14]: numbers2
Uscita [14]: array ([1.1, 2.2, 3.3, 4.4, 5.5])

In [15]: numbers2 <numbers


Out [15]: array ([True, True, True, True, True])

In [16]: numeri == numeri2


Out [16]: array ([False, False, False, False, False])

In [17]: numeri == numeri


Out [17]: array ([True, True, True, True, True])

C
Pagina 273
Snippet [13] utilizza la trasmissione per determinare se ogni elemento di numeri è
maggiore o uguale a 13. Gli snippet rimanenti confrontano i corrispondenti
elementi di ogni operando array.

7.8 METODI DI CALCOLO DEL NUMERO


Un array dispone di vari metodi che eseguono calcoli utilizzando il suo contenuto. Per impostazione predefinita,
questi metodi ignorano la forma dell'array e utilizzano tutti gli elementi nei calcoli.

Ad esempio, il calcolo della media di un array totalizza tutti i suoi elementi indipendentemente dal suo
forma, quindi divide per il numero totale di elementi. Puoi eseguirli
calcoli anche su ogni dimensione. Ad esempio, in un array bidimensionale, tu
può calcolare la media di ogni riga e la media di ogni colonna.

Considera una matrice che rappresenta i voti di quattro studenti su tre esami:

lecca qui per visualizzare l'immagine del codice

In [1]: importa numpy come np

In [2]: grades = np.array ([[ 87 , 96 , 70 ], [ 100 , 87 , 90 ],


...: [ 94 , 77 , 90 ], [ 100 , 81 , 82 ]])
...:

In [3]: voti
Fuori [3]:
matrice ([[87, 96, 70],
[100, 87, 90],
[94, 77, 90],
[100, 81, 82]])

Possiamo usare metodi per calcolare somma , min , max , media , std (deviazione standard) e

var (varianza): ciascuna è una riduzione della programmazione in stile funzionale :

lecca qui per visualizzare l'immagine del codice

In [4]: ​grades.sum ()
Uscita [4]: ​1054

In [5]: grades.min ()
Uscita [5]: 70

In [6]: grades.max ()
Uscita [6]: 100

In [7]: grades.mean ()

Uscita [7]: 87.83333333333333 Pagina 274

In [8]: grades.std ()
Uscita [8]: 8.792357792739987

In [9]: grades.var ()
Uscita [9]: 77.30555555555556

Calcoli per riga o colonna

Molti metodi di calcolo possono essere eseguiti su dimensioni di array specifiche, note come
gli assi dell'array . Questi metodi ricevono un argomento della parola chiave dell'asse che specifica
quale dimensione utilizzare nel calcolo, offrendo un modo rapido per eseguire
calcoli per riga o colonna in un array bidimensionale.

Supponi di voler calcolare il voto medio di ogni esame , rappresentato dal


colonne di voti. Specificando axis = 0 si esegue il calcolo su tutti i valori di riga

all'interno di ogni colonna:

lecca qui per visualizzare l'immagine del codice

In [10]: grades.mean (axis = 0 )


Out [10]: array ([95.25, 85.25, 83.])

Quindi 95.25 sopra è la media dei voti della prima colonna (87, 100, 94 e 100),

85.25 è la media dei voti della seconda colonna (96, 87, 77 e 81) e 83 è il
media dei voti della terza colonna (70, 90, 90 e 82). Ancora una volta, NumPy non lo fa

visualizzare gli 0 finali a destra del punto decimale in "83.". Nota anche che lo fa

visualizzare tutti i valori degli elementi nella stessa larghezza del campo, motivo per cui "83". è seguito da
due spazi.

Allo stesso modo, specificando axis = 1 si esegue il calcolo su tutti i valori di colonna all'interno

ogni singola riga. Possiamo calcolare il voto medio di ogni studente per tutti gli esami
uso:
lecca qui per visualizzare l'immagine del codice

In [11]: grades.mean (axis = 1 )


Uscita [11]: array ([84.33333333, 92.33333333, 87., 87.66666667])

Questo produce quattro medie, una per ciascuno dei valori in ogni riga. Quindi 84.33333333 è

C
Pagina 275
la media dei voti della riga 0 (87, 96 e 70) e le altre medie sono per il
righe rimanenti.

Gli array NumPy hanno molti più metodi di calcolo. Per l'elenco completo, vedere

ttps: //docs.scipy.org/doc/numpy/reference/arrays.ndarray.html

7.9 FUNZIONI UNIVERSALI


NumPy offre dozzine di funzioni universali autonome (o ufunc ) che eseguono
varie operazioni elementwise. Ciascuno svolge il proprio compito utilizzando uno o due array o

argomenti simili ad array (come elenchi). Alcune di queste funzioni vengono chiamate quando usi
operatori come + e * sugli array. Ciascuno restituisce un nuovo array contenente i risultati.

Creiamo un array e calcoliamo la radice quadrata dei suoi valori, usando sqrt

funzione universale :

lecca qui per visualizzare l'immagine del codice

In [1]: importa numpy come np

In [2]: numbers = np.array ([ 1 , 4 , 9 , 16 , 25 , 36 ])

In [3]: np.sqrt (numeri)


Uscita [3]: array ([1., 2., 3., 4., 5., 6.])

Aggiungiamo due array con la stessa forma, utilizzando la funzione aggiungi universale:

lecca qui per visualizzare l'immagine del codice

In [4]: ​numbers2 = np.arange ( 1 , 7 ) * 10

In [5]: numbers2
Uscita [5]: array ([10, 20, 30, 40, 50, 60])

In [6]: np.add (numbers, numbers2)


Uscita [6]: array ([11, 24, 39, 56, 75, 96])

L'espressione np.add (numbers, numbers2) è equivalente a:

numeri + numeri 2

B
C roadcasting con funzioni universali
h

Trasmissione con funzioni universali Pagina 276

Usiamo la funzione moltiplica universale per moltiplicare ogni elemento di numeri2

dal valore scalare 5:

lecca qui per visualizzare l'immagine del codice


In [7]: np.multiply (numbers2, 5 )
Uscita [7]: matrice ([50, 100, 150, 200, 250, 300])

L'espressione np.multiply (numbers2, 5) è equivalente a:

numeri2 * 5

Rimodelliamo numbers2 in un array 2by3, quindi moltiplichiamo i suoi valori per uno
matrice dimensionale di tre elementi:

lecca qui per visualizzare l'immagine del codice

In [8]: numbers3 = numbers2.reshape ( 2 , 3 )

In [9]: numbers3
Fuori [9]:
matrice ([[10, 20, 30],
[40, 50, 60]])

In [10]: numbers4 = np.array ([ 2 , 4 , 6 ])

In [11]: np.multiply (numbers3, numbers4)


Fuori [11]:
matrice ([[20, 80, 180],
[80, 200, 360]])

Questo funziona perché numbers4 ha la stessa lunghezza di ogni riga di numbers3, quindi
NumPy può applicare l'operazione di moltiplicazione trattando numbers4 come se fosse il file

seguente matrice:

matrice ([[2, 4, 6],


[2, 4, 6]])

Se una funzione universale riceve due array di forme diverse che non supportano
broadcasting, si verifica un ValueError. Puoi visualizzare le regole di trasmissione su:

C
Pagina 277
ttps: //docs.scipy.org/doc/numpy/user/basics.broadcasting.html

Altre funzioni universali


La documentazione di NumPy elenca le funzioni universali in cinque categorie: matematica,
trigonometria, manipolazione dei bit, confronto e virgola mobile. La tabella seguente elenca
alcune funzioni di ciascuna categoria. Puoi visualizzare l'elenco completo, le loro descrizioni
e ulteriori informazioni sulle funzioni universali su:

ttps: //docs.scipy.org/doc/numpy/reference/ufuncs.html

NumPy funzioni universali

Matematica: aggiungi, sottrai, moltiplica, dividi, resto, exp, log, sqrt,

potenza e altro ancora.

Trigonometria: sin, cos, tan, hypot, arcsin, arccos, arctan e


Di Più.

Manipolazione di bit: bitwise_and, bitwise_or, bitwise_xor, invert,

shift_sinistra e shift_destra.

Confronto: maggiore, maggiore_uguale, minore, minore_uguale, uguale,

non_uguale, logico_e, logico_or, logico_xor, logico_not,

minimo, massimo e altro.

Virgola mobile: pavimento, soffitto, isinf, isnan, fabs, trunc e altro ancora.

7.10 INDICATRICE E AFFETTARE


Gli array monodimensionali possono essere indicizzati e suddivisi in sezioni utilizzando la stessa sintassi e
tecniche che abbiamo dimostrato nel capitolo "Sequenze: elenchi e tuple". Qui noi
concentrarsi sulle capacità di indicizzazione e sezionamento specifiche degli array.

Indicizzazione con array bidimensionali

Pagina 278
Per selezionare un elemento in un array bidimensionale, specificare una tupla contenente il
indici di riga e colonna dell'elemento tra parentesi quadre (come nello snippet [4]):

lecca qui per visualizzare l'immagine del codice

In [1]: importa numpy come np

In [2]: grades = np.array ([[ 87 , 96 , 70 ], [ 100 , 87 , 90 ],


...: [ 94 , 77 , 90 ], [ 100 , 81 , 82 ]])
...:

In [3]: voti
Fuori [3]:
matrice ([[87, 96, 70],
[100, 87, 90],
[94, 77, 90],
[100, 81, 82]])

In [4]: ​voti [ 0 , 1 ] # riga 0, colonna 1


Uscita [4]: ​96

Selezione di un sottoinsieme di righe di un array bidimensionale

Per selezionare una singola riga, specificare solo un indice tra parentesi quadre:

lecca qui per visualizzare l'immagine del codice

In [5]: voti [ 1 ]
Uscita [5]: array ([100, 87, 90])

Per selezionare più righe sequenziali, utilizzare la notazione delle sezioni:

lecca qui per visualizzare l'immagine del codice

In [6]: voti [ 0 : 2 ]
Fuori [6]:
matrice ([[87, 96, 70],
[100, 87, 90]])

Per selezionare più righe non sequenziali, utilizzare un elenco di indici di riga:

In [7]: voti [[ 1 , 3 ]]
Fuori [7]:
matrice ([[100, 87, 90],
[100, 81, 82]])

C
Pagina 279

Selezione di un sottoinsieme di colonne di una matrice bidimensionale

È possibile selezionare sottoinsiemi delle colonne fornendo una tupla che specifica le righe e
colonna (e) da selezionare. Ciascuno può essere un indice specifico, una sezione o un elenco. Selezioniamo solo il file
elementi nella prima colonna:

lecca qui per visualizzare l'immagine del codice

In [8]: voti [:, 0 ]


Uscita [8]: array ([87, 100, 94, 100])

Lo 0 dopo la virgola indica che stiamo selezionando solo la colonna 0. Il: prima di
la virgola indica quali righe all'interno di quella colonna selezionare. In questo caso ,: è una fetta
che rappresenta tutte le righe. Potrebbe anche essere un numero di riga specifico, una sezione che rappresenta un file
sottoinsieme delle righe o un elenco di indici di riga specifici da selezionare, come negli snippet [5] - [7].

È possibile selezionare colonne consecutive utilizzando una sezione:

In [9]: voti [:, 1 : 3 ]


Fuori [9]:
matrice ([[96, 70],
[87, 90],
[77, 90],
[81, 82]])

o colonne specifiche utilizzando un elenco di indici di colonna:

In [10]: voti [:, [ 0 , 2 ]]


Fuori [10]:
matrice ([[87, 70],
[100, 90],
[94, 90],
[100, 82]])

7.11 VISUALIZZAZIONI: COPIE RIDOTTE


Il capitolo precedente ha introdotto gli oggetti di visualizzazione , ovvero gli oggetti che "vedono" i dati
altri oggetti, piuttosto che avere le proprie copie dei dati. Le viste sono copie superficiali.
Vari metodi di matrice e operazioni di suddivisione in sezioni producono visualizzazioni dei dati di un array.

La visualizzazione del metodo array restituisce un nuovo oggetto array con una visualizzazione dell'array originale

C
Pagina 280
dati dell'oggetto. Per prima cosa, creiamo un array e una vista di quell'array:

lecca qui per visualizzare l'immagine del codice

In [1]: importa numpy come np


In [2]: numbers = np.arange ( 1 , 6 )

In [3]: numeri
Uscita [3]: array ([1, 2, 3, 4, 5])

In [4]: ​numbers2 = numbers.view ()

In [5]: numbers2
Uscita [5]: array ([1, 2, 3, 4, 5])

Possiamo usare la funzione id incorporata per vedere che numeri e numeri2 sono diversi

oggetti:

In [6]: id (numeri)
Uscita [6]: 4462958592

In [7]: id (numbers2)
Uscita [7]: 4590846240

Per dimostrare che numbers2 visualizza gli stessi dati dei numeri, modifichiamo un elemento in

numeri, quindi visualizzare entrambi gli array:

lecca qui per visualizzare l'immagine del codice

In [8]: numeri [ 1 ] * = 10

In [9]: numbers2
Uscita [9]: array ([1, 20, 3, 4, 5])

In [10]: numeri
Uscita [10]: array ([1, 20, 3, 4, 5])

Allo stesso modo, la modifica di un valore nella vista cambia anche quel valore nell'array originale:

In [11]: numbers2 [ 1 ] / = 10

In [12]: numeri
Uscita [12]: array ([1, 2, 3, 4, 5])

In [13]: numbers2 Pagina 281


Uscita [13]: array ([1, 2, 3, 4, 5])

Vista in sezioni

Le sezioni creano anche viste. Facciamo di numbers2 una sezione che visualizzi solo i primi tre

elementi di numeri:

In [14]: numbers2 = numbers [ 0 : 3 ]


In [15]: numbers2
Uscita [15]: array ([1, 2, 3])

Di nuovo, possiamo confermare che i numeri e i numeri2 sono oggetti diversi con id:

In [16]: id (numeri)
Uscita [16]: 4462958592

In [17]: id (numbers2)
Uscita [17]: 4590848000
Possiamo confermare che numbers2 è una visualizzazione solo dei primi tre elementi di numeri
tentativo di accedere a numbers2 [3], che produce un IndexError:

lecca qui per visualizzare l'immagine del codice

In [18]: numbers2 [ 3 ]

IndexError Traceback (la chiamata più recente last


ipythoninput18582053f52daa> in <module> ()
> 1 numeri2 [ 3 ]

IndexError : l'indice 3 è fuori dai limiti per l'asse 0 con dimensione 3

Ora, modifichiamo un elemento condiviso da entrambi gli array, quindi visualizziamoli. Di nuovo, lo vediamo

numbers2 è una visualizzazione dei numeri:

lecca qui per visualizzare l'immagine del codice

In [19]: numeri [ 1 ] * = 20

In [20]: numeri
Uscita [20]: array ([1, 2, 3, 4, 5])

C
<

In [21]: numbers2 Pagina 282


Uscita [21]: array ([1, 40, 3])

7.12 COPIE PROFONDE


Sebbene le viste siano oggetti array separati , risparmiano memoria condividendo i dati degli elementi

da altri array. Tuttavia, quando si condividono valori mutabili , a volte è necessario


per creare una copia completa con copie indipendenti dei dati originali. Questo è specialmente
importante nella programmazione multicore, dove potrebbero essere parti separate del programma
tentare di modificare i propri dati allo stesso tempo, eventualmente corrompendoli.

La copia del metodo array restituisce un nuovo oggetto array con una copia completa dell'originale

dati dell'oggetto array. Per prima cosa, creiamo un array e una copia completa di quell'array:

lecca qui per visualizzare l'immagine del codice

In [1]: importa numpy come np

In [2]: numbers = np.arange ( 1 , 6 )

In [3]: numeri
Uscita [3]: array ([1, 2, 3, 4, 5])

In [4]: ​numbers2 = numbers.copy ()

In [5]: numbers2
Uscita [5]: array ([1, 2, 3, 4, 5])

Per dimostrare che numbers2 ha una copia separata dei dati in numbers, modifichiamo un file
elemento in numeri, quindi visualizza entrambi gli array:

lecca qui per visualizzare l'immagine del codice

In [6]: numeri [ 1 ] * = 10

In [7]: numeri
Uscita [7]: array ([1, 20, 3, 4, 5])

In [8]: numbers2
Uscita [8]: array ([1, 2, 3, 4, 5])

Come puoi vedere, il cambiamento appare solo in numeri.

M
C Copia odule: copie superficiali e profonde per altri tipi di Python

Copia del modulo: copie superficiali e profonde per altri tipi di Python Pagina 283

Oggetti

Nei capitoli precedenti abbiamo trattato la copia superficiale . In questo capitolo abbiamo spiegato come
per copiare in profondità gli oggetti dell'array utilizzando il loro metodo di copia. Se hai bisogno di copie profonde di altri file

tipi di oggetti Python, passali alla funzione di copia profonda del modulo di copia .

7.13 RIMODELLAMENTO E TRASPORTO


Abbiamo utilizzato il metodo array reshape per produrre array bidimensionali da uno
gamme dimensionali. NumPy fornisce vari altri modi per rimodellare gli array.

rimodellare e ridimensionare

I metodi degli array reshape e resize consentono entrambi di modificare un array


dimensioni. Il metodo reshape restituisce una vista (copia superficiale) dell'array originale con
le nuove dimensioni. Esso non modifica dell'array originale:

lecca qui per visualizzare l'immagine del codice

In [1]: importa numpy come np

In [2]: grades = np.array ([[ 87 , 96 , 70 ], [ 100 , 87 , 90 ]])

In [3]: voti
Fuori [3]:
matrice ([[87, 96, 70],
[100, 87, 90]])

In [4]: ​grades.reshape ( 1 , 6 )
Uscita [4]: ​array ([[87, 96, 70, 100, 87, 90]])

In [5]: voti
Fuori [5]:
matrice ([[87, 96, 70],
[100, 87, 90]])

Il metodo resize modifica la forma dell'array originale :

lecca qui per visualizzare l'immagine del codice

In [6]: grades.resize ( 1 , 6 )

In [7]: voti
Uscita [7]: array ([[87, 96, 70, 100, 87, 90]])

fC latten vs. ravel

Pagina 284
flatten vs. ravel
Puoi prendere un array multidimensionale e appiattirlo in una singola dimensione con l'estensione
metodi di appiattimento e sbavatura . Il metodo flatten copia in profondità i dati dell'array originale:
lecca qui per visualizzare l'immagine del codice

In [8]: grades = np.array ([[ 87 , 96 , 70 ], [ 100 , 87 , 90 ]])

In [9]: voti
Fuori [9]:
matrice ([[87, 96, 70],
[100, 87, 90]])

In [10]: flattened = grades.flatten ()

In [11]: appiattito
Uscita [11]: array ([87, 96, 70, 100, 87, 90])

In [12]: voti
Fuori [12]:
matrice ([[87, 96, 70],
[100, 87, 90]])

Per confermare che voti e appiattiti non condividono i dati, modifichiamo un elemento

di appiattito, quindi visualizza entrambi gli array:

lecca qui per visualizzare l'immagine del codice

In [13]: appiattito [ 0 ] = 100

In [14]: appiattito
Uscita [14]: array ([100, 96, 70, 100, 87, 90])

In [15]: voti
Fuori [15]:
matrice ([[87, 96, 70],
[100, 87, 90]])

Il metodo ravel produce una vista della matrice originale, che condivide i gradi

dati dell'array:

lecca qui per visualizzare l'immagine del codice

In [16]: raveled = grades.ravel ()

In [17]: sfilacciato Pagina 285


Uscita [17]: array ([87, 96, 70, 100, 87, 90])

In [18]: voti
Fuori [18]:
matrice ([[87, 96, 70],
[100, 87, 90]])

Per confermare che i voti e le denunce condividono gli stessi dati, modifichiamo un elemento di

sfilacciato, quindi visualizzare entrambi gli array:

lecca qui per visualizzare l'immagine del codice

In [19]: raveled [ 0 ] = 100

In [20]: sfilacciato
Uscita [20]: array ([100, 96, 70, 100, 87, 90])

In [21]: voti
Fuori [21]:
matrice ([[100, 96, 70],
[100, 87, 90]])
Trasposizione di righe e colonne

È possibile trasporre rapidamente le righe e le colonne di un array, ovvero "capovolgere" l'array, quindi
le righe diventano le colonne e le colonne diventano le righe. L' attributo T.

restituisce una vista trasposta (copia superficiale) dell'array. La matrice dei voti originale
rappresenta i voti di due studenti (le righe) su tre esami (le colonne). Facciamo
trasporre le righe e le colonne per visualizzare i dati come voti su tre esami (il
righe) per due studenti (le colonne):

In [22]: voti.T
Fuori [22]:
matrice ([[100, 100],
[96, 87],
[70, 90]])

La trasposizione non modifica l'array originale:

In [23]: voti
Fuori [23]:
matrice ([[100, 96, 70],
[100, 87, 90]])

H
C impilamento orizzontale e verticale

Impilamento orizzontale e verticale Pagina 286

È possibile combinare array aggiungendo più colonne o più righe, note come orizzontali
accatastamento e accatastamento verticale . Creiamo un altro array di voti 2 per 3:

lecca qui per visualizzare l'immagine del codice

In [24]: grades2 = np.array ([[ 94 , 77 , 90 ], [ 100 , 81 , 82 ]])

Supponiamo che i voti2 rappresentino tre voti aggiuntivi per i due studenti in
la matrice dei voti. Possiamo combinare gradi e grades2 con NumPy di hstack
(stack orizzontale) passando una tupla contenente gli array da combinare.
Le parentesi extra sono necessarie perché hstack si aspetta un argomento:

lecca qui per visualizzare l'immagine del codice

In [25]: np.hstack ((voti, voti2))


Fuori [25]:
matrice ([[100, 96, 70, 94, 77, 90],
[100, 87, 90, 100, 81, 82]])

Successivamente, supponiamo che i voti2 rappresentino altri due voti degli studenti su tre esami.
In questo caso, possiamo combinare voti e voti2 con vstack di NumPy (vertical

stack) funzione :

lecca qui per visualizzare l'immagine del codice

In [26]: np.vstack ((grades, grades2))


Fuori [26]:
matrice ([[100, 96, 70],
[100, 87, 90],
[94, 77, 90],
[100, 81, 82]])
7.14 INTRO A DATA SCIENCE: SERIE PANDAS E
DATAFRAMES
L'array di NumPy è ottimizzato per dati numerici omogenei a cui si accede tramite numero intero
indici. La scienza dei dati presenta richieste uniche per le quali dati più personalizzati
sono necessarie strutture. Le applicazioni per big data devono supportare tipi di dati misti,
indicizzazione personalizzata, dati mancanti, dati non strutturati in modo coerente e dati che

C
Pagina 287
deve essere manipolato in forme appropriate per i database e l'analisi dei dati
pacchetti che usi.

Pandas è la libreria più popolare per gestire tali dati. Fornisce due chiavi
raccolte che utilizzerai in molte delle nostre sezioni Introduzione alla scienza dei dati e
in tutti i casi di studio della scienza dei dati— Serie per raccolte unidimensionali e

DataFrame per raccolte bidimensionali. Puoi usare il MultiIndex dei panda per
manipolare dati multidimensionali nel contesto di Series e DataFrame.

Wes McKinney ha creato i panda nel 2008 mentre lavorava nell'industria. Il nome panda è
derivato dal termine "dati del pannello", ovvero i dati per le misurazioni nel tempo, ad esempio
prezzi delle azioni o letture storiche della temperatura. McKinney aveva bisogno di una libreria in cui il file
le stesse strutture di dati potrebbero gestire dati sia temporali che non basati sull'ora con il supporto
per l'allineamento dei dati, i dati mancanti, la manipolazione dei dati di stili di database comuni e
4
Di Più.

4
McKinney, Wes. Python per l'analisi dei dati: data wrangling con Panda, NumPy,
e IPython , pagg. 123 165. Sebastopol, CA: OReilly Media, 2018.

NumPy e i panda sono intimamente legati. Serie e DataFrames utilizzano array


"sotto il cappuccio." Serie e DataFrame sono argomenti validi per molti NumPy

operazioni. Allo stesso modo, gli array sono argomenti validi per molti Series e DataFrame
operazioni.

5
Pandas è un argomento enorme: il PDF della sua documentazione è di oltre 2000 pagine. In questo
e le sezioni Intro to Data Science dei prossimi capitoli, presentiamo un'introduzione a
panda. Discutiamo le sue raccolte Series e DataFrames e le usiamo a supporto

della preparazione dei dati. Vedrai che Series e DataFrames ti rendono facile
eseguire attività comuni come selezionare elementi in vari modi, filtrare / mappare / ridurre
operazioni (centrali per la programmazione in stile funzionale e big data), matematiche
operazioni, visualizzazione e altro ancora.

5
Per la documentazione più recente sui panda, vedere

ttp: //pandas.pydata.org/pandasdocs/stable/ .

7.14.1 Serie panda

Una serie è un array unidimensionale migliorato. Mentre gli array usano solo zero
Gli indici interi basati su serie supportano l'indicizzazione personalizzata, inclusi anche quelli non interi

indici come stringhe. Le serie offrono anche funzionalità aggiuntive che le rendono di più

nh
Pagina 288
conveniente per molte attività orientate alla datascience. Ad esempio, Series potrebbe avere
dati mancanti e molte operazioni della serie ignorano i dati mancanti per impostazione predefinita.

Creazione di una serie con indici predefiniti


Per impostazione predefinita, una serie ha indici interi numerati in sequenza da 0. Quanto segue
crea una serie di voti degli studenti da un elenco di numeri interi:

lecca qui per visualizzare l'immagine del codice

In [1]: importa i panda come pd

In [2]: grades = pd.Series ([87, 100, 94])

L'inizializzatore può anche essere una tupla, un dizionario, un array, un'altra serie o un singolo
valore. Mostreremo momentaneamente un singolo valore.

Visualizzazione di una serie

Pandas mostra una serie in formato a due colonne con gli indici allineati a sinistra a sinistra

colonna ei valori allineati a destra nella colonna di destra. Dopo aver elencato la serie
elements, pandas mostra il tipo di dati (dtype) degli elementi dell'array sottostante:

In [3]: voti
Fuori [3]:
0 87
1 100
2 94
dtype: int64

Nota quanto è facile visualizzare una serie in questo formato, rispetto al corrispondente
codice per la visualizzazione di una lista nello stesso formato a due colonne.

Creazione di una serie con tutti gli elementi che hanno lo stesso valore

Puoi creare una serie di elementi che hanno tutti lo stesso valore:

lecca qui per visualizzare l'immagine del codice

In [4]: ​pd.Series ( 98.6 , intervallo ( 3 ))


Fuori [4]:
0 98.6
1 98.6

2 98.6 Pagina 289


dtype: float64

Il secondo argomento è un oggetto iterabile monodimensionale (come un elenco, un array o un file

range) contenente gli indici delle serie. Il numero di indici determina il numero
di elementi.

Accesso agli elementi di una serie

È possibile accedere agli elementi di una serie tramite parentesi quadre contenenti un indice:

In [5]: voti [ 0 ]
Uscita [5]: 87

Produzione di statistiche descrittive per una serie

Series fornisce molti metodi per attività comuni, inclusa la produzione di vari
statistiche descrittive. Qui mostriamo count, mean, min, max e std (standard

deviazione):
lecca qui per visualizzare l'immagine del codice

In [6]: grades.count ()
Fuori [6]: 3

In [7]: grades.mean ()
Uscita [7]: 93.66666666666667

In [8]: grades.min ()
Uscita [8]: 87

In [9]: grades.max ()
Uscita [9]: 100

In [10]: grades.std ()
Uscita [10]: 6.506407098647712

Ognuno di questi è una riduzione dello stile funzionale. Il metodo Calling Series descrive
produce tutte queste statistiche e molto altro:

lecca qui per visualizzare l'immagine del codice

In [11]: grades.describe ()
Fuori [11]:

contare 3.000000 Pagina 290


media 93,666667
std 6.506407
min 87.000000
25% 90.500000
50% 94.000000
75% 97.000000
max 100.000000
dtype: float64

Il 25%, il 50% e il 75% sono quartili :

Il 50% rappresenta la mediana dei valori ordinati.

Il 25% rappresenta la mediana della prima metà dei valori ordinati.

Il 75% rappresenta la mediana della seconda metà dei valori ordinati.

Per i quartili, se ci sono due elementi intermedi, la loro media è quella di quel quartile
mediano. Abbiamo solo tre valori nella nostra serie, quindi il quartile del 25% è la media di

87 e 94, e il quartile del 75% è la media di 94 e 100. Insieme, il


l'intervallo interquartile è il 75% del quartile meno il 25% del quartile, che è un altro
misura della dispersione, come la deviazione standard e la varianza. Naturalmente, quartili e
intervallo interquartile sono più utili in set di dati più grandi.

Creazione di una serie con indici personalizzati

È possibile specificare indici personalizzati con l'argomento della parola chiave index:

lecca qui per visualizzare l'immagine del codice

In [12]: grades = pd.Series ([ 87 , 100 , 94 ], index = [ 'Wally' , 'Eva' , 'Sam' ]

n [13]: voti
Fuori [13]:
Wally 87
Eva 100
Sam 94
dtype: int64

In questo caso, abbiamo utilizzato indici di stringa, ma puoi utilizzare altri tipi immutabili, tra cui
interi che non iniziano da 0 e interi non consecutivi. Ancora una volta, nota quanto bene e
panda concisamente formatta una serie per la visualizzazione.

D
C inizializzatori ictionary
io

Inizializzatori di dizionario Pagina 291

Se si inizializza una serie con un dizionario, le sue chiavi diventano gli indici della serie e
i suoi valori diventano i valori dell'elemento della serie:

lecca qui per visualizzare l'immagine del codice

In [14]: grades = pd.Series ({ 'Wally' : 87 , 'Eva' : 100 , 'Sam' : 94 })

In [15]: voti
Fuori [15]:
Wally 87
Eva 100
Sam 94
dtype: int64

Accesso agli elementi di una serie tramite indici personalizzati

In una serie con indici personalizzati, è possibile accedere ai singoli elementi tramite quadrato

parentesi che contengono un valore di indice personalizzato:

In [16]: voti [ "Eva" ]


Fuori [16]: 100

Se gli indici personalizzati sono stringhe che potrebbero rappresentare identificatori Python validi, panda
li aggiunge automaticamente alla serie come attributi a cui è possibile accedere tramite un punto (.),
come in:

In [17]: gradi.Wally
Uscita [17]: 87

Series ha anche incorporato attributi. Ad esempio, l' attributo dtype restituisce


tipo di elemento dell'array sottostante:

In [18]: grades.dtype
Out [18]: dtype ('int64')

e l' attributo values restituisce l'array sottostante:

lecca qui per visualizzare l'immagine del codice

In [19]: grades.values

Uscita [19]: array ([87, 100, 94]) Pagina 292

Creazione di una serie di stringhe


Se una serie contiene stringhe, puoi usare il suo attributo str per chiamare i metodi stringa
gli elementi. Innanzitutto, creiamo una serie di stringhe correlate all'hardware:

lecca qui per visualizzare l'immagine del codice

In [20]: hardware = pd.Series ([ 'Hammer' , 'Saw' , 'Wrench' ])

In [21]: hardware
Fuori [21]:
0 Hammer
1 sega
2 chiave
dtype: oggetto

Si noti che i panda anche rightaligns valori degli elementi di stringa e che la DTYPE per le stringhe

è oggetto.

Chiamiamo il metodo stringa contiene su ogni elemento per determinare se il valore di


ogni elemento contiene una "a" minuscola:

lecca qui per visualizzare l'immagine del codice

In [22]: hardware.str.contains ( 'a' )


Fuori [22]:
0 Vero
1 Vero
2 Falso
dtype: bool

Pandas restituisce una serie contenente valori bool che indicano il metodo contiene

risultato per ogni elemento: l'elemento con indice 2 ("Chiave inglese") non contiene una "a",
quindi il suo elemento nella serie risultante è False. Nota che i panda gestiscono l'iterazione

internamente per te: un altro esempio di programmazione in stile funzionale. Lo str


attributo fornisce molti metodi di elaborazione delle stringhe simili a quelli di Python
tipo di stringa. Per un elenco, vedere:
ttps: //pandas.pydata.org/pandas

ocs / stabile / API.html # stringhandling .

Di seguito viene utilizzato il metodo stringa upper per produrre una nuova serie contenente il file

C
dh
Pagina 293
versioni maiuscole di ogni elemento nell'hardware:

lecca qui per visualizzare l'immagine del codice

In [23]: hardware.str.upper ()
Fuori [23]:
0 MARTELLO
1 SEGA
2 CHIAVE
dtype: oggetto

7.14.2 DataFrame

Un DataFrame è un array bidimensionale avanzato. Come Series, DataFrames può


hanno indici di riga e di colonna personalizzati e offrono operazioni e funzionalità aggiuntive
che li rendono più convenienti per molte attività orientate alla datascience. DataFrames
supporta anche i dati mancanti. Ogni colonna in un DataFrame è una serie. La serie
che rappresenta ogni colonna può contenere diversi tipi di elementi, come vedrai presto quando
discutiamo del caricamento di set di dati in DataFrame.
Creazione di un DataFrame da un dizionario

Creiamo un DataFrame da un dizionario che rappresenta i voti degli studenti su tre


esami:

lecca qui per visualizzare l'immagine del codice

In [1]: importa i panda come pd

In [2]: grades_dict = { 'Wally' : [ 87 , 96 , 70 ], 'Eva' : [ 100 , 87 , 90 ],


...: "Sam" : [ 94 , 77 , 90 ], "Katie" : [ 100 , 81 , 82 ],
...: "Bob" : [ 83 , 65 , 85 ]}
...:

In [3]: grades = pd.DataFrame (grades_dict)

In [4]: ​voti
Fuori [4]:
Wally Eva Sam Katie Bob
0 87100 94100 83
1 96 87 77 81 65
2 70 90 90 82 85

Pandas visualizza DataFrame in formato tabulare con gli indici allineati a sinistra nel file

C
Pagina 294
colonna indice e i valori delle colonne rimanenti allineati a destra . Le chiavi del dizionario
diventano i nomi delle colonne ei valori associati a ciascuna chiave diventano l'elemento
valori nella colonna corrispondente. A breve, mostreremo come "capovolgere" le righe e
colonne. Per impostazione predefinita, gli indici di riga sono numeri interi generati automaticamente a partire da 0.

Personalizzazione degli indici di un DataFrame con l'attributo index

Avremmo potuto specificare indici personalizzati con l'argomento della parola chiave index quando abbiamo

ha creato il DataFrame, come in:

lecca qui per visualizzare l'immagine del codice

pd.DataFrame (grades_dict, index = [ 'Test1' , 'Test2' , 'Test3' ])

Usiamo l' attributo index per cambiare gli indici del DataFrame da sequenziali

numeri interi alle etichette:

lecca qui per visualizzare l'immagine del codice

In [5]: grades.index = [ "Test1" , "Test2" , "Test3" ]

In [6]: voti
Fuori [6]:
Wally Eva Sam Katie Bob
Test1 87100 94100 83
Test2 96 87 77 81 65
Test3 70 90 90 82 85

Quando si specificano gli indici, è necessario fornire una raccolta unidimensionale che abbia
lo stesso numero di elementi quante sono le righe nel DataFrame; in caso contrario, a

Si verifica ValueError. Series fornisce anche un attributo di indice per modificare un file
indici delle serie esistenti.
Accesso alle colonne di un DataFrame
Uno dei vantaggi dei panda è che puoi esaminare rapidamente e comodamente i tuoi dati in formato
molti modi diversi, inclusa la selezione di porzioni di dati. Cominciamo ottenendo
I voti di Eva per nome, che mostra la sua colonna come una serie:

In [7]: voti [ "Eva" ]


Fuori [7]:
Test1 100

Test2 87 Pagina 295


Test3 90
Nome: Eva, dtype: int64

Se le stringhe columnname di un DataFrame sono identificatori Python validi, puoi usarle


come attributi. Otteniamo i voti di Sam con l' attributo Sam :

In [8]: grades.Sam
Fuori [8]:
Test1 94
Test2 77
Test3 90
Nome: Sam, dtype: int64

Selezione di righe tramite gli attributi loc e iloc

Sebbene DataFrames supporti funzionalità di indicizzazione con [], la documentazione di pandas

consiglia di utilizzare gli attributi loc, iloc, at e iat, ottimizzati per


accedi a DataFrame e fornisci anche funzionalità aggiuntive oltre a ciò che puoi fare
solo con []. Inoltre, la documentazione afferma che l'indicizzazione con [] spesso produce un file
copia dei dati, che è un errore logico se si tenta di assegnare nuovi valori al file

DataFrame assegnando al risultato dell'operazione [].

È possibile accedere a una riga tramite la sua etichetta tramite l' attributo loc del DataFrame . Il seguente
elenca tutti i voti nella riga "Test1":

lecca qui per visualizzare l'immagine del codice

In [9]: grades.loc [ 'Test1' ]


Fuori [9]:
Wally 87
Eva 100
Sam 94
Katie 100
Bob 83
Nome: Test1, dtype: int64

È inoltre possibile accedere alle righe tramite indici interi a base zero utilizzando l' attributo iloc (i
in iloc significa che è usato con indici interi). Di seguito sono elencati tutti i voti in
la seconda riga:

lecca qui per visualizzare l'immagine del codice

C
Pagina 296
In [10]: grades.iloc [ 1 ]
Fuori [10]:
Wally 96
Eva 87
Sam 77
Katie 81
Bob 65
Nome: Test2, dtype: int64

Selezione di righe tramite sezioni ed elenchi con gli attributi loc e iloc

L'indice può essere una sezione . Quando si utilizzano sezioni contenenti etichette con loc, l'intervallo

specificato include l'indice alto ('Test3'):

lecca qui per visualizzare l'immagine del codice

In [11]: grades.loc [ 'Test1' : 'Test3' ]


Fuori [11]:
Wally Eva Sam Katie Bob
Test1 87100 94100 83
Test2 96 87 77 81 65
Test3 70 90 90 82 85

Quando si utilizzano sezioni contenenti indici interi con iloc, l'intervallo specificato esclude

l'indice alto (2):

lecca qui per visualizzare l'immagine del codice

In [12]: grades.iloc [ 0 : 2 ]
Fuori [12]:
Wally Eva Sam Katie Bob
Test1 87100 94100 83
Test2 96 87 77 81 65

Per selezionare righe specifiche , utilizza un elenco anziché la notazione slice con loc o iloc:

lecca qui per visualizzare l'immagine del codice

In [13]: grades.loc [[ 'Test1' , 'Test3' ]]


Fuori [13]:
Wally Eva Sam Katie Bob
Test1 87100 94100 83
Test3 70 90 90 82 85

In [14]: grades.iloc [[ 0 , 2 ]]

Fuori [14]: Pagina 297


Wally Eva Sam Katie Bob
Test1 87100 94100 83
Test3 70 90 90 82 85

Selezione di sottoinsiemi di righe e colonne


Finora abbiamo selezionato solo intere righe. Puoi concentrarti su piccoli sottoinsiemi di un DataFrame

selezionando righe e colonne utilizzando due sezioni, due elenchi o una combinazione di sezioni e
elenchi.

Supponi di voler visualizzare solo i voti di Eva e Katie nei Test1 e Test2. Noi
può farlo usando loc con uno slice per le due righe consecutive e un elenco per le due
colonne non consecutive:

lecca qui per visualizzare l'immagine del codice

In [15]: grades.loc [ 'Test1' : 'Test2' , [ 'Eva' , 'Katie' ]]


Fuori [15]:
Eva Katie
Test1 100100
Test2 87 81

La sezione "Test1": "Test2" seleziona le righe per Test1 e Test2. L'elenco ["Eva",

"Katie"] seleziona solo i voti corrispondenti da queste due colonne.

Usiamo iloc con un elenco e una fetta per selezionare il primo e il terzo test e i primi tre
colonne per questi test:

lecca qui per visualizzare l'immagine del codice

In [16]: grades.iloc [[ 0 , 2 ], 0 : 3 ]
Fuori [16]:
Wally Eva Sam
Test1 87100 94
Test3 70 90 90

Indicizzazione booleana

Una delle funzionalità di selezione più potenti dei panda è l'indicizzazione booleana . Per
esempio, selezioniamo tutti i voti A, ovvero quelli che sono maggiori o uguali a 90:

lecca qui per visualizzare l'immagine del codice

C
Pagina 298
In [17]: voti [voti> = 90 ]
Fuori [17]:
Wally Eva Sam Katie Bob
Test1 NaN 100,0 94,0 100,0 NaN
Test2 96,0 NaN NaN NaN NaN
Test3 NaN 90,0 90,0 NaN NaN

Pandas controlla ogni grado per determinare se il suo valore è maggiore o uguale a 90
e, in tal caso, lo include nel nuovo DataFrame. Gradi per i quali la condizione è False
sono rappresentati come NaN (non un numero) nel nuovo DataFrame. NaN è panda

notazione per i valori mancanti.

Selezioniamo tutti i gradi B nell'intervallo 80-89:

lecca qui per visualizzare l'immagine del codice

In [18]: voti [(voti> = 80 ) & (voti < 90 )]


Fuori [18]:
Wally Eva Sam Katie Bob
Test1 87,0 NaN NaN NaN 83,0
Test2 NaN 87,0 NaN 81,0 NaN
Test3 NaN NaN NaN 82,0 85,0

Gli indici booleani di Pandas combinano più condizioni con l'operatore Python e
(AND bit per bit), non l'operatore e booleano. Per o le condizioni, utilizzare | (OR bit per bit).

NumPy supporta anche l'indicizzazione booleana per gli array, ma ne restituisce sempre uno
matrice dimensionale contenente solo i valori che soddisfano la condizione.

Accesso a una cella DataFrame specifica per riga e colonna

È possibile utilizzare gli attributi at e iat di un DataFrame per ottenere un singolo valore da un file

DataFrame. Come loc e iloc, at usa etichette e iat usa indici interi. In ciascuna
caso, gli indici di riga e di colonna devono essere separati da una virgola. Selezioniamo Eva's

Grado Test2 (87) e grado Test3 di Wally (70)


lecca qui per visualizzare l'immagine del codice

In [19]: grades.at [ 'Test2' , 'Eva' ]


Fuori [19]: 87

In [20]: grades.iat [ 2 , 0 ]
Uscita [20]: 70

C
Pagina 299
È inoltre possibile assegnare nuovi valori a elementi specifici. Cambiamo il grado Test2 di Eva in

100 usando at, quindi cambiarlo di nuovo in 87 usando iat:

lecca qui per visualizzare l'immagine del codice

In [21]: grades.at [ 'Test2' , 'Eva' ] = 100

In [22]: grades.at [ 'Test2' , 'Eva' ]


Fuori [22]: 100

In [23]: grades.iat [ 1 , 2 ] = 87

In [24]: grades.iat [ 1 , 2 ]
Uscita [24]: 87,0

Statistiche descrittive

Sia Series che DataFrame hanno un metodo di descrizione che calcola di base
statistiche descrittive per i dati e li restituisce come DataFrame. In un DataFrame,
le statistiche sono calcolate per colonna (di nuovo, presto vedrai come capovolgere le righe e
colonne):

lecca qui per visualizzare l'immagine del codice

In [25]: grades.describe ()
Fuori [25]:
Wally Eva Sam Katie Bob
conteggio 3.000000 3.000000 3.000000 3.000000 3.000000
media 84.333333 92.333333 87.000000 87.666667 77.666667
std 13.203535 6.806859 8.888194 10.692677 11.015141
min 70.000000 87.000000 77.000000 81.000000 65.000000
25% 78.500000 88.500000 83.500000 81.500000 74.000000
50% 87.000000 90.000000 90.000000 82.000000 83.000000
75% 91.500000 95.000000 92.000000 91.000000 84.000000
max 96.000000 100.000000 94.000000 100.000000 85.000000

Come puoi vedere, la descrizione ti offre un modo rapido per riassumere i tuoi dati. Piacevolmente

dimostra la potenza della programmazione orientata agli array con un linguaggio pulito e conciso
chiamata in stile funzionale. Pandas gestisce internamente tutti i dettagli del calcolo di questi
statistiche per ogni colonna. Potresti essere interessato a vedere statistiche simili sui test
bytest in modo da poter vedere come si comportano tutti gli studenti nei test 1, 2 e 3: lo faremo
mostra come farlo a breve.

Per impostazione predefinita, panda calcola le statistiche descrittive con valori in virgola mobile e

C
Pagina 300
li visualizza con sei cifre di precisione. Puoi controllare la precisione e altro
impostazioni predefinite con la funzione set_option dei panda :

lecca qui per visualizzare l'immagine del codice


In [26]: pd.set_option ( 'precision' , 2 )

In [27]: grades.describe ()
Fuori [27]:
Wally Eva Sam Katie Bob
conteggio 3.00 3.00 3.00 3.00 3.00
media 84,33 92,33 87,00 87,67 77,67
standard 13,20 6,81 8,89 10,69 11,02
min 70,00 87,00 77,00 81,00 65,00
25% 78,50 88,50 83,50 81,50 74,00
50% 87,00 90,00 90,00 82,00 83,00
75% 91,50 95,00 92,00 91,00 84,00
max 96,00 100,00 94,00 100,00 85,00

Per i voti degli studenti, la più importante di queste statistiche è probabilmente la media. Puoi
calcola quello per ogni studente semplicemente chiamando mean sul DataFrame:

In [28]: grades.mean ()
Fuori [28]:
Wally 84.33
Eva 92.33
Sam 87.00
Katie 87.67
Bob 77.67
dtype: float64

Tra poco mostreremo come ottenere la media dei voti di tutti gli studenti su ogni test
in una riga di codice aggiuntivo.

Trasposizione del DataFrame con l'attributo T.

Puoi trasporre rapidamente le righe e le colonne, in modo che le righe diventino le colonne,
e le colonne diventano le righe, utilizzando l' attributo T :

lecca qui per visualizzare l'immagine del codice

In [29]: voti.T
Fuori [29]:
Test1 Test2 Test3
Wally 87 96 70
Eva 100 87 90

Sam 94 77 90 Pagina 301


Katie 100 81 82
Bob 83 65 85

T restituisce una vista trasposta (non una copia) del DataFrame.

Supponiamo che invece di ottenere le statistiche di riepilogo dallo studente, tu voglia ottenere
loro tramite prova. Chiama semplicemente descrivere sui voti T, come in:

lecca qui per visualizzare l'immagine del codice

In [30]: grades.T.describe ()
Fuori [30]:
Test1 Test2 Test3
contare 5,00 5,00 5,00
media 92,80 81,20 83,40
standard 7,66 11,54 8,23
min 83,00 65,00 70,00
25% 87,00 77,00 82,00
50% 94,00 81,00 85,00
75% 100,00 87,00 90,00
max 100,00 96,00 90,00

Per vedere la media dei voti di tutti gli studenti su ogni test, basta chiamare mean sulla T

attributo:

In [31]: grades.T.mean ()
Fuori [31]:
Test1 92.8
Test2 81.2
Test3 83.4
dtype: float64

Ordinamento per righe in base ai rispettivi indici

Ordinerai spesso i dati per una più facile leggibilità. Puoi ordinare un DataFrame in base alle sue righe o

colonne, in base ai loro indici o valori. Ordiniamo le righe in base ai loro indici in
ordine discendente utilizzando sort_index e l'argomento della parola chiave ascending = False

(l'impostazione predefinita è ordinare in ordine crescente ). Ciò restituisce un nuovo DataFrame contenente
i dati ordinati:

lecca qui per visualizzare l'immagine del codice

In [32]: grades.sort_index (ascending = False )

Fuori [32]: Pagina 302


Wally Eva Sam Katie Bob
Test3 70 90 90 82 85
Test2 96 87 77 81 65
Test1 87100 94100 83

Ordinamento per indici di colonna


Ora ordiniamo le colonne in ordine crescente (da sinistra a destra) in base ai loro nomi di colonna.
Il passaggio dell'argomento della parola chiave axis = 1 indica che si desidera ordinare la colonna
indici, anziché gli indici di riga: axis = 0 (impostazione predefinita) ordina gli indici di riga :

lecca qui per visualizzare l'immagine del codice

In [33]: grades.sort_index (axis = 1 )


Fuori [33]:
Bob Eva Katie Sam Wally
Test1 83100100 94 87
Test2 65 87 81 77 96
Test3 85 90 82 90 70

Ordinamento per valori di colonna

Supponiamo di voler vedere i voti di Test1 in ordine decrescente in modo da poter vedere il file

i nomi degli studenti in ordine di grado più alto o più basso. Possiamo chiamare il metodo
sort_values come segue:

lecca qui per visualizzare l'immagine del codice

In [34]: grades.sort_values ​(by = "Test1" , axis = 1 , ascending = False )


Fuori [34]:
Eva Katie Sam Wally Bob
Test1 100100 94 87 83
Test2 87 81 77 96 65
Test3 90 82 90 70 85
Gli argomenti della parola chiave by e axis lavorano insieme per determinare quali valori saranno

smistato. In questo caso, ordiniamo in base ai valori della colonna (asse = 1) per Test1.

Certo, potrebbe essere più facile leggere i voti e i nomi se fossero in una colonna, quindi
possiamo invece ordinare il DataFrame trasposto. Qui, non era necessario specificare il file

argomento della parola chiave axis, perché sort_values ​ordina i dati in una colonna specificata per
predefinito:

lecca qui per visualizzare l'immagine del codice Pagina 303

In [35]: grades.T.sort_values ​(by = 'Test1' , ascending = False )


Fuori [35]:
Test1 Test2 Test3
Eva 100 87 90
Katie 100 81 82
Sam 94 77 90
Wally 87 96 70
Bob 83 65 85

Infine, poiché stai ordinando solo i voti del Test1, potresti non voler vedere l'altro

prove a tutti. Quindi, combiniamo la selezione con l'ordinamento:

lecca qui per visualizzare l'immagine del codice

In [36]: grades.loc [ 'Test1' ] .sort_values ​(ascending = False )


Fuori [36]:
Katie 100
Eva 100
Sam 94
Wally 87
Bob 83
Nome: Test1, dtype: int64

Copia e ordinamento sul posto

Per impostazione predefinita, sort_index e sort_values ​restituiscono una copia dell'originale

DataFrame, che potrebbe richiedere una notevole quantità di memoria in un'applicazione per big data. Puoi
ordinare il DataFrame in posizione , invece di copiare i dati. A tale scopo, passare la parola chiave
argomento inplace = True per sort_index o sort_values.

Abbiamo mostrato molte caratteristiche della serie Panda e DataFrame. Nel prossimo capitolo

Introduzione alla sezione Data Science, useremo Series e DataFrames per il munging dei dati -
pulizia e preparazione dei dati da utilizzare nel database o nel software di analisi.

7.15 WRAP-UP
Questo capitolo ha esplorato l'uso dei ndarrays ad alte prestazioni di NumPy per l'archiviazione e

recupero dei dati e per eseguire manipolazioni di dati comuni in modo conciso e con
ridotta possibilità di errori con la programmazione in stile funzionale. Ci riferiamo a ndarrays

semplicemente dal loro sinonimo, array.

C
Pagina 304
Gli esempi del capitolo hanno dimostrato come creare, inizializzare e fare riferimento a un individuo
elementi di array unidimensionali e bidimensionali. Abbiamo utilizzato gli attributi per determinare un file

dimensione, forma e tipo di elemento dell'array. Abbiamo mostrato le funzioni che creano array di 0,
1s, valori specifici o valori di intervalli. Abbiamo confrontato l'elenco e le prestazioni dell'array con il
IPython% timeit magic e ha visto che gli array sono fino a due ordini di grandezza più veloci.

Abbiamo utilizzato operatori di array e funzioni universali NumPy per eseguire elementwise

calcoli su ogni elemento di array che hanno la stessa forma. Hai visto anche quello
NumPy utilizza la trasmissione per eseguire operazioni elementwise tra array e

valori scalari e tra array di forme diverse. Abbiamo introdotto vari builtin

metodi di array per eseguire calcoli utilizzando tutti gli elementi di un array e noi
ha mostrato come eseguire quei calcoli riga per riga o colonna per colonna. Noi
ha dimostrato varie funzionalità di suddivisione e indicizzazione degli array che sono più potenti
rispetto a quelli forniti dalle raccolte incorporate di Python. Abbiamo dimostrato vari modi per farlo
rimodellare gli array. Abbiamo discusso su come eseguire la copia superficiale e la copia profonda di array e altro
Oggetti Python.

Nella sezione Intro to Data Science, abbiamo iniziato la nostra introduzione multisezione a
popolare libreria di panda che utilizzerai in molti dei capitoli dei case study di data science.
Hai visto che molte applicazioni per big data richiedono raccolte più flessibili rispetto a NumPy

array, raccolte che supportano tipi di dati misti, indicizzazione personalizzata, dati mancanti, dati
non è strutturato in modo coerente e i dati devono essere manipolati in moduli
appropriato per i database e i pacchetti di analisi dei dati utilizzati.

Abbiamo mostrato come creare e manipolare Serie unidimensionali simili ad array di panda
e DataFrame bidimensionali. Abbiamo personalizzato gli indici di serie e DataFrame.

Hai visto gli output ben formattati dei panda e hai personalizzato la precisione del galleggiamento
valori in punti. Abbiamo mostrato vari modi per accedere e selezionare i dati in Series e

DataFrames. Abbiamo utilizzato il metodo Descrivere per calcolare le statistiche descrittive di base per
Serie e DataFrames. Abbiamo mostrato come trasporre le righe DataFrame e
colonne tramite l'attributo T. Hai visto diversi modi per ordinare i DataFrame usando il loro indice
valori, i nomi delle loro colonne, i dati nelle loro righe e i dati nelle loro colonne. Tu sei
ora ha familiarità con quattro potenti raccolte di tipo array: elenchi, array, serie e

DataFrame e i contesti in cui utilizzarli. Aggiungeremo un quinto - tensori - nel file


Capitolo "Deep Learning".

Nel prossimo capitolo, daremo uno sguardo più approfondito alle stringhe, alla formattazione delle stringhe e alle stringhe
metodi. Introduciamo anche espressioni regolari, che useremo per trovare modelli in
testo. Le funzionalità che vedrai ti aiuteranno a prepararti per il " Linguaggio naturale

T
N
Pagina 305
capitolo rocessing (PNL) "e altri capitoli chiave sulla scienza dei dati. Nel prossimo capitolo
Nell'introduzione alla sezione Data Science, introdurremo il munging dei dati dei panda , che prepara i dati per
utilizzare nel database o nel software di analisi. Nei capitoli successivi, useremo i panda per
analisi di base delle serie temporali e introduzione alle funzionalità di visualizzazione dei panda.
https://avxhm.se/blogs/hill0

P
Pagina 306

tory . Corde: uno sguardo più profondo


Obiettivi
foto

In questo capitolo potrai:


rning Pat

Comprendere l'elaborazione del testo.


fers & Dea

Usa metodi stringa.


hlights

Formatta il contenuto della stringa.


ttings

Concatena e ripeti le stringhe.


Supporto
Elimina gli spazi bianchi dalle estremità delle stringhe.
Disconnessione
Cambia i caratteri da minuscolo a maiuscolo e viceversa.

Confronta le stringhe con gli operatori di confronto.

Cerca nelle stringhe sottostringhe e sostituisci le sottostringhe.

Dividi le stringhe in gettoni.

Concatena le stringhe in una singola stringa con un separatore specificato tra gli elementi.

Crea e usa espressioni regolari per abbinare modelli nelle stringhe, sostituire le sottostringhe
e convalidare i dati.

Usa metacaratteri delle espressioni regolari, quantificatori, classi di caratteri e raggruppamenti.

Comprendi quanto siano critiche le manipolazioni delle stringhe per l'elaborazione del linguaggio naturale.

Comprendere i termini della scienza dei dati data munging, data wrangling e data cleaning,
e usa espressioni regolari per munge i dati nei formati preferiti.

8
Pagina 307
Contorno

.1 Introduzione

.2 Formattazione delle stringhe

.2.1 Tipi di presentazione

.2.2 Larghezze dei campi e allineamento

.2.3 Formattazione numerica

.2.4 Metodo di formattazione della stringa

.3 Concatenazione e ripetizione di stringhe

.4 Rimozione di spazi bianchi dalle stringhe

.5 Modifica delle maiuscole / minuscole

.6 Operatori di confronto per stringhe

.7 Ricerca di sottostringhe

.8 Sostituzione di sottostringhe

.9 Divisione e unione di stringhe

.10 Caratteri e metodi di verifica dei caratteri

.11 Corde grezze

.12 Introduzione alle espressioni regolari

.12.1 re Modulo e funzione fullmatch

.12.2 Sostituzione di sottostringhe e suddivisione di stringhe

.12.3 Altre funzioni di ricerca; accesso alle corrispondenze

.13 Introduzione alla scienza dei dati: panda, espressioni regolari e scambio di dati

.14 WrapUp

8
Pagina 308

.1 INTRODUZIONE
Abbiamo introdotto le stringhe, la formattazione delle stringhe di base e diversi operatori di stringa e
metodi. Hai visto che le stringhe supportano molte delle stesse operazioni di sequenza delle liste
e tuple, e quelle stringhe, come le tuple, sono immutabili. Ora, diamo uno sguardo più approfondito
stringhe e introdurre espressioni regolari e il modulo re, che useremo per abbinare
1
modelli nel testo. Le espressioni regolari sono particolarmente importanti nei dati ricchi di oggi
applicazioni. Le funzionalità qui presentate ti aiuteranno a prepararti per il " aturale
anguage Processing (NLP) ”e altri capitoli chiave sulla scienza dei dati. Nella PNL
capitolo, esamineremo altri modi per far sì che i computer manipolino e persino "comprendano"
testo. La tabella seguente mostra molte applicazioni relative all'elaborazione delle stringhe e all'NLP. Nel
nella sezione Introduzione alla scienza dei dati, introduciamo brevemente i dati
pulizia / munging / wrangling con Pandas Series e DataFrames.

1
Vedremo nei capitoli del caso di studio della scienza dei dati che la ricerca di pattern nel testo è un
parte cruciale dell'apprendimento automatico.

String e
PNL
applicazioni

Anagrammi

Automatizzato
classificazione di
scritto
Traduzione interlinguistica
compiti a casa

Documento legale
Automatizzato Classificazione dello spam
preparazione
sistemi di insegnamento
Motori Speechtotext
Monitoraggio dei social media
Classificazione
post Correttori ortografici
articoli

Linguaggio naturale Steganografia


Chatbot
comprensione

Compilatori e Editor di testo


Analisi delle opinioni

8LN
Pagina 309
interpreti Software di composizione delle pagine Motori Texttospeech

Scrittura creativa Palindromi Web scraping

Crittografia Etichettatura di parti di discorso Chi ha scritto


Le opere di Shakespeare?
Documento Progetto Gutenberg gratuito
classificazione libri Nuvole di parole

Documento Leggere libri, articoli, Giochi di parole


somiglianza documentazione e
conoscenza assorbente Scrittura medica
Documento diagnosi da raggi X,
riepilogo Motori di ricerca scansioni, esami del sangue

Libro elettronico Analisi del sentiment e molti altri


lettori
Intercettazione di una frode

Grammatica
dama

8.2 FORMATTAZIONE DELLE STRINGHE


La corretta formattazione del testo semplifica la lettura e la comprensione dei dati. Qui, vi presentiamo
molte funzionalità di formattazione del testo.

8.2.1 Tipi di presentazione


Hai visto la formattazione di base delle stringhe con fstrings. Quando specifichi un segnaposto per un file
value in una stringa f, Python assume che il valore debba essere visualizzato come una stringa a meno che
si specifica un altro tipo. In alcuni casi, il tipo è obbligatorio. Ad esempio, formatta
il valore del float 17.489 arrotondato alla posizione dei centesimi:

In [1]: f " { 17.489 : .2 f} "


Uscita [1]: '17 .49 '

Pagina 310
Python supporta la precisione solo per i valori floatingpoint e Decimal. La formattazione è

tipo dipendente —se provi a usare .2f per formattare una stringa come 'ciao', un ValueError
si verifica. Quindi è richiesto il tipo di presentazione f nell'identificatore di formato .2f. It
indica quale tipo viene formattato in modo che Python possa determinare se l'altro
le informazioni di formattazione sono consentite per quel tipo. Qui, mostriamo alcuni comuni
tipi di presentazione. Puoi visualizzare l'elenco completo su

ttps: //docs.python.org/3/library/string.html#formatspec

Interi

Il tipo di presentazione d formatta i valori interi come stringhe:

In [2]: f ' { 10 : d} '


Uscita [2]: "10"

Esistono anche tipi di presentazione intera (b, oex o X) che formattano i numeri interi usando
2
i sistemi numerici binari, ottali o esadecimali.

2
Vedere l'appendice in linea Sistemi numerici per informazioni su binario, ottale e
sistemi numerici esadecimali.

Personaggi

Il tipo di presentazione c formatta un codice di caratteri interi come corrispondente


carattere:

lecca qui per visualizzare l'immagine del codice

In [3]: f ' { 65 : c} { 97 : c} '


Uscita [3]: "A a"
stringhe

Il tipo di presentazione s è l'impostazione predefinita. Se si specifica esplicitamente s, il valore da formattare


deve essere una variabile che fa riferimento a una stringa, un'espressione che produce una stringa o un file
stringa letterale, come nel primo segnaposto di seguito. Se non specifichi un tipo di presentazione,
come nel secondo segnaposto sotto, i valori non di stringa come il numero intero 7 vengono convertiti in
stringhe:

lecca qui per visualizzare l'immagine del codice

C
h

Pagina 311
In [4]: ​f ' { "hello" : s} { 7 } '
Uscita [4]: ​"ciao 7"

In questo frammento, "ciao" è racchiuso tra virgolette doppie. Ricorda che non puoi posizionare
virgolette singole all'interno di una stringa con virgolette singole.

Valori a virgola mobile e decimali

Hai utilizzato il tipo di presentazione f per formattare i valori in virgola mobile e decimale. Per
valori estremamente grandi e piccoli di questi tipi, notazione esponenziale (scientifica)
può essere utilizzato per formattare i valori in modo più compatto. Mostriamo la differenza tra f
e e per un valore grande, ciascuno con tre cifre di precisione a destra del decimale
punto:

lecca qui per visualizzare l'immagine del codice

In [5]: from decimal import Decimal

In [6]: f ' {Decimal ( "10000000000000000000000000.0" ): .3 f} '


Uscita [6]: "10000000000000000000000000.000"

In [7]: f ' {Decimal ( "10000000000000000000000000.0" ): .3 e} '


Uscita [7]: "1.000e + 25"

Per il tipo di presentazione e nello snippet [5], il valore formattato 1.000e + 25 è


equivalente a

25
1.000 x 10

Se preferisci una E maiuscola per l'esponente, usa il tipo di presentazione E invece di e.

8.2.2 Larghezze dei campi e allineamento


In precedenza, utilizzavi le larghezze dei campi per formattare il testo in un numero di caratteri specificato
posizioni. Per impostazione predefinita, Python right0aligns numeri e leftaligns altri valori tali
come stringhe: racchiudiamo i risultati di seguito tra parentesi ([]) in modo da poter vedere come i valori
allineare nel campo:

lecca qui per visualizzare l'immagine del codice

In [1]: f '[ { 27 : 10 d} ]'

Uscita [1]: "[27]" Pagina 312

In [2]: f "[ { 3.5 : 10 f} ]"


Uscita [2]: "[3.500000]"
In [3]: f '[ { "hello" : 10 } ]'
Uscita [3]: "[ciao]"

Snippet [2] mostra che Python formatta valori float con sei cifre di precisione per
a destra del punto decimale per impostazione predefinita. Per i valori che hanno meno caratteri di
larghezza del campo, le posizioni dei caratteri rimanenti vengono riempite con spazi. Valori con più
i caratteri rispetto alla larghezza del campo utilizzano tutte le posizioni dei caratteri necessarie.

Specificare in modo esplicito l'allineamento a sinistra ea destra in un campo

Ricorda che puoi specificare l'allineamento sinistro e destro con <e>:

lecca qui per visualizzare l'immagine del codice

In [4]: ​f '[ { 27 : < 15 d} ]'


Uscita [4]: ​"[27]"

In [5]: f "[ { 3.5 : < 15 f} ]"


Uscita [5]: "[3.500000]"

In [6]: f '[ { "hello" :> 15 } ]'


Uscita [6]: "[ciao]"

Centrare un valore in un campo

Inoltre, puoi centrare i valori:

lecca qui per visualizzare l'immagine del codice

In [7]: f '[ { 27 : ^ 7 d} ]'


Uscita [7]: "[27]"

In [8]: f "[ { 3.5 : ^ 7.1 f} ]"


Uscita [8]: "[3.5]"

In [9]: f '[ { "hello" : ^ 7 } ]'


Uscita [9]: "[ciao]"

Il centraggio tenta di distribuire ugualmente a


a sinistra ea destra del valore formattato. Python posiziona lo spazio extra a destra se un file

C
Pagina 313
rimane un numero dispari di posizioni dei caratteri.

8.2.3 Formattazione numerica


Sono disponibili numerose funzionalità di formattazione numerica.

Formattazione di numeri positivi con segni

A volte è desiderabile forzare il segno su un numero positivo:

In [1]: f "[ { 27 : + 10 d} ]"


Uscita [1]: "[+27]"

Il + prima della larghezza del campo specifica che un numero positivo deve essere preceduto da un +.
Un numero negativo inizia sempre con a. Per riempire i caratteri rimanenti del campo
con 0 anziché spazi, inserire uno 0 prima della larghezza del campo (e dopo il + se c'è
uno):
In [2]: f "[ { 27 : + 010 d} ]"
Uscita [2]: "[+000000027]"

Utilizzo di uno spazio in cui apparirà un segno + con un valore positivo

Uno spazio indica che i numeri positivi dovrebbero mostrare un carattere spazio nel segno
posizione. Ciò è utile per allineare valori positivi e negativi a scopo di visualizzazione:

lecca qui per visualizzare l'immagine del codice

In [3]: print (f ' { 27 : d} \ n { 27 : d} \ n { 27 : d} ' )


27
27
27

Nota che i due numeri con uno spazio nei loro identificatori di formato si allineano. Se la larghezza di un campo
è specificato, lo spazio dovrebbe apparire prima della larghezza del campo.

Cifre di raggruppamento

È possibile formattare i numeri con migliaia di separatori utilizzando una virgola (,) , come
segue:

In [4]: ​f ' { 12345678:, d} '

Uscita [4]: ​'12, 345,678 ' Pagina 314

In [5]: f ' { 123.456,78 :, 0,2 f} '


Uscita [5]: "123,456,78"

8.2.4 Metodo del formato della stringa


Le stringhe di Python sono state aggiunte al linguaggio nella versione 3.6. Prima di allora, la formattazione
è stato eseguito con il formato del metodo stringa . In effetti, la formattazione di fstring è basata su
le capacità del metodo di formattazione. Ti mostriamo il metodo di formattazione qui perché
lo incontrerai nel codice scritto prima di Python 3.6. Vedrai spesso il formato

metodo nella documentazione di Python e nei numerosi libri e articoli di Python


scritto prima dell'introduzione di fstrings. Tuttavia, si consiglia di utilizzare il più recente f
formattazione delle stringhe che abbiamo presentato fino a questo punto.

Chiami il formato del metodo su una stringa di formato contenente segnaposto parentesi graffa ({}) ,
possibilmente con specificatori di formato. Si passano al metodo i valori da formattare. Facciamo
formattare il valore float 17.489 arrotondato alla posizione dei centesimi:

lecca qui per visualizzare l'immagine del codice

In [1]: ' {: .2 f} ' .format ( 17.489 )


Uscita [1]: '17 .49 '

In un segnaposto, se è presente un identificatore di formato, lo fai precedere da due punti (:), come in f

stringhe. Il risultato della chiamata di formattazione è una nuova stringa contenente i risultati formattati.

Segnaposto multipli

Una stringa di formato può contenere più segnaposto, nel qual caso il metodo di formato
gli argomenti corrispondono ai segnaposto da sinistra a destra:
lecca qui per visualizzare l'immagine del codice

In [2]: " {} {} " .format ( "Amanda" , "Cyan" )


Uscita [2]: "Amanda Cyan"

Riferimento agli argomenti per numero di posizione

La stringa di formato può fare riferimento ad argomenti specifici in base alla loro posizione nel formato
elenco degli argomenti del metodo, a partire dalla posizione 0:

C
Pagina 315
lecca qui per visualizzare l'immagine del codice

In [3]: " { 0 } { 0 } { 1 } " .format ( "Happy" , "Birthday" )


Uscita [3]: "Happy Happy Birthday"

Nota che abbiamo usato due volte il numero di posizione 0 ("Happy"): puoi fare riferimento a ciascuno di essi
litigare tutte le volte che vuoi e in qualsiasi ordine.

Riferimento ad argomenti di parole chiave

Puoi fare riferimento agli argomenti delle parole chiave tramite le loro chiavi nei segnaposto:

lecca qui per visualizzare l'immagine del codice

In [4]: " {first} {last} " .format (first = "Amanda" , last = "Gray" )
Uscita [4]: ​"Amanda Gray"

In [5]: " {last} {first} " .format (first = "Amanda" , last = "Gray" )
Uscita [5]: "Grey Amanda"

8.3 CONCATENARE E RIPETERE STRINGHE


Nei capitoli precedenti, abbiamo usato l'operatore + per concatenare le stringhe e l'operatore * per
ripetere le stringhe. È inoltre possibile eseguire queste operazioni con assegnazioni aumentate.
Le stringhe non sono modificabili, quindi ogni operazione assegna un nuovo oggetto stringa alla variabile:

lecca qui per visualizzare l'immagine del codice

In [1]: s1 = "happy"

In [2]: s2 = "compleanno"

In [3]: s1 + = '' + s2

In [4]: ​s1
Uscita [4]: ​"buon compleanno"

In [5]: symbol = '>'

In [6]: simbolo * = 5

In [7]: simbolo
Uscita [7]: ">>>>>"

8C .4 RIMUOVERE LO SPAZIO BIANCO DALLE CORDE


Pagina 316
8.4 RIMOZIONE DI WHITESPACE DALLE STRINGHE
Esistono diversi metodi di stringa per rimuovere gli spazi bianchi dalle estremità di una stringa.
Ciascuno restituisce una nuova stringa lasciando l'originale non modificato. Le stringhe sono immutabili, quindi
ogni metodo che sembra modificare una stringa ne restituisce uno nuovo.

Rimozione di spazi bianchi iniziali e finali

Usiamo la striscia del metodo stringa per rimuovere lo spazio bianco iniziale e finale da un file
corda:

lecca qui per visualizzare l'immagine del codice

In [1]: frase = '\ t \ n Questa è una stringa di prova. \ t \ t \ n '

In [2]: phrase.strip ()
Out [2]: "Questa è una stringa di prova."

Rimozione degli spazi bianchi iniziali

Il metodo lstrip rimuove solo gli spazi bianchi iniziali :

lecca qui per visualizzare l'immagine del codice

In [3]: phrase.lstrip ()
Out [3]: 'Questa è una stringa di prova. \ t \ t \ n '

Rimozione degli spazi vuoti finali


Il metodo rstrip rimuove solo gli spazi vuoti finali:

lecca qui per visualizzare l'immagine del codice

In [4]: ​phrase.rstrip ()
Out [4]: ​"\ t \ n Questa è una stringa di prova."

Come dimostrano gli output, questi metodi rimuovono tutti i tipi di spazi, inclusi
spazi, nuove righe e tabulazioni.

8.5 CAMBIARE CASO CARATTERE


Nei capitoli precedenti, hai usato i metodi delle stringhe lower e upper per convertire le stringhe in all

C
Pagina 317
lettere minuscole o tutte maiuscole. Puoi anche modificare le maiuscole di una stringa con
metodi in maiuscolo e titolo.

Mettere in maiuscolo solo il primo carattere di una stringa

Il metodo capitalize copia la stringa originale e restituisce una nuova stringa con solo l'estensione
prima lettera maiuscola (a volte viene chiamata maiuscola della frase ):

lecca qui per visualizzare l'immagine del codice

In [1]: "buon compleanno". Maiuscola ()


Uscita [1]: "Buon compleanno"

Mettere in maiuscolo il primo carattere di ogni parola in una stringa

Il titolo del metodo copia la stringa originale e restituisce una nuova stringa con solo la prima
carattere di ogni parola in maiuscolo (questo è talvolta chiamato maiuscolo del titolo del libro ):
lecca qui per visualizzare l'immagine del codice

In [2]: 'strings: a deeper look'.title ()


Out [2]: "Strings: A Deeper Look"

8.6 OPERATORI DI CONFRONTO PER STRINGHE


Le stringhe possono essere confrontate con gli operatori di confronto. Ricorda che le stringhe sono
confrontati in base ai valori numerici interi sottostanti. Quindi lettere maiuscole
confrontare come meno delle lettere minuscole perché le lettere maiuscole hanno un numero intero inferiore
valori. Ad esempio, "A" è 65 e "a" è 97. Hai visto che puoi controllare il carattere

codici con ord:

lecca qui per visualizzare l'immagine del codice

In [1]: print (f 'A: {ord ( "A" )}; a: {ord ( "a" )} ' )


A: 65; a: 97

Confrontiamo le stringhe "Orange" e "orange" utilizzando gli operatori di confronto:

lecca qui per visualizzare l'immagine del codice

In [2]: "Orange" == "orange"

Fuori [2]: Falso Pagina 318

In [3]: "Orange" ! = "Orange"


Out [3]: Vero

In [4]: "Orange" < "orange"


Out [4]: ​vero

In [5]: "Orange" <= "orange"


Out [5]: Vero

In [6]: "Orange" > "orange"


Fuori [6]: Falso

In [7]: "Orange" > = "orange"


Fuori [7]: Falso

8.7 RICERCA DI SOTTOSTRINGHE


Puoi cercare in una stringa uno o più caratteri adiacenti, noti come sottostringa ,
per contare il numero di occorrenze, determinare se una stringa contiene una sottostringa,
o determinare l'indice in cui risiede una sottostringa in una stringa. Ogni metodo mostrato in
questa sezione confronta i caratteri lessicograficamente utilizzando il valore numerico sottostante
valori.

Conteggio delle occorrenze

Il conteggio del metodo String restituisce il numero di volte in cui il suo argomento ricorre nella stringa su
quale metodo si chiama:

lecca qui per visualizzare l'immagine del codice

In [1]: frase = "essere o non essere questa è la domanda"

In [2]: phrase.count ( 'to' )


Fuori [2]: 2

Se specifichi come secondo argomento un start_index , count ricerca solo la slice


stringa [ start_index :] - cioè da start_index fino alla fine della stringa:

lecca qui per visualizzare l'immagine del codice

In [3]: phrase.count ( 'to' , 12 )


Fuori [3]: 1

C
Pagina 319
Se specifichi come secondo e terzo argomento start_index e end_index ,
count cerca solo la stringa slice [ start_index : end_index ], ovvero da
start_index fino a, ma escluso, end_index :

lecca qui per visualizzare l'immagine del codice

In [4]: ​phrase.count ( 'that' , 12 , 25 )


Fuori [4]: ​1

Come count, ciascuno degli altri metodi di stringa presentati in questa sezione ha start_index

e end_index argomenti per cercare solo una porzione della stringa originale.

Individuazione di una sottostringa in una stringa

L' indice del metodo String cerca una sottostringa all'interno di una stringa e restituisce la prima
indice in cui si trova la sottostringa; in caso contrario, si verifica un'eccezione ValueError:

lecca qui per visualizzare l'immagine del codice

In [5]: phrase.index ( 'be' )


Fuori [5]: 3

Il metodo String rindex esegue la stessa operazione di index, ma cerca nel file
fine della stringa e restituisce l' ultimo indice in cui si trova la sottostringa; in caso contrario, a

ValueError si verifica:

lecca qui per visualizzare l'immagine del codice

In [6]: phrase.rindex ( 'be' )


Fuori [6]: 16

I metodi String find e rfind eseguono le stesse attività di index e rindex ma, if
la sottostringa non viene trovata, restituisce 1 invece di causare un'eccezione ValueError.

Determinare se una stringa contiene una sottostringa

Se hai bisogno di sapere solo se una stringa contiene una sottostringa, usa l'operatore in o no

nel:

lecca qui per visualizzare l'immagine del codice

C
Pagina 320
In [7]: "quello" nella frase
Out [7]: Vero
In [8]: "QUELLO" nella frase
Fuori [8]: Falso

In [9]: "QUELLO" non nella frase


Out [9]: Vero

Individuazione di una sottostringa all'inizio o alla fine di una stringa


Metodi String StartsWith e endswith ritorno True se la stringa inizia con o

termina con una sottostringa specificata:

lecca qui per visualizzare l'immagine del codice

In [10]: phrase.startswith ( 'to' )


Out [10]: Vero

In [11]: frase.startswith ( 'be' )


Out [11]: Falso

In [12]: frase.endswith ( 'domanda' )


Out [12]: Vero

In [13]: phrase.endswith ( 'quest' )


Out [13]: Falso

8.8 SOSTITUZIONE SOTTOSTRINGHE


Una manipolazione del testo comune consiste nell'individuare una sottostringa e sostituirne il valore. Metodo

sostituire richiede due sottostringhe. Cerca una stringa per la sottostringa nella sua prima
argomento e sostituisce ogni occorrenza con la sottostringa nel secondo argomento. Il
restituisce una nuova stringa contenente i risultati. Sostituiamo i caratteri di tabulazione con
virgole:

lecca qui per visualizzare l'immagine del codice

In [1]: values ​= "1 \ t2 \ t3 \ t4 \ t5"

In [2]: values.replace ( '\ t' , ',' )


Fuori [2]: "1,2,3,4,5"

Il metodo di sostituzione può ricevere un terzo argomento opzionale che specifica il massimo

C
Pagina 321
numero di sostituzioni da eseguire.

8.9 SEPARAZIONE E UNIRE LE STRINGHE


Quando leggi una frase, il tuo cervello la scompone in singole parole, o gettoni, ciascuna
di cui trasmette significato. Interpreti come IPython tokenize statement, breaking
in singoli componenti come parole chiave, identificatori, operatori e altro
elementi di un linguaggio di programmazione. I token in genere sono separati da spazi bianchi
caratteri come vuoto, tabulazione e nuova riga, sebbene possano essere utilizzati altri caratteri: il
i separatori sono noti come delimitatori .

Divisione delle corde

Abbiamo mostrato in precedenza che il metodo delle stringhe split senza argomenti tokenizza una stringa
suddividendolo in sottostringhe ad ogni carattere di spazio, quindi restituisce un elenco di token.
Per tokenizzare una stringa con un delimitatore personalizzato (come ogni coppia virgola e spazio),
specifica la stringa delimitatore (come, ',') che split usa per tokenizzare la stringa:
lecca qui per visualizzare l'immagine del codice

In [1]: lettere = "A, B, C, D"

In [2]: letters.split ( ',' )


Fuori [2]: ['A', 'B', 'C', 'D']

Se fornisci un numero intero come secondo argomento, specifica il numero massimo di


si divide. L'ultimo token è il resto della stringa dopo il numero massimo di divisioni:

lecca qui per visualizzare l'immagine del codice

In [3]: letters.split ( ',' , 2 )


Uscita [3]: ['A', 'B', 'C, D']

Esiste anche un metodo rsplit che esegue la stessa attività di split but process
il numero massimo di divisioni dalla fine della stringa all'inizio.

Unire le stringhe

Il join del metodo String concatena le stringhe nel suo argomento, che deve essere un file
iterabile contenente solo valori stringa; in caso contrario, si verifica un'eccezione TypeError. Il separatore
tra gli elementi concatenati c'è la stringa su cui chiami join. Il seguente

C
Pagina 322
codice crea stringhe contenenti elenchi di valori separati da virgole:

lecca qui per visualizzare l'immagine del codice

In [4]: ​letters_list = [ "A" , "B" , "C" , "D" ]


In [5]: ',' .join (letters_list)
Uscita [5]: "A, B, C, D"

Lo snippet successivo unisce i risultati di una comprensione dell'elenco che crea un elenco di stringhe:

lecca qui per visualizzare l'immagine del codice

In [6]: ',' .join ([str (i) for i in range ( 10 )])


Fuori [6]: "0,1,2,3,4,5,6,7,8,9"

Nel capitolo "File ed eccezioni" vedrai come lavorare con i file che contengono
valori separati da virgola. Questi sono noti come file CSV e sono un formato comune per
memorizzazione dei dati che possono essere caricati da applicazioni per fogli di calcolo come Microsoft Excel o
Fogli Google. Nei capitoli del case study sulla scienza dei dati, vedrai tante chiavi
le librerie, come NumPy, Pandas e Seaborn, forniscono funzionalità integrate per lavorare
con dati CSV.

String Methods partition e rpartition

La partizione del metodo String divide una stringa in una tupla di tre stringhe basata su
argomento separatore del metodo . Le tre corde sono

la parte della stringa originale prima del separatore,

il separatore stesso e

la parte della stringa dopo il separatore.


Questo potrebbe essere utile per dividere stringhe più complesse. Considera una stringa che rappresenta
il nome e i voti di uno studente:

"Amanda: 89, 97, 92"

Dividiamo la stringa originale nel nome dello studente, nel separatore ":" e in una stringa

che rappresenta l'elenco dei voti:

C
Pagina 323
lecca qui per visualizzare l'immagine del codice

In [7]: 'Amanda: 89, 97, 92' .partition ( ':' )


Out [7]: ('Amanda', ':', '89, 97, 92 ')

Per cercare invece il separatore dalla fine della stringa, usa il metodo

rpartizione da dividere. Ad esempio, considera la seguente stringa URL:

' ttp: //www.deitel.com/books/PyCDS/table_of_contents.html "

Usiamo rpartition split "table_of_contents.html" dal resto dell'URL:

lecca qui per visualizzare l'immagine del codice

In [8]: url = "http://www.deitel.com/books/PyCDS/table_of_contents.html"

In [9]: rest_of_url, separator, document = url.rpartition ( '/' )

In [10]: document
Uscita [10]: "table_of_contents.html"

In [11]: rest_of_url
Uscita [11]: "http://www.deitel.com/books/PyCDS"

Linee di divisione del metodo stringa

Nel capitolo "File ed eccezioni" leggerai il testo da un file. Se leggi in grande


quantità di testo in una stringa, potresti voler dividere la stringa in un elenco di righe basato
sui caratteri di nuova riga. Il metodo splitlines restituisce un elenco di nuove stringhe che rappresentano
le righe di testo si dividono in corrispondenza di ogni carattere di nuova riga nella stringa originale. Ricorda quel Python
memorizza stringhe multilinea con caratteri \ n incorporati per rappresentare le interruzioni di riga, come
mostrato nello snippet [13]:

lecca qui per visualizzare l'immagine del codice

In [12]: lines = "" "Questa è la riga 1


...: Questa è la riga 2
...: questa è la riga 3 "" "

In [13]: righe
Out [13]: "Questa è la riga 1 \ nQuesta è la riga2 \ nQuesta è la riga3"

C
h

In [14]: lines.splitlines () Pagina 324


Out [14]: ["This is line 1", "This is line2", "This is line3"]
Passando True a splitlines mantiene i newline alla fine di ogni stringa:

lecca qui per visualizzare l'immagine del codice

In [15]: lines.splitlines ( True )


Out [15]: ["Questa è la riga 1 \ n", "Questa è la riga 2 \ n", "Questa è la riga 3"]

8.10 CARATTERI E TEST SUI CARATTERI


METODI
Molti linguaggi di programmazione hanno tipi di stringhe e caratteri separati. In Python, a
è semplicemente una stringa di un carattere.

Python fornisce metodi di stringa per verificare se una stringa corrisponde a determinati
caratteristiche. Ad esempio, il metodo stringa isdigit restituisce True se la stringa è attiva

che chiamate il metodo contiene solo i caratteri numerici (0–9). Potresti usare questo
durante la convalida dell'input dell'utente che deve contenere solo cifre:

lecca qui per visualizzare l'immagine del codice

In [1]: "27" .isdigit ()


Fuori [1]: Falso

In [2]: "27" .isdigit ()


Out [2]: vero

e il metodo stringa isalnum restituisce True se la stringa su cui si chiama il


metodo è alfanumerico, ovvero contiene solo cifre e lettere:

lecca qui per visualizzare l'immagine del codice

In [3]: 'A9876' .isalnum ()


Out [3]: Vero

In [4]: "123 Main Street" .isalnum ()


Fuori [4]: ​Falso

La tabella seguente mostra molti dei metodi di test dei caratteri. Ogni metodo restituisce

C
Pagina 325
anche se la condizione descritta non è soddisfatta:

Metodo String Descrizione

Restituisce True se la stringa contiene solo caratteri alfanumerici


isalnum ()
caratteri (cioè cifre e lettere).

Restituisce True se la stringa contiene solo caratteri alfabetici


isalpha ()
caratteri (cioè lettere).

Restituisce True se la stringa contiene solo un numero intero decimale


isdecimal () caratteri (ovvero, numeri interi in base 10) e non lo fa
contenere un segno + o.

Restituisce True se la stringa contiene solo cifre (ad es. "0",


isdigit ()
"1", "2").

isidentifier () Restituisce True se la stringa rappresenta un identificatore valido .

Restituisce True se tutti i caratteri alfabetici nella stringa lo sono


è più basso()
caratteri minuscoli (ad esempio, "a", "b", "c").

Restituisce True se i caratteri nella stringa rappresentano un

isnumeric () valore numerico senza segno + o e senza segno


punto decimale.

Restituisce True se la stringa contiene solo spazi


isspace ()
personaggi.

F
Pagina 326
Restituisce True se il primo carattere di ogni parola nel file
istitle () stringa è l'unico carattere maiuscolo nella parola.

Restituisce True se tutti i caratteri alfabetici nella stringa lo sono


isupper ()
caratteri maiuscoli (ad es. "A", "B", "C").

8.11 STRINGHE GREZZE


Ricorda che i caratteri backslash nelle stringhe introducono sequenze di escape, come \ n per
nuova riga e \ t per la tabulazione. Quindi, se desideri includere una barra rovesciata in una stringa, devi usare
due caratteri backslash \\. Ciò rende difficile leggere alcune stringhe. Per esempio,
Microsoft Windows utilizza le barre rovesciate per separare i nomi delle cartelle quando si specifica un file
Posizione. Per rappresentare la posizione di un file su Windows, potresti scrivere:

lecca qui per visualizzare l'immagine del codice

In [1]: file_path = "C: \\ MyFolder \\ MySubFolder \\ MyFile.txt"

In [2]: file_path
Uscita [2]: "C: \\ MyFolder \\ MySubFolder \\ MyFile.txt"

In questi casi, le stringhe grezze , precedute dal carattere r, sono più convenienti. Essi

considera ogni barra rovesciata come un carattere normale, piuttosto che l'inizio di una fuga
sequenza:

lecca qui per visualizzare l'immagine del codice


In [3]: file_path = r "C: \ MyFolder \ MySubFolder \ MyFile.txt"

In [4]: ​file_path
Uscita [4]: ​"C: \\ MyFolder \\ MySubFolder \\ MyFile.txt"

Python converte la stringa grezza in una stringa normale che utilizza ancora le due barre rovesciate
caratteri nella sua rappresentazione interna, come mostrato nell'ultimo frammento. Le corde grezze possono
rendi il tuo codice più leggibile, in particolare quando usi le espressioni regolari che noi
discuti nella sezione successiva. Le espressioni regolari spesso contengono molte barre rovesciate
personaggi.

8C .12 INTRODUZIONE ALLE ESPRESSIONI REGOLARI


Pagina 327
.12 INTRODUZIONE ALLE ESPRESSIONI REGOLARI
A volte dovrai riconoscere schemi nel testo, come numeri di telefono, e-mail
indirizzi, codici postali, indirizzi di pagine web, numeri di previdenza sociale e altro ancora. UN
stringa di espressione regolare descrive un modello di ricerca per la corrispondenza dei caratteri in
altre corde.

Le espressioni regolari possono aiutarti a estrarre dati da testo non strutturato, come social
post sui media. Sono anche importanti per garantire che i dati siano nel formato corretto
3
prima di tentare di elaborarlo.

3
L'argomento delle espressioni regolari potrebbe sembrare più impegnativo rispetto alla maggior parte degli altri Python
funzioni che hai utilizzato. Dopo aver imparato questo argomento, scriverai spesso codice più conciso
rispetto alle tradizionali tecniche di elaborazione delle stringhe, accelerando lo sviluppo del codice
processi. Ti occuperai anche di casi marginali a cui potresti non pensare normalmente, forse
evitando insetti sottili.

Convalida dei dati

Prima di lavorare con i dati di testo, userete spesso espressioni regolari per convalidare i dati .
Ad esempio, puoi verificare che:

Un codice postale degli Stati Uniti è composto da cinque cifre (come 02215) o cinque cifre seguite da a
trattino e altre quattro cifre (ad esempio 022154775).

Un cognome stringa contiene solo lettere, spazi, apostrofi e trattini.

Un indirizzo e-mail contiene solo i caratteri consentiti nell'ordine consentito.

Un numero di previdenza sociale statunitense contiene tre cifre, un trattino, due cifre, un trattino
e quattro cifre e aderisce ad altre regole sui numeri specifici che possono essere
utilizzato in ogni gruppo di cifre.

Raramente avrai bisogno di creare le tue espressioni regolari per elementi comuni come questi.
Siti web come

ttps: //regex101.com

ttp: //www.regexlib.com

ttps: //www.regularexpressions.info

8h
Pagina 328
e altri offrono archivi di espressioni regolari esistenti che puoi copiare e utilizzare.
Molti siti come questi forniscono anche interfacce in cui è possibile testare espressioni regolari
per determinare se soddisferanno le tue esigenze.

Altri usi delle espressioni regolari

Oltre a convalidare i dati, le espressioni regolari vengono spesso utilizzate per:

Estrarre i dati dal testo (a volte noto come scraping ), ad esempio, individuare tutto
URL in una pagina web. [Potresti preferire strumenti come BeautifulSoup, XPath e lxml.]

Pulizia dei dati: ad esempio, rimozione dei dati non necessari, rimozione dei duplicati
dati, gestione di dati incompleti, correzione di errori di battitura, garanzia di formati di dati coerenti,
trattare con valori anomali e altro ancora.

Trasforma i dati in altri formati, ad esempio riformattando i dati che erano


raccolti come valori separati da tabulazioni o spazi separati in valori separati da virgole
(CSV) per un'applicazione che richiede che i dati siano in formato CSV.

8.12.1 re Modulo e funzione fullmatch


Per usare le espressioni regolari, importa il modulo re della Python Standard Library :

In [1]: import re

Una delle più semplici funzioni delle espressioni regolari è fullmatch , che controlla se
l' intera stringa nel secondo argomento corrisponde al modello nel primo argomento.

Caratteri letterali corrispondenti

Cominciamo con la corrispondenza dei caratteri letterali , ovvero i caratteri che corrispondono a se stessi:

lecca qui per visualizzare l'immagine del codice

In [2]: pattern = "02215"

In [3]: "Match" se re.fullmatch (pattern, "02215" ) altrimenti "No match"


Out [3]: "Match"

In [4]: "Match" se re.fullmatch (pattern, "51220" ) altrimenti "Nessuna corrispondenza"


Uscita [4]: ​"Nessuna corrispondenza"

C
Pagina 329
Il primo argomento della funzione è il modello di espressione regolare da trovare. Qualsiasi stringa può
essere un'espressione regolare. Il valore del modello di variabile, "02215", contiene solo valori letterali

cifre che corrispondono a se stesse nell'ordine specificato. Il secondo argomento è la stringa


che dovrebbe corrispondere interamente al modello.

Se il secondo argomento corrisponde al modello nel primo argomento, fullmatch restituisce

un oggetto contenente il testo corrispondente, che restituisce True. Diremo di più su


questo oggetto più tardi. Nello snippet [4], anche se il secondo argomento contiene lo stesso
cifre come espressione regolare, sono in un ordine diverso . Quindi non c'è corrispondenza, e

fullmatch restituisce None, che restituisce False.

Metacaratteri, classi di caratteri e quantificatori

Le espressioni regolari contengono tipicamente vari simboli speciali chiamati metacaratteri ,


che sono mostrati nella tabella seguente:
Metacaratteri delle espressioni regolari

[] {} () \ * + ^ $? . |

Il \ metacharacter inizia ciascuna delle classi di caratteri predefinite , ciascuna

corrispondenza di un insieme specifico di caratteri. Convalidiamo un CAP di cinque cifre:

lecca qui per visualizzare l'immagine del codice

In [5]: "Valid" if re.fullmatch (r '\ d {5}' , '02215' ) else "Nonvalid"


Out [5]: "Valid"

In [6]: 'Valid' if re.fullmatch (r '\ d {5}' , '9876' ) else 'Nonvalid'


Uscita [6]: "Non valido"

Nell'espressione regolare \ d {5}, \ d è una classe di caratteri che rappresenta una cifra (0–9). UN
la classe di caratteri è una sequenza di escape di espressioni regolari che corrisponde a un carattere. Per
corrisponde a più di uno, segui la classe di caratteri con un quantificatore . Il quantificatore {5}
ripete \ d cinque volte, come se avessimo scritto \ d \ d \ d \ d \ d, in modo che corrisponda a cinque volte consecutive
cifre. Nello snippet [6], fullmatch restituisce Nessuno perché "9876" ne contiene solo quattro

caratteri di cifre consecutive.

O
C altre classi di caratteri predefinite

Altre classi di caratteri predefinite Pagina 330

La tabella seguente mostra alcune classi di caratteri predefinite comuni e i gruppi di


caratteri che corrispondono. Per far corrispondere qualsiasi metacarattere come valore letterale , farlo precedere da a
barra rovesciata (\). Ad esempio, \\ corrisponde a una barra rovesciata (\) e \ $ corrisponde a un segno di dollaro

($).

Carattere
Partite
classe

\d Qualsiasi cifra (0–9).

\D Qualsiasi carattere che non sia una cifra.

\S Qualsiasi carattere di spazio (come spazi, tabulazioni e nuove righe).

\S Qualsiasi carattere che non sia uno spazio vuoto.

Qualsiasi carattere alfanumerico (chiamato anche alfanumerico


\w carattere ): qualsiasi lettera maiuscola o minuscola, qualsiasi cifra
o un trattino basso

\W Qualsiasi carattere che non sia un carattere di parola.


Classi di caratteri personalizzati

Le parentesi quadre, [], definiscono una classe di caratteri personalizzata che corrisponde a un singolo

carattere. Ad esempio, [aeiou] corrisponde a una vocale minuscola, [AZ] corrisponde a una
lettera maiuscola, [az] corrisponde a una lettera minuscola e [azAZ] corrisponde a qualsiasi

lettera minuscola o maiuscola.

Pagina 331
Convalidiamo un semplice nome senza spazi o punteggiatura. Faremo in modo che sia così
inizia con una lettera maiuscola (A – Z) seguita da un numero qualsiasi di lettere minuscole
(a – z):

lecca qui per visualizzare l'immagine del codice

In [7]: "Valid" se re.fullmatch ( "[AZ] [az] *" , "Wally" ) altrimenti "Non valido"
Uscita [7]: "Valido"

In [8]: "Valid" if re.fullmatch ( "[AZ] [az] *" , "eva" ) else "Nonvalid"


Fuori [8]: "Non valido"

Un nome potrebbe contenere molte lettere. Il quantificatore * corrisponde a zero o più


occorrenze della sottoespressione alla sua sinistra (in questo caso, [az]). Quindi [AZ] [az] *

corrisponde a una lettera maiuscola seguita da zero o più lettere minuscole, come
"Amanda", "Bo" o anche "E".

Quando una classe di caratteri personalizzata inizia con un accento circonflesso (^) , la classe corrisponde a qualsiasi carattere
che è non è specificato. Quindi [^ az] corrisponde a qualsiasi carattere che non sia una lettera minuscola:

lecca qui per visualizzare l'immagine del codice

In [9]: "Match" se re.fullmatch ( "[^ az]" , "A" ) altrimenti "Nessuna corrispondenza"


Fuori [9]: "Match"

In [10]: "Match" se re.fullmatch ( "[^ az]" , "a" ) altrimenti "Nessuna corrispondenza"


Uscita [10]: "Nessuna corrispondenza"

I metacaratteri in una classe di caratteri personalizzata vengono trattati come caratteri letterali, ovvero i caratteri
personaggi stessi. Quindi [* + $] corrisponde a un singolo carattere *, + o $:

lecca qui per visualizzare l'immagine del codice

In [11]: "Match" se re.fullmatch ( "[* + $]" , "*" ) altrimenti "Nessuna corrispondenza"


Fuori [11]: "Match"

In [12]: "Match" se re.fullmatch ( "[* + $]" , "!" ) Altrimenti "Nessuna corrispondenza"


Uscita [12]: "Nessuna corrispondenza"

* rispetto a + Quantifier

Se vuoi richiedere almeno una lettera minuscola nel nome, puoi sostituire *

C
Pagina 332
quantificatore nello snippet [7] con + , che corrisponde ad almeno un'occorrenza di a

sottoespressione:
lecca qui per visualizzare l'immagine del codice

In [13]: "Valid" if re.fullmatch ( "[AZ] [az] +" , "Wally" ) else "Nonvalid"


Out [13]: "Valid"

In [14]: "Valid" if re.fullmatch ( "[AZ] [az] +" , "E" ) else "Nonvalid"


Uscita [14]: "Non valido"

Sia * che + sono avidi: corrispondono al maggior numero di caratteri possibile. Quindi il normale
espressione [AZ] [az] + corrisponde a "Al", "Eva", "Samantha", "Benjamin" e qualsiasi

altre parole che iniziano con una lettera maiuscola seguite almeno una lettera minuscola.

Altri quantificatori
Il ? quantificatore corrisponde a zero o una occorrenza di una sottoespressione:

lecca qui per visualizzare l'immagine del codice

In [15]: 'Match' if re.fullmatch ( ' labell ? Ed' , 'labeled' ) else 'No match'
Out [15]: "Match"

In [16]: 'Match' if re.fullmatch ( ' labell ? Ed' , 'labeled' ) else 'No match'
Fuori [16]: "Match"

In [17]: 'Match' if re.fullmatch ( ' labell ? Ed' , 'labellled' ) else 'No matc'
ut [17]: "Nessuna corrispondenza"

L'espressione regolare labell? Ed corrisponde a labeled (ortografia inglese britannico) e

etichettato (l'ortografia inglese degli Stati Uniti), ma non la parola errata etichettata. In ciascuna
snippet sopra, i primi cinque caratteri letterali nell'espressione regolare (etichetta) corrispondono
i primi cinque caratteri dei secondi argomenti. Allora io? indica che ci possono essere

zero o uno in più l caratteri prima dei restanti caratteri letterali ed.

Puoi abbinare almeno n occorrenze di una sottoespressione con il quantificatore { n ,} .


La seguente espressione regolare corrisponde a stringhe contenenti almeno tre cifre:

lecca qui per visualizzare l'immagine del codice

C
O

Pagina 333
In [18]: "Match" se re.fullmatch (r '\ d {3,}' , '123' ) altrimenti "Nessuna corrispondenza"
Fuori [18]: "Match"

In [19]: "Match" if re.fullmatch (r '\ d {3,} " , " 1234567890 " ) altrimenti " Nessuna corrispondenza
ut [19]: "Match"

In [20]: "Match" se re.fullmatch (r '\ d {3,}' , '12' ) altrimenti "Nessuna corrispondenza"


Out [20]: "Nessuna corrispondenza"

È possibile trovare una corrispondenza tra n e m (incluse) occorrenze di una sottoespressione con

{ n , m } quantificatore . La seguente espressione regolare corrisponde a stringhe contenenti da 3 a


6 cifre:

lecca qui per visualizzare l'immagine del codice

In [21]: 'Match' if re.fullmatch (r '\ d {3,6}' , '123' ) else 'No match'


Fuori [21]: "Match"

In [22]: 'Match' if re.fullmatch (r '\ d {3,6}' , '123456' ) else 'No match'


Fuori [22]: "Match"

In [23]: "Match" if re.fullmatch (r '\ d {3,6} " , " 1234567 " ) altrimenti " Nessuna corrispondenza "
Uscita [23]: "Nessuna corrispondenza"

In [24]: 'Match' se re.fullmatch (r '\ d {3,6}' , '12' ) altrimenti 'Nessuna corrispondenza'


Out [24]: "Nessuna corrispondenza"

8.12.2 Sostituzione di sottostringhe e suddivisione di stringhe


Il modulo re fornisce la funzione sub per sostituire i pattern in una stringa e function

split per rompere una stringa in pezzi, in base a modelli.

Funzione sub - Sostituzione di modelli

Per impostazione predefinita, la funzione secondaria del modulo re sostituisce tutte le occorrenze di un pattern con
il testo sostitutivo specificato. Convertiamo una stringa delimitata da tabulazione in virgola
delimitato:

lecca qui per visualizzare l'immagine del codice

In [1]: import re

In [2]: re.sub (r '\ t' , ',' , '1 \ t2 \ t3 \ t4' )

C
O

Uscita [2]: "1, 2, 3, 4" Pagina 334

La funzione sub riceve tre argomenti obbligatori:

il modello da abbinare (il carattere di tabulazione '\ t')

il testo sostitutivo (',') e

la stringa da cercare ('1 \ t2 \ t3 \ t4')

e restituisce una nuova stringa. Il conteggio dell'argomento della parola chiave può essere utilizzato per specificare il file
numero massimo di sostituzioni:

lecca qui per visualizzare l'immagine del codice

In [3]: re.sub (r '\ t' , ',' , '1 \ t2 \ t3 \ t4' , count = 2 )


Uscita [3]: "1, 2, 3 \ t4"

Funzione split

La funzione split tokenizza una stringa, utilizzando un'espressione regolare per specificare il file
delimitatore e restituisce un elenco di stringhe. Tokenizziamo una stringa dividendola in qualsiasi
virgola seguita da 0 o più spazi vuoti: \ s è lo spazio bianco
classe di caratteri e * indica zero o più occorrenze del precedente
sottoespressione:

lecca qui per visualizzare l'immagine del codice

In [4]: ​re.split (r ', \ s *' , '1, 2, 3,4, 5,6,7,8' )


Fuori [4]: ​["1", "2", "3", "4", "5", "6", "7", "8"]
Utilizza l'argomento della parola chiave maxsplit per specificare il numero massimo di divisioni:

lecca qui per visualizzare l'immagine del codice

In [5]: re.split (r ', \ s *' , '1, 2, 3,4, 5,6,7,8' , maxsplit = 3 )


Uscita [5]: ['1', '2', '3', '4, 5,6,7,8']

In questo caso, dopo le 3 divisioni, la quarta stringa contiene il resto della stringa originale.

8C .12.3 Altre funzioni di ricerca; Accesso alle partite

8.12.3 Altre funzioni di ricerca; Accesso alle partite Pagina 335

In precedenza abbiamo utilizzato la funzione fullmatch per determinare se un'intera stringa


corrispondeva a un'espressione regolare. Ci sono molte altre funzioni di ricerca. Qui noi
discutere le funzioni cerca, abbina, trova tutto e trova e mostra come farlo
accedere alle sottostringhe corrispondenti.

Ricerca di funzioni: trovare la prima corrispondenza ovunque in una stringa

La ricerca di funzione cerca in una stringa la prima occorrenza di una sottostringa che corrisponde a un file

espressione regolare e restituisce un oggetto match (di tipo SRE_Match ) che contiene l' estensione
sottostringa corrispondente. Il metodo group dell'oggetto match restituisce quella sottostringa:

lecca qui per visualizzare l'immagine del codice

In [1]: import re

In [2]: result = re.search ( 'Python' , 'Python is fun' )

In [3]: result.group () if result else 'not found'


Uscita [3]: "Python"

La ricerca della funzione restituisce Nessuno se la stringa non contiene il modello:

lecca qui per visualizzare l'immagine del codice

In [4]: ​result2 = re.search ( 'fun!' , 'Python is fun' )

In [5]: result2.group () if result2 else 'not found'


Out [5]: "non trovato"

Puoi cercare una corrispondenza solo all'inizio di una stringa con corrispondenza di funzione .

Ignorare maiuscole e minuscole con i flag facoltativi Argomento parola chiave

Molte funzioni del modulo re ricevono un argomento di parola chiave flag opzionale che cambia
come vengono abbinate le espressioni regolari. Ad esempio, le corrispondenze distinguono tra maiuscole e minuscole da
predefinito, ma utilizzando la costante IGNORECASE del modulo re, è possibile eseguire un caso
ricerca insensibile :

lecca qui per visualizzare l'immagine del codice

In [6]: result3 = re.search ( 'Sam' , 'SAM WHITE' , flags = re.IGNORECASE )

C
Pagina 336
In [7]: result3.group () if result3 else 'not found'
Uscita [7]: "SAM"

Qui, "SAM" corrisponde al modello "Sam" perché entrambi hanno anche le stesse lettere
sebbene "SAM" contenga solo lettere maiuscole.

Metacaratteri che limitano le corrispondenze all'inizio o alla fine di una stringa

Il metacarattere ^ all'inizio di un'espressione regolare (e non all'interno di square

parentesi) è un'ancora che indica che l'espressione corrisponde solo all'inizio di a


corda:

lecca qui per visualizzare l'immagine del codice

In [8]: result = re.search ( '^ Python' , 'Python is fun' )

In [9]: result.group () if result else 'not found'


Uscita [9]: "Python"

In [10]: result = re.search ( '^ fun' , 'Python is fun' )

In [11]: result.group () if result else 'not found'


Out [11]: "non trovato"

Allo stesso modo, il metacarattere $ alla fine di un'espressione regolare è un'ancora

indicando che l'espressione corrisponde solo alla fine di una stringa:

lecca qui per visualizzare l'immagine del codice

In [12]: result = re.search ( 'Python $' , 'Python is fun' )

In [13]: result.group () if result else 'not found'


Out [13]: "non trovato"

In [14]: result = re.search ( 'fun $' , 'Python is fun' )

In [15]: result.group () if result else 'not found'


Out [15]: "fun"

Funzione findall e finditer: ricerca di tutte le corrispondenze in una stringa

La funzione findall trova ogni sottostringa corrispondente in una stringa e restituisce un elenco di
sottostringhe corrispondenti. Estraiamo tutti i numeri di telefono degli Stati Uniti da una stringa. Per
semplicità supporremo che i numeri di telefono degli Stati Uniti abbiano il formato ##########:

C
Pagina 337
lecca qui per visualizzare l'immagine del codice

In [16]: contact = "Wally White, Home: 5555551234, Work: 5555554321"

In [17]: re.findall (r '\ d {3} \ d {3} \ d {4}' , contact)


Uscita [17]: ["5555551234", "5555554321"]

La funzione finditer funziona come findall, ma restituisce un iterabile pigro di oggetti match.
Per un gran numero di corrispondenze, l'uso di finditer può far risparmiare memoria perché ritorna
una corrispondenza alla volta, mentre findall restituisce tutte le corrispondenze contemporaneamente:

lecca qui per visualizzare l'immagine del codice

In [18]: per telefono in re.finditer (r '\ d {3} \ d {3} \ d {4}' , contatto):


...: print (phone.group ())
...:
5555551234
5555554321

Acquisizione di sottostringhe in una corrispondenza

Puoi usare i metacaratteri delle parentesi - ( e ) - per catturare sottostringhe in un file


incontro. Ad esempio, acquisiamo come sottostringhe separate il nome e l'indirizzo e-mail
nella stringa di testo:

lecca qui per visualizzare l'immagine del codice

In [19]: text = "Charlie Cyan, email: demo1@deitel.com"

In [20]: pattern = r '([AZ] [az] + [AZ] [az] +), email: (\ w + @ \ w + \. \ W {3})

n [21]: risultato = re.search (pattern, text)

L'espressione regolare specifica due sottostringhe da acquisire, ciascuna indicata con


metacaratteri (e). Questi metacaratteri non influenzano se il pattern è
trovato nella stringa di testo: la funzione match restituisce un oggetto match solo se intero

pattern si trova nella stringa di testo.

Consideriamo l'espressione regolare:

'([AZ] [az] + [AZ] [az] +)' corrisponde a due parole separate da uno spazio. Ogni

C
io

Pagina 338
la parola deve avere una lettera maiuscola iniziale.

", email:" contiene caratteri letterali che corrispondono a se stessi.

(\ w + @ \ w + \. \ w {3}) corrisponde a un semplice indirizzo email composto da uno o più


caratteri alfanumerici (\ w +), il carattere @, uno o più caratteri alfanumerici
caratteri (\ w +), un punto (\.) e tre caratteri alfanumerici (\ w {3}). Noi

ha preceduto il punto con \ perché un punto (.) è un metacarattere di un'espressione regolare che
corrisponde a un carattere.

Il metodo groups dell'oggetto match restituisce una tupla delle sottostringhe catturate:

lecca qui per visualizzare l'immagine del codice

In [22]: result.groups ()
Uscita [22]: ('Charlie Cyan', 'demo1@deitel.com')

Il metodo di gruppo dell'oggetto match restituisce l' intera corrispondenza come una singola stringa:

lecca qui per visualizzare l'immagine del codice

In [23]: result.group ()
Uscita [23]: "Charlie Cyan, email: demo1@deitel.com"

È possibile accedere a ciascuna sottostringa acquisita passando un numero intero al metodo group.
Le sottostringhe catturate sono numerate da 1 (a differenza degli indici di lista, che iniziano da 0):

lecca qui per visualizzare l'immagine del codice


In [24]: result.group ( 1 )
Uscita [24]: "Charlie Cyan"

In [25]: result.group ( 2 )
Uscita [25]: "demo1@deitel.com"

8.13 INTRO A DATA SCIENCE: PANDAS, REGULAR


ESPRESSIONI E MUNGING DEI DATI
I dati non sempre arrivano in forme pronte per l'analisi. Potrebbe, ad esempio, essere in
formato sbagliato, errato o addirittura mancante. L'esperienza nel settore ha dimostrato che i dati

C
Pagina 339
i cientisti possono dedicare fino al 75% del loro tempo alla preparazione dei dati prima di iniziare
studi. La preparazione dei dati per l'analisi è chiamata data munging o data wrangling .
Questi sono sinonimi: da questo punto in avanti diremo mungitura dei dati.

Due dei passaggi più importanti nel munging dei dati sono la pulizia e la trasformazione dei dati
dati nei formati ottimali per i vostri sistemi di database e software di analisi. Alcuni
esempi comuni di pulizia dei dati sono:

eliminare le osservazioni con valori mancanti,

sostituire valori ragionevoli con valori mancanti,

eliminare le osservazioni con valori errati,

sostituire valori ragionevoli con valori errati,

lanciare valori anomali (anche se a volte vorrai mantenerli),

eliminazione dei duplicati (anche se a volte i duplicati sono validi),

trattare con dati incoerenti,

e altro ancora.

Probabilmente stai già pensando che la pulizia dei dati sia un processo difficile e disordinato
dove potresti facilmente prendere decisioni sbagliate che avrebbero un impatto negativo sui tuoi risultati.
Questo è corretto. Quando arriverai ai casi di studio sulla scienza dei dati nei capitoli successivi, lo farai
vedere che la scienza dei dati è più una scienza empirica , come la medicina, e meno una scienza
scienza teorica, come la fisica teorica. Le scienze empiriche basano le loro conclusioni
su osservazioni ed esperienze. Ad esempio, molti farmaci che risolvono efficacemente
problemi medici odierni sono stati sviluppati osservando gli effetti che le prime versioni di
questi farmaci erano su animali da laboratorio e, infine, sugli esseri umani, e si raffinavano gradualmente
ingredienti e dosaggi. Le azioni intraprese dai data scientist possono variare a seconda del progetto
sulla qualità e la natura dei dati ed essere influenzato dall'evoluzione dell'organizzazione e
standard professionali.

Alcune trasformazioni di dati comuni includono:

rimozione di dati e funzionalità non necessari (diremo di più sulle funzionalità nel file data
studi di casi scientifici),

S
Pagina 340
combinando caratteristiche correlate,
campionamento dei dati per ottenere un sottoinsieme rappresentativo (vedremo nel caso della scienza dei dati
studi che il campionamento casuale è particolarmente efficace per questo e diremo perché),

standardizzare i formati dei dati,

dati di raggruppamento,

e altro ancora.

È sempre consigliabile conservare i dati originali. Mostreremo semplici esempi di pulizia


e trasformare i dati nel contesto di Pandas Series e DataFrames.

Pulizia dei dati

Valori di dati errati e valori mancanti possono avere un impatto significativo sull'analisi dei dati. Alcuni dati
gli scienziati sconsigliano qualsiasi tentativo di inserire "valori ragionevoli". Invece, loro
sostengono di contrassegnare chiaramente i dati mancanti e lasciare che sia compito del pacchetto di analisi dei dati
4
gestire il problema. Altri offrono forti cautele.

4
Questa nota a piè di pagina è stata estratta da un commento inviatoci il 20 luglio 2018 da uno dei
revisori di libri, il dottor Alison Sanchez della University of San Diego School of Business.
Ha commentato: essere cauti quando si parla di "sostituzione di valori ragionevoli" per
valori mancanti o cattivi. Un severo avvertimento: "sostituire" valori che aumentano le statistiche
importanza o fornire risultati più "ragionevoli" o "migliori" non è consentito. 'Sostituzione'
i dati non dovrebbero trasformarsi in dati "fudging". La prima regola che i lettori dovrebbero imparare è di non farlo
eliminare o modificare i valori che contraddicono le loro ipotesi. 'Sostituzione ragionevole
valori 'non significa che i lettori dovrebbero sentirsi liberi di cambiare i valori per ottenere i risultati che vogliono
voglio.

Consideriamo un ospedale che registra le temperature dei pazienti (e probabilmente altri vitali
segni) quattro volte al giorno. Supponiamo che i dati siano costituiti da un nome e quattro float
valori, come

[ "Brown, Sue" , 98.6 , 98.4 , 98.7 , 0.0 ]

Le prime tre temperature registrate del paziente precedente sono 99,7, 98,4 e 98,7. Il
l'ultima temperatura era mancante e registrata come 0.0, forse perché il sensore
mal funzionante. La media dei primi tre valori è 98,57, che è quasi normale.

Pagina 341
Tuttavia, se si calcola la temperatura media compreso il valore mancante per
cui 0,0 è stato sostituito, la media è solo 73,93, risultato chiaramente discutibile.
Certamente, i medici non vorrebbero intraprendere azioni correttive drastiche su questo paziente - lo è
fondamentale per "ottenere i dati corretti".

Un modo comune per pulire i dati è sostituire un valore ragionevole per i dati mancanti
temperatura, come la media delle altre letture del paziente. Se l'avessimo fatto
sopra, la temperatura media del paziente rimarrebbe 98,57, molto più probabile
temperatura media, in base alle altre letture.

Convalida dei dati

Cominciamo creando una serie di codici postali a cinque cifre da un dizionario di città
nome / fivedigitZIPCode coppie chiave-valore. Abbiamo inserito intenzionalmente un ZIP non valido
Codice per Miami:
lecca qui per visualizzare l'immagine del codice

In [1]: importa i panda come pd

In [2]: zips = pd.Series ({ 'Boston' : '02215' , 'Miami' : '3310' })

In [3]: zip
Fuori [3]:
Boston 02215
Miami 3310
dtype: oggetto

Sebbene le cerniere sembrino un array bidimensionale, in realtà è unidimensionale. Il


"Seconda colonna" rappresenta i valori del codice postale della serie (dal dizionario
valori) e la "prima colonna" rappresenta i loro indici (dalle chiavi del dizionario).

Possiamo usare espressioni regolari con Panda per convalidare i dati. L' attributo str di a

Series fornisce l'elaborazione delle stringhe e vari metodi di espressione regolare. Usiamo
il metodo di corrispondenza dell'attributo str per verificare se ogni CAP è valido:

lecca qui per visualizzare l'immagine del codice

In [4]: ​zips.str.match (r '\ d {5}' )


Fuori [4]:
Boston True
Miami False
dtype: bool

C
Pagina 342
La corrispondenza del metodo applica l'espressione regolare \ d {5} a ogni elemento della serie,

cercando di garantire che l'elemento sia composto esattamente da cinque cifre. Non
bisogno di scorrere in modo esplicito tutti i codici postali: match lo fa per te. Questo è

un altro esempio di programmazione in stile funzionale con interni piuttosto che esterni
iterazione. Il metodo restituisce una nuova serie contenente True per ogni elemento valido.
In questo caso, il codice postale di Miami non corrisponde, quindi il suo elemento è False.

Esistono diversi modi per gestire i dati non validi. Uno è catturarlo alla fonte e
interagire con la sorgente per correggere il valore. Non è sempre possibile. Per esempio,
i dati potrebbero provenire da sensori ad alta velocità nell'Internet of Things. In ciò
caso, non saremmo in grado di correggerlo alla fonte, quindi potremmo applicare la pulizia dei dati
tecniche. Nel caso del cattivo codice postale di Miami di 3310, potremmo cercare Miami
Codici postali che iniziano con 3310. Ce ne sono due, 33101 e 33109, e potremmo scegliere

uno di quelli.

A volte, piuttosto che abbinare un intero valore a un modello, vorrai sapere


se un valore contiene una sottostringa che corrisponde al modello. In questo caso, usa il metodo

contiene invece di match. Creiamo una serie di stringhe, ciascuna contenente un US


città, stato e CAP, quindi determina se ogni stringa contiene una sottostringa
corrispondente al modello "[AZ] {2}" (uno spazio, seguito da due lettere maiuscole,
seguito da uno spazio):

lecca qui per visualizzare l'immagine del codice

In [5]: cities = pd.Series ([ 'Boston, MA 02215' , 'Miami, FL 33101' ])

In [6]: città
Fuori [6]:
0 Boston, MA 02215
1 Miami, FL 33101
dtype: oggetto
In [7]: cities.str.contains (r '[AZ] {2}' )
Fuori [7]:
0 Vero
1 Vero
dtype: bool

In [8]: cities.str.match (r '[AZ] {2}' )


Fuori [8]:
0 Falso
1 Falso
dtype: bool

C
Pagina 343
Non abbiamo specificato i valori dell'indice, quindi la serie utilizza indici a base zero per impostazione predefinita
(snippet [6]). Lo snippet [7] usa contiene per mostrare che entrambi gli elementi della serie

contengono sottostringhe che corrispondono a "[AZ] {2}". Lo snippet [8] utilizza la corrispondenza per dimostrarlo
il valore di nessuno dei due elementi corrisponde a quel modello nella sua interezza, perché ognuno ne ha un altro
caratteri nel suo valore completo.

Riformattazione dei dati

Abbiamo discusso della pulizia dei dati. Consideriamo ora l'unione dei dati in un formato diverso.
Come semplice esempio, si supponga che un'applicazione richieda numeri di telefono statunitensi in
formato ##########, con trattini che separano ogni gruppo di cifre. Il telefono
i numeri ci sono stati forniti come stringhe di 10 cifre senza trattini. Creiamo il file

DataFrame:

lecca qui per visualizzare l'immagine del codice

In [9]: contatti = [[ 'Mike Green' , 'demo1@deitel.com' , '5555555555' ],


...: [ "Sue Brown" , "demo2@deitel.com" , "5555551234" ]]
...:

In [10]: contactsdf = pd.DataFrame (contatti,


...: colonne = [ "Nome" , "Email" , "Telefono" ])
...:

In [11]: contactsdf
Fuori [11]:
Nome Email Telefono
0 Mike Green demo1@deitel.com 5555555555
1 Sue Brown demo2@deitel.com 5555551234

In questo DataFrame, abbiamo specificato gli indici di colonna tramite l'argomento della parola chiave column
ma non ha specificato gli indici di riga, quindi le righe sono indicizzate da 0. Inoltre, l'output mostra
i valori della colonna sono allineati a destra per impostazione predefinita. Questo differisce dalla formattazione Python in
quali numeri in un campo sono allineati a destra per impostazione predefinita, ma i valori non numerici vengono lasciati
allineato per impostazione predefinita.

Ora, munge i dati con una programmazione un po 'più funzionale. Noi possiamo
mappare i numeri di telefono nel formato corretto chiamando la mappa del metodo Series su

la colonna "Telefono" di DataFrame. L'argomento della mappa del metodo è una funzione che riceve
un valore e restituisce il valore mappato . La funzione get_formatted_phone maps 10

cifre consecutive nel formato ##########:

lecca qui per visualizzare l'immagine del codice

C
Pagina 344
n [12]: import re
In [13]: def get_formatted_phone (value):
...: risultato = re.fullmatch (r '(\ d {3}) (\ d {3}) (\ d {4})' , valore)
...: return '' .join (result.groups ()) if result else value
...:
...:

L'espressione regolare nella prima istruzione del blocco corrisponde solo a 10 cifre consecutive.
Cattura le sottostringhe contenenti le prime tre cifre, le tre cifre successive e l'ultima
quattro cifre. L'istruzione return funziona come segue:

Se il risultato è Nessuno, restituiamo semplicemente il valore non modificato.

Altrimenti, chiamiamo result.groups () per ottenere una tupla contenente il file acquisito

sottostringhe e passa la tupla al metodo stringa join per concatenare gli elementi,
separandoli dal successivo con "" per formare il numero di telefono mappato.

La mappa del metodo della serie restituisce una nuova serie contenente i risultati della chiamata di
argomento della funzione per ogni valore nella colonna. Lo snippet [15] mostra il risultato,

incluso il nome e il tipo della colonna:

lecca qui per visualizzare l'immagine del codice

In [14]: formatted_phone = contactsdf [ 'Phone' ] .map (get_formatted_phone)

In [15]: formatted_phone
0 5555555555
1 5555551234
Nome: telefono, dtype: oggetto

Dopo aver verificato che i dati siano nel formato corretto, puoi aggiornarli nel file
DataFrame originale assegnando la nuova serie alla colonna "Telefono":

lecca qui per visualizzare l'immagine del codice

In [16]: contactsdf [ 'Phone' ] = formatted_phone

In [17]: contactdf
Fuori [17]:
Nome Email Telefono
0 Mike Green demo1@deitel.com 5555555555
1 Sue Brown demo2@deitel.com 5555551234

C
io

Pagina 345

Continueremo la nostra discussione sui panda nell'introduzione alla scienza dei dati del prossimo capitolo
sezione, e useremo i panda in diversi capitoli successivi.

8.14 WRAP-UP
In questo capitolo sono state presentate varie funzionalità di formattazione ed elaborazione delle stringhe. tu
dati formattati in fstrings e con il formato del metodo stringa. Abbiamo mostrato il file
assegnazioni aumentate per concatenare e ripetere stringhe. Hai usato la stringa
metodi per rimuovere gli spazi all'inizio e alla fine delle stringhe e per modificare
il loro caso. Abbiamo discusso metodi aggiuntivi per dividere le stringhe e per unire
iterabili di stringhe. Abbiamo introdotto vari metodi di test dei caratteri.

Abbiamo mostrato stringhe non elaborate che trattano i backslash (\) come caratteri letterali anziché come caratteri
inizio delle sequenze di escape. Questi erano particolarmente utili per definire regolari
espressioni, che spesso contengono molti backslash.

Successivamente, abbiamo introdotto le potenti capacità di patternmatching delle espressioni regolari


con funzioni dal modulo re. Abbiamo utilizzato la funzione fullmatch per garantire che un file

l'intera stringa corrisponde a un modello, utile per la convalida dei dati. Abbiamo mostrato come farlo
utilizzare la funzione di sostituzione per cercare e sostituire le sottostringhe. Abbiamo usato la divisione

funzione per tokenizzare le stringhe in base a delimitatori che corrispondono a un'espressione regolare
modello. Quindi abbiamo mostrato vari modi per cercare pattern nelle stringhe e per accedere
le corrispondenze risultanti.

Nella sezione Intro to Data Science, abbiamo introdotto i sinonimi data munging e
data wrangling e ha mostrato l'operazione di munging dei dati del campione, vale a dire la trasformazione
dati. Abbiamo continuato la nostra discussione sulla serie di Panda e sui DataFrame utilizzando
espressioni regolari per convalidare e munge i dati.

Nel prossimo capitolo, continueremo a utilizzare varie capacità di elaborazione delle stringhe come abbiamo fatto
introdurre la lettura di testo da file e la scrittura di testo su file. Useremo il modulo csv per
manipolazione di file con valori separati da virgole (CSV). Introdurremo anche l'eccezione
in modo da poter elaborare le eccezioni man mano che si verificano, anziché visualizzare un file
rintracciare.

W
Pagina 346

storia . File ed eccezioni


Obiettivi
opiche

In questo capitolo potrai:


guadagnando Pat

Comprendere le nozioni di file e dati persistenti.


ffers & Dea

Leggi, scrivi e aggiorna i file.


ighlights

Leggere e scrivere file CSV, un formato comune per i set di dati di machine learning.
ettings

Serializza gli oggetti nel formato di scambio dati JSON, comunemente utilizzato per la trasmissione
su Internet
Supporto e deserializza JSON in oggetti.

Disconnessione
Usa l'istruzione with per assicurarti che le risorse vengano rilasciate correttamente, evitando
"Perdite di risorse".

Utilizzare l'istruzione try per delimitare il codice in cui possono verificarsi e gestire eccezioni
quelle eccezioni con clausole di eccezione associate.

Utilizzare la clausola else dell'istruzione try per eseguire il codice quando non si verificano eccezioni nel file

prova la suite.
Utilizzare la clausola finalmente dell'istruzione try per eseguire il codice indipendentemente dal fatto che un file
si verifica un'eccezione nel tentativo.

sollevare eccezioni per indicare problemi di runtime.

Comprendere il traceback di funzioni e metodi che hanno portato a un'eccezione.

Usa i panda per caricare in un DataFrame ed elaborare il set di dati CSV di Titanic Disaster.

Contorno

9
Pagina 347
.1 Introduzione

.2 File

.3 Elaborazione di file di testo

.3.1 Scrittura su un file di testo: presentazione dell'istruzione with

.3.2 Lettura di dati da un file di testo

.4 Aggiornamento dei file di testo

.5 Serializzazione con JSON

.6 Focus sulla sicurezza: serializzazione e deserializzazione pickle

.7 Note aggiuntive sui file

.8 Gestione delle eccezioni

.8.1 Divisione per zero e input non valido

.8.2 provare le dichiarazioni

.8.3 Rilevamento di più eccezioni in una clausola esclusa

.8.4 Quali eccezioni genera una funzione o un metodo?

.8.5 Quale codice dovrebbe essere inserito in una suite di prova?

.9 infine Clausola

.10 Sollevare esplicitamente un'eccezione

.11 (Opzionale) Stack Svolgimento e Traceback

.12 Introduzione alla scienza dei dati: utilizzo dei file CSV

.12.1 Modulo libreria standard Python csv

.12.2 Lettura di file CSV in Pandas DataFrame

.12.3 Lettura del set di dati di Titanic Disaster

9
Pagina 348
.12.4 Semplice analisi dei dati con il set di dati Titanic Disaster
.12.5 Istogramma dell'età dei passeggeri

.13 WrapUp

9.1 INTRODUZIONE
Variabili, elenchi, tuple, dizionari, insiemi, array, serie di panda e panda

I DataFrames offrono solo l'archiviazione temporanea dei dati. I dati vengono persi quando una variabile locale
"Esce dall'ambito" o quando il programma termina. I file forniscono una conservazione a lungo termine
di quantità generalmente elevate di dati, anche dopo il programma che ha creato i dati
termina, quindi i dati conservati nei file sono persistenti. I computer archiviano i file sul secondario
dispositivi di archiviazione, comprese unità a stato solido, dischi rigidi e altro ancora. In questo capitolo, noi
spiegare come i programmi Python creano, aggiornano ed elaborano i file di dati.

Consideriamo file di testo in diversi formati popolari: testo normale, JSON (JavaScript Object
Notazione) e CSV (valori separati da virgole). Useremo JSON per serializzare e
deserializzare gli oggetti per facilitare il salvataggio di tali oggetti nell'archivio secondario e
trasmettendoli su Internet. Assicurati di leggere l'Intro to Data Science di questo capitolo
sezione in cui useremo sia il modulo csv della libreria standard Python che pandas
per caricare e manipolare i dati CSV. In particolare, esamineremo la versione CSV di
Set di dati del disastro del Titanic. Useremo molti set di dati popolari nei prossimi datascience
capitoli di studio sull'elaborazione del linguaggio naturale, data mining Twitter, IBM Watson,
machine learning, deep learning e big data.

Come parte della nostra continua enfasi sulla sicurezza di Python, discuteremo della sicurezza
vulnerabilità della serializzazione e deserializzazione dei dati con la libreria standard di Python

modulo sottaceto. Consigliamo la serializzazione JSON invece di pickle.

Introduciamo anche la gestione delle eccezioni . Un'eccezione indica un tempo di esecuzione


problema. Hai visto eccezioni di tipo ZeroDivisionError, NameError,

ValueError, StatisticsError, TypeError, IndexError, KeyError e

RuntimeError. Mostreremo come gestire le eccezioni quando si verificano utilizzando try


istruzioni e clausole di eccezione associate per gestire le eccezioni. Discuteremo anche di

le clausole dell'istruzione try e infine. Le funzionalità presentate qui ti aiutano


scrivere robusti , faulttolerant programmi in grado di affrontare i problemi e continuare
eseguire o terminare correttamente .

9
Pagina 349
I rogrammi tipicamente richiedono e rilasciano risorse (come file) durante il programma
esecuzione. Spesso, questi sono in quantità limitata o possono essere utilizzati solo da un programma in a
tempo. Mostriamo come garantire che dopo che un programma utilizza una risorsa, venga rilasciato per
utilizzo da parte di altri programmi, anche se si è verificata un'eccezione. Userai il con
dichiarazione a tal fine.

9.2 FILE
Python visualizza un file di testo come una sequenza di caratteri e un file binario (per le immagini,
video e altro) come sequenza di byte. Come negli elenchi e negli array, il primo carattere in a
file di testo e byte in un file binario si trovano alla posizione 0, quindi in un file di n caratteri o
byte, il numero di posizione più alto è n - 1. Il diagramma seguente mostra una vista concettuale
di un file:
Per ogni file che apri , Python crea un oggetto file che utilizzerai per interagire con il file
file.

Fine del file

Ogni sistema operativo fornisce un meccanismo per indicare la fine di un file. Alcuni
rappresentarlo con un marker di endoffile (come nella figura precedente), mentre altri
potrebbe mantenere un conteggio dei caratteri o dei byte totali nel file. Programmazione
le lingue generalmente nascondono questi dettagli del sistema operativo all'utente.

Oggetti file standard

Quando un programma Python inizia l'esecuzione, crea tre oggetti file standard :

sys.stdin: l' oggetto file di input standard

sys.stdout: l' oggetto file di output standard e

sys.stderr: l' oggetto file di errore standard .

Sebbene siano considerati oggetti file, non leggono o scrivono su file da


predefinito. La funzione di input utilizza implicitamente sys.stdin per ottenere l'input dell'utente da
tastiera. La funzione print restituisce implicitamente l'output a sys.stdout, che appare nel file
riga di comando. Python restituisce implicitamente errori di programma e traceback in

P
Pagina 350
sys.stderr, che appare anche nella riga di comando. Devi importare il file sys
se è necessario fare riferimento a questi oggetti in modo esplicito nel codice, ma questo è raro.

9.3 ELABORAZIONE DEI FILE DI TESTO


In questa sezione, scriveremo un semplice file di testo che potrebbe essere utilizzato da un account
sistema di crediti per tenere traccia del denaro dovuto dai clienti di un'azienda. Lo leggeremo quindi
file di testo per confermare che contenga i dati. Per ogni cliente, memorizzeremo i file del cliente
numero di conto, cognome e saldo del conto dovuto alla società. Insieme, questi
i campi dati rappresentano un record del cliente . Python non impone alcuna struttura a un file, quindi nozioni
come i record non esistono nativamente in Python . I programmatori devono strutturare i file in
soddisfare i requisiti delle loro applicazioni. Creeremo e manterremo questo file in ordine per
numero di conto. In questo senso, il numero di conto può essere considerato come un record
chiave . Per questo capitolo, si presume che si avvii IPython dagli esempi ch09

cartella.

9.3.1 Scrivere su un file di testo: presentazione dell'istruzione with

Creiamo un file accounts.txt e scriviamo cinque record client nel file. Generalmente,
i record nei file di testo vengono memorizzati uno per riga, quindi terminiamo ogni record con una nuova riga
carattere:

lecca qui per visualizzare l'immagine del codice

In [1]: con open ( 'accounts.txt' , mode = 'w' ) come account:


...: accounts.write ( '100 Jones 24.98 \ n' )
...: accounts.write ( '200 Doe 345.67 \ n' )
...: accounts.write ( '300 White 0.00 \ n' )
...: accounts.write ( '400 Stone 42.16 \ n' )
...: accounts.write ( '500 Rich 224.62 \ n' )
...:

Puoi anche scrivere su un file con print (che restituisce automaticamente un \ n), come in

lecca qui per visualizzare l'immagine del codice

print ( '100 Jones 24.98' , file = account)

La dichiarazione con

Molte applicazioni acquisiscono risorse, come file, connessioni di rete, database

C
Pagina 351
connessioni e altro ancora. Dovresti rilasciare le risorse non appena non sono più
necessario. Questa pratica garantisce che altre applicazioni possano utilizzare le risorse. Python's
con dichiarazione :

acquisisce una risorsa (in questo caso, l'oggetto file per accounts.txt) e assegna il suo file
oggetto corrispondente a una variabile (conti in questo esempio),

consente all'applicazione di utilizzare la risorsa tramite quella variabile e

chiama il metodo close dell'oggetto risorsa per rilasciare la risorsa quando il programma
il controllo raggiunge la fine della suite dell'istruzione with.

Funzione incorporata aperta

La funzione di apertura incorporata apre il file accounts.txt e lo associa a un file


oggetto. L'argomento mode specifica la modalità fileopen , indicando se aprire
un file per la lettura dal file, per la scrittura nel file o entrambi. La modalità 'w' apre il file

file per la scrittura , creando il file se non esiste. Se non si specifica un percorso per il file
file, Python lo crea nella cartella corrente (ch09). Fai attenzione: apri un file in scrittura
elimina tutti i dati esistenti nel file. Per convenzione, l' estensione del file .txt

indica un file di testo semplice.

Scrittura sul file

L'istruzione with assegna l'oggetto restituito da open alla variabile accounts in

la clausola as . Nella suite dell'istruzione with, utilizziamo gli account variabili per interagire
con il file. In questo caso, chiamiamo il metodo di scrittura dell'oggetto file cinque volte per scriverne cinque

record nel file, ciascuno come una riga di testo separata che termina con una nuova riga. Alla fine di

con la suite dell'istruzione, l'istruzione with chiama implicitamente la chiusura dell'oggetto file
metodo per chiudere il file.

Contenuto del file accounts.txt

Dopo aver eseguito lo snippet precedente, la directory ch09 contiene il file

accounts.txt con i seguenti contenuti, visualizzabili aprendo il file in formato


un editor di testo:

100 Jones 24.98


200 Doe 345.67
300 Bianco 0.00
400 Pietra 42.16
500 Rich 224.62

Pagina 352
Nella sezione successiva, leggerai il file e ne visualizzerai il contenuto.

9.3.2 Lettura di dati da un file di testo


Abbiamo appena creato il file di testo accounts.txt e vi abbiamo scritto i dati. Ora leggiamolo
dati dal file in sequenza dall'inizio alla fine. La sessione seguente legge
registra dal file accounts.txt e visualizza il contenuto di ogni record in formato
colonne con le colonne Account e Nome allineate a sinistra e la colonna Saldo
allineato a destra , quindi i punti decimali si allineano verticalmente:

lecca qui per visualizzare l'immagine del codice

In [1]: con aperti ( 'accounts.txt' , mode = 'r' ) come account:


...: print (f ' { "Account" : < 10 } { "Name" : < 10 } { "Balance" :> 10 } ' )
...: per la registrazione nei conti:
...: account, nome, saldo = record.split ()
...: print (f ' {account: < 10 } {name: < 10 } {balance:> 10 } ' )
...:
Saldo nome account
100 Jones 24.98
200 Doe 345.67
300 Bianco 0.00
400 Pietra 42.16
500 Rich 224.62

Se il contenuto di un file non deve essere modificato, aprire il file in sola lettura. Questo
impedisce al programma di modificare accidentalmente il file. Apri un file per la lettura
passando la modalità fileopen 'r' come secondo argomento di apertura della funzione. Se non

specificare la cartella in cui memorizzare il file, open presuppone che il file si trovi nel file corrente
cartella.

L'iterazione attraverso un oggetto file, come mostrato nell'istruzione for precedente, legge una riga
alla volta dal file e lo restituisce come stringa. Per ogni record (ovvero, riga) nel file
file, stringa metodo split restituisce i token nella riga come un elenco, che scompattiamo nel file
1
conto, nome e saldo delle variabili. L' ultima affermazione nella dichiarazione for
suite visualizza queste variabili in colonne utilizzando le larghezze dei campi.

1
Quando si dividono le stringhe negli spazi (impostazione predefinita), split elimina automaticamente il file
carattere di nuova riga.

File Method readlines

C
Pagina 353
Il metodo readlines dell'oggetto file può essere utilizzato anche per leggere un intero file di testo. Il
restituisce ogni riga come una stringa in un elenco di stringhe. Per file piccoli, funziona bene,
2
ma l'iterazione sulle righe in un oggetto file, come mostrato sopra, può essere più efficiente.
La chiamata di readline per un file di grandi dimensioni può essere un'operazione che richiede tempo, che deve
completare prima di poter iniziare a utilizzare l'elenco di stringhe. Utilizzando l'oggetto file in un file for

consente al programma di elaborare ogni riga di testo mentre viene letta.

2
ttps: //docs.python.org/3/tutorial/inputoutput.html#methods
ffileobjects .

Alla ricerca di una posizione specifica del file

Durante la lettura di un file, il sistema mantiene un puntatore di posizione del file


che rappresenta la posizione del prossimo carattere da leggere. A volte è necessario
elaborare un file in sequenza dall'inizio più volte durante un programma
esecuzione. Ogni volta, è necessario riposizionare il puntatore di posizione del file all'inizio di
il file, operazione che puoi eseguire chiudendo e riaprendo il file o chiamando il file
metodo di ricerca dell'oggetto , come in

file_object .seek ( 0 )

Quest'ultimo approccio è più veloce.

9.4 AGGIORNAMENTO DEI FILE DI TESTO


I dati formattati scritti in un file di testo non possono essere modificati senza il rischio di distruzione
altri dati. Se il nome "White" deve essere cambiato in "Williams" in

accounts.txt, il vecchio nome non può essere semplicemente sovrascritto. Il record originale per
Il bianco viene memorizzato come

300 Bianco 0.00

Se sovrascrivi il nome "White" con il nome "Williams", il record diventa

300 Williams00

Il nuovo cognome contiene tre caratteri in più rispetto a quello originale, quindi il
i caratteri oltre la seconda "i" in "Williams" sovrascrivono gli altri caratteri in
linea. Il problema è che nel modello input-output formattato, record e relativi campi

ho
Pagina 354
può variare di dimensioni. Ad esempio, 7, 14, –117, 2074 e 27383 sono tutti numeri interi e lo sono
memorizzati internamente nello stesso numero di "dati grezzi" (tipicamente 4 o 8 byte in formato
sistemi odierni). Tuttavia, quando questi numeri interi vengono emessi come testo formattato, essi
diventano campi di dimensioni differenziate. Ad esempio, 7 è un carattere, 14 è due caratteri e
27383 è di cinque caratteri.

Per modificare il nome precedente, possiamo:

copiare i record prima di 300 White 0.00 in un file temporaneo,

scrivere il record aggiornato e formattato correttamente per l'account 300 in questo file,

copiare i record dopo 300 White 0.00 nel file temporaneo,

eliminare il vecchio file e

rinominare il file temporaneo per utilizzare il nome del file originale.

Questo può essere complicato perché richiede l'elaborazione di tutti i record nel file, anche se
devi aggiornare solo un record. L'aggiornamento di un file come descritto sopra è più efficiente
3
quando un'applicazione deve aggiornare molti record in un passaggio del file.

3
Nel capitolo Big Data: Hadoop, Spark, NoSQL e IoT, vedrai quel database
sistemi risolvono questo problema di aggiornamento in modo efficiente.

Aggiornamento di accounts.txt

Usiamo un'istruzione with per aggiornare il file accounts.txt per modificare l'account 300
nome da 'White' a 'Williams' come descritto sopra:
lecca qui per visualizzare l'immagine del codice

n [1]: account = aperti ( "accounts.txt" , "r" )

In [2]: temp_file = open ( 'temp_file.txt' , 'w' )

In [3]: con account, temp_file:


...: per la registrazione nei conti:
...: account, nome, saldo = record.split ()
...: if account! = '300' :
...: temp_file.write (record)
...: altro :
...: new_record = '' .join ([account, 'Williams' , balance])
...: temp_file.write (new_record + '\ n' )

C
io

...: Pagina 355

o leggibilità, abbiamo aperto gli oggetti file (snippet [1] e [2]), quindi abbiamo specificato i loro
nomi di variabili nella prima riga dello snippet [3]. Questo con l'affermazione ne gestisce due
oggetti risorsa, specificati in un elenco separato da virgole dopo con. L'istruzione for
decomprime ogni record in conto, nome e saldo. Se l'account non è "300",

scriviamo record (che contiene una nuova riga) in temp_file. Altrimenti, ci assembliamo
il nuovo record contenente "Williams" al posto di "White" e scriverlo nel file.

Dopo lo snippet [3], temp_file.txt contiene:

100 Jones 24.98


200 Doe 345.67
300 Williams 0,00
400 Pietra 42.16
500 Rich 224.62

Funzioni di elaborazione dei file del modulo os

A questo punto, abbiamo il vecchio file accounts.txt e il nuovo temp_file.txt. Per


completare l'aggiornamento, eliminare il vecchio file accounts.txt, quindi rinominare
4
temp_file.txt come accounts.txt. Il modulo os fornisce funzioni per
interagire con il sistema operativo, inclusi molti che manipolano il tuo sistema
file e directory. Ora che abbiamo creato il file temporaneo, usiamo il file remove
5
funzione per eliminare il file originale:

4
ttps: //docs.python.org/3/library/os.html .

5
Usa rimuovi con cautela perché non ti avvisa che stai eliminando definitivamente il file

file.

lecca qui per visualizzare l'immagine del codice

In [4]: import os

In [5]: os.remove ( 'accounts.txt' )

Successivamente, usiamo la funzione di rinomina per rinominare il file temporaneo come

"accounts.txt":

lecca qui per visualizzare l'immagine del codice

F
C
h
Pagina 356
In [6]: os.rename ( 'temp_file.txt' , 'accounts.txt' )

9.5 SERIALIZZAZIONE CON JSON


Molte librerie che utilizzeremo per interagire con servizi basati su cloud, come Twitter, IBM
Watson e altri, comunicano con le tue applicazioni tramite oggetti JSON. JSON
(JavaScript Object Notation) è un dato basato su testo, leggibile dall'uomo e dal computer
formato di interscambio utilizzato per rappresentare gli oggetti come raccolte di coppie nome-valore. JSON
può anche rappresentare oggetti di classi personalizzate come quelle che costruirai nel prossimo capitolo.

JSON è diventato il formato dati preferito per la trasmissione di oggetti su piattaforme.


Ciò è particolarmente vero per invocare servizi Web basati su cloud, che sono funzioni e
metodi che chiami su Internet. Diventerai abile nel lavorare con JSON
dati. Nel capitolo "Twitter di data mining", accederai a oggetti JSON contenenti
tweet e relativi metadati. Nel capitolo "IBM Watson e Cognitive Computing",
accederai ai dati nelle risposte JSON restituite dai servizi Watson. Nel " ig Dati:
adoop, Spark, NoSQL e IoT ”, memorizzeremo gli oggetti tweet JSON che otteniamo
da Twitter in MongoDB, un popolare database NoSQL. In quel capitolo lavoreremo anche
con altri servizi Web che inviano e ricevono dati come oggetti JSON.

Formato dati JSON


Gli oggetti JSON sono simili ai dizionari Python. Ogni oggetto JSON contiene una virgola
elenco separato di nomi e valori di proprietà , tra parentesi graffe. Ad esempio, il seguente
le coppie chiave-valore potrebbero rappresentare un record del cliente:

{"account": 100, "name": "Jones", "balance": 24,98}

JSON supporta anche gli array che, come gli elenchi Python, sono valori separati da virgole in
parentesi quadre. Ad esempio, il seguente è un array di numeri JSON accettabile:

[100, 200, 300]

I valori negli oggetti e negli array JSON possono essere:

stringhe tra virgolette doppie (come "Jones"),

numeri (come 100 o 24,98),

B
H
Pagina 357
Valori booleani JSON (rappresentati come vero o falso in JSON),

null (per non rappresentare alcun valore, come None in Python),

array (come [100, 200, 300]) e

altri oggetti JSON.

Modulo libreria standard Python json

Il modulo json consente di convertire gli oggetti in JSON (JavaScript Object

Notazione) formato di testo. Ciò è noto come serializzazione dei dati. Considera quanto segue
dizionario, che contiene una coppia chiave-valore composta dalla chiave "account" con
il suo valore associato è un elenco di dizionari che rappresentano due account. Ogni account
dizionario contiene tre coppie chiave-valore per il numero di conto, il nome e il saldo:
lecca qui per visualizzare l'immagine del codice

In [1]: accounts_dict = { "accounts" : [


...: { 'account' : 100 , 'name' : 'Jones' , 'balance' : 24.98 },
...: { 'account' : 200 , 'name' : 'Doe' , 'balance' : 345.67 }]}

Serializzazione di un oggetto in JSON

Scriviamo quell'oggetto in formato JSON in un file:

lecca qui per visualizzare l'immagine del codice

In [2]: importa json

In [3]: con open ( 'accounts.json' , 'w' ) come account:


...: json.dump (accounts_dict, account)
...:

Snippet [3] apre il file accounts.json e utilizza il dump del modulo json

funzione per serializzare il dizionario accounts_dict nel file. Il file risultante


contiene il testo seguente, che abbiamo leggermente riformattato per renderlo leggibile:

lecca qui per visualizzare l'immagine del codice

{"account":
[{"account": 100, "name": "Jones", "balance": 24,98},
{"account": 200, "name": "Doe", "balance": 345.67}]}

C
Pagina 358

Nota che JSON delimita le stringhe con caratteri a doppia virgola .

Deserializzazione del testo JSON

La funzione di caricamento del modulo json legge l'intero contenuto JSON del suo oggetto file
argomento e converte il JSON in un oggetto Python. Questa operazione è nota come deserializzazione
i dati. Ricostruiamo l'oggetto Python originale da questo testo JSON:

lecca qui per visualizzare l'immagine del codice

In [4]: con open ( 'accounts.json' , 'r' ) come account:


...: accounts_json = json.load (account)
...:
...:

Ora possiamo interagire con l'oggetto caricato. Ad esempio, possiamo visualizzare il dizionario:

lecca qui per visualizzare l'immagine del codice

In [5]: accounts_json
Fuori [5]:
{"accounts": [{"account": 100, "name": "Jones", "balance": 24.98},
{'account': 200, 'name': 'Doe', 'balance': 345.67}]}

Come ti aspetteresti, puoi accedere ai contenuti del dizionario. Otteniamo l'elenco delle dizione
ariete associato alla chiave "account":

lecca qui per visualizzare l'immagine del codice


In [6]: accounts_json [ "account" ]
Fuori [6]:
[{"account": 100, "name": "Jones", "balance": 24,98},
{'account': 200, 'name': 'Doe', 'balance': 345.67}]

Ora, prendiamo i dizionari degli account individuali:

lecca qui per visualizzare l'immagine del codice

In [7]: accounts_json [ "account" ] [ 0 ]


In uscita [7]: {"account": 100, "name": "Jones", "balance": 24,98}

In [8]: accounts_json [ "accounts" ] [ 1 ]

In uscita [8]: {"account": 200, "name": "Doe", "balance": 345,67} Pagina 359

Sebbene non lo abbiamo fatto qui, puoi modificare anche il dizionario. Ad esempio, tu
potrebbe aggiungere o rimuovere account dall'elenco, quindi riscrivere il dizionario
nel file JSON.

Visualizzazione del testo JSON

La funzione dump del modulo json (dump è l'abbreviazione di "dump string") restituisce a
Rappresentazione in stringa Python di un oggetto in formato JSON. Usando dump con carico, tu
può leggere il JSON dal file e visualizzarlo in un formato ben rientrato, a volte
chiamato "bella stampa" il JSON. Quando la chiamata alla funzione dump include il rientro
argomento della parola chiave, la stringa contiene caratteri di nuova riga e rientro per pretty
stampa: puoi anche usare il rientro con la funzione dump quando scrivi su un file:

lecca qui per visualizzare l'immagine del codice

In [9]: con open ( 'accounts.json' , 'r' ) come account:


...: print (json.dumps (json.load (account), indent = 4 ))
...:
{
"account": [
{
"account": 100,
"nome": "Jones",
"saldo": 24,98
},
{
"account": 200,
"name": "Doe",
"saldo": 345,67
}
]
}

9.6 FOCUS SULLA SICUREZZA: SERIALIZZAZIONE PICKLE E


DESERIALIZZAZIONE
Il modulo pickle della Python Standard Library può serializzare gli oggetti in un Python
formato dati specifico. Attenzione: la documentazione di Python fornisce il
seguenti avvertenze sul sottaceto:

“I file Pickle possono essere violati. Se ricevi un file raw pickle sulla rete, non farlo
fidati! Potrebbe contenere codice dannoso, che eseguirà Python arbitrario quando

C
provi a depickle. Tuttavia, se stai scrivendo i tuoi sottaceti e Pagina 360
6
leggendo, sei al sicuro (a condizione che nessun altro abbia accesso al file pickle, ovviamente.) "

6
ttps: //wiki.python.org/moin/UsingPickle .

“Pickle è un protocollo che consente la serializzazione di Python arbitrariamente complessi


oggetti. In quanto tale, è specifico di Python e non può essere utilizzato per comunicare con
applicazioni scritte in altre lingue. Inoltre è insicuro per impostazione predefinita: deserializzazione
i dati pickle provenienti da una fonte non attendibile possono eseguire codice arbitrario, se i dati
7
è stato creato da un abile aggressore ".

ttps: //docs.python.org/3/tutorial/inputoutput.html#reading
ndwritingfiles .

Non consigliamo di usare il sottaceto, ma è stato usato per molti anni, quindi è probabile

per incontrarlo nel codice legacy, vecchio codice che spesso non è più supportato.

9.7 NOTE AGGIUNTIVE RIGUARDANTI I FILE


La tabella seguente riassume le varie modalità fileopen per i file di testo, incluso il
modalità di lettura e scrittura che abbiamo introdotto. Le modalità di scrittura e aggiunta
creare il file se non esiste. Le modalità di lettura sollevano un'eccezione FileNotFoundError if

il file non esiste. Ogni modalità di file di testo ha una modalità di file binario corrispondente
specificato con b, come in "rb" o "wb +". Ad esempio, useresti queste modalità se lo fossi
leggere o scrivere file binari, come immagini, audio, video, file ZIP compressi e
molti altri formati di file personalizzati popolari.

Modalità Descrizione

Apri un file di testo per la lettura. Questa è l'impostazione predefinita se non specifichi
'r'
la modalità fileopen quando chiami open.

'w' Apri un file di testo per la scrittura. Il contenuto del file esistente viene eliminato .

yun'
h
Pagina 361
'un' Apri un file di testo da aggiungere alla fine, creando il file se lo fa
non esiste. I nuovi dati vengono scritti alla fine del file.

"r +" Apri un file di testo leggendo e scrivendo.

"w +" Apri un file di testo leggendo e scrivendo. Il contenuto del file esistente viene eliminato .

Apri un file di testo leggendolo e aggiungendolo alla fine. I nuovi dati sono
"a +"
scritto alla fine del file. Se il file non esiste, viene creato.
Altri metodi di oggetti file

Ecco alcuni metodi fileobject più utili.

Per un file di testo, il metodo read restituisce una stringa contenente il numero di

caratteri specificati dall'argomento intero del metodo. Per un file binario, il metodo
restituisce il numero di byte specificato. Se non viene specificato alcun argomento, il metodo
restituisce l'intero contenuto del file.

Il metodo readline restituisce una riga di testo come stringa, inclusa la nuova riga
carattere se ce n'è uno. Questo metodo restituisce una stringa vuota quando incontra
la fine del file.

Il metodo writelines riceve un elenco di stringhe e ne scrive il contenuto in un file.

Le classi che Python utilizza per creare oggetti file sono definite nello standard Python
Modulo io della libreria ( ttps: //docs.python.org/3/library/io.html ).

9.8 ECCEZIONI NEL TRATTAMENTO


Quando si lavora con i file possono verificarsi vari tipi di eccezioni, tra cui:

Un FileNotFoundError si verifica se si tenta di aprire un file inesistente per


lettura con le modalità "r" o "r +".

h
Pagina 362
Se si tenta di eseguire un'operazione per la quale non si esegue, si verifica un errore PermissionsError
avere il permesso. Ciò potrebbe verificarsi se provi ad aprire un file che il tuo account non è
autorizzato ad accedere o creare un file in una cartella in cui il tuo account non ha
permesso di scrivere, ad esempio dove è archiviato il sistema operativo del tuo computer.

Un ValueError (con il messaggio di errore "Operazione di I / O su file chiuso.")


si verifica quando si tenta di scrivere su un file che è già stato chiuso.

9.8.1 Divisione per zero e input non valido


Rivediamo due eccezioni che hai visto in precedenza nel libro.

Divisione per zero

Ricorda che il tentativo di dividere per 0 produce un'eccezione ZeroDivisionError:

lecca qui per visualizzare l'immagine del codice

In [1]: 10 / 0

ZeroDivisionError Traceback (la chiamata più recente per ultima


ipythoninput1a243dfbf119d> in <module> ()
> 1 10 / 0

ZeroDivisionError : divisione per zero

In 2]:

In questo caso, si dice che l'interprete solleva un'eccezione di tipo

ZeroDivisionError. Quando viene sollevata un'eccezione in IPython, essa:


termina lo snippet,

mostra il traceback dell'eccezione, quindi

mostra il successivo prompt In [] in modo da poter inserire lo snippet successivo.

Se si verifica un'eccezione in uno script, termina e IPython visualizza il traceback.

inserimento non valido

Ricorda che la funzione int solleva un'eccezione ValueError se tenti di convertire in un file

C
<

Pagina 363
nteger una stringa (come 'ciao') che non rappresenta un numero:

lecca qui per visualizzare l'immagine del codice

In [2]: value = int (input ( 'Enter an integer:' ))


Inserisci un numero intero: ciao

ValueError Traceback (la chiamata più recente last


ipythoninput2b521605464d6> in <module> ()
> 1 valore = int (input ( 'Inserisci un numero intero:' ))

ValueError : valore letterale non valido per int () con base 10: 'hello'

In [3]:

9.8.2 Provare le dichiarazioni

Ora vediamo come gestire queste eccezioni in modo da poter abilitare il codice per continuare
in lavorazione. Considera il seguente script e un'esecuzione di esempio. Il suo ciclo tenta di farlo
legge due numeri interi dall'utente, quindi visualizza il primo numero diviso per il secondo.
Lo script utilizza la gestione delle eccezioni per catturare e gestire (ovvero, gestirne) qualsiasi

ZeroDivisionErrors e ValueErrors che si presentano, in questo caso, consentendo all'utente di farlo


reinserire l'input.

lecca qui per visualizzare l'immagine del codice

1 # dividebyzero.py
2 "" "Semplice esempio di gestione delle eccezioni." ""
3
4 mentre True :
5 # tenta di convertire e dividere i valori
6 prova :
7 number1 = int (input ( 'Enter numerator:' ))
8 number2 = int (input ( 'Enter denominator:' ))
9 risultato = numero1 / numero2
10 tranne ValueError: # ha tentato di convertire un valore non numerico in int
11 print ( 'Devi inserire due numeri interi \ n' )
12 tranne ZeroDivisionError: # denominatore era 0
13 print ( 'Tentativo di divisione per zero \ n' )
14 else : # viene eseguito solo se non si verificano eccezioni
15 print (f ' {numero1: .3 f} / {numero2: .3 f} = {risultato: .3 f} ' )
16 break # termina il ciclo

lecca qui per visualizzare l'immagine del codice

io
C
<
Pagina 364
Inserisci numeratore: 100
Inserisci denominatore: 0
Tentativo di dividere per zero

Inserisci numeratore: 100


Inserisci denominatore: ciao
Devi inserire due numeri interi

Inserisci numeratore: 100


Immettere il denominatore: 7
100.000 / 7.000 = 14.286

prova Clause

Python usa istruzioni try (come le righe 6–16) per abilitare la gestione delle eccezioni. La prova
la clausola try dell'istruzione (righe 6-9) inizia con la parola chiave try, seguita da due punti (:)
e una serie di istruzioni che potrebbero sollevare eccezioni.

tranne la clausola
Una clausola try può essere seguita da una o più clausole tranne (righe 10-11 e 12-13)

che seguono immediatamente la suite della clausola try. Anche questi sono noti come eccezioni
gestori . Ciascuna clausola tranne specifica il tipo di eccezione che gestisce. In questo
Ad esempio, ogni gestore di eccezioni visualizza solo un messaggio che indica il problema
si è verificato.

altra clausola
Dopo l'ultima clausola tranne, una clausola else opzionale (righe 14-16) specifica il codice che
dovrebbe essere eseguito solo se il codice nella suite try non ha sollevato eccezioni. Se no

si verificano eccezioni nella suite di prove di questo esempio, la riga 15 mostra il risultato e la riga della divisione

16 termina il ciclo.

Flusso di controllo per ZeroDivisionError

Consideriamo ora il flusso di controllo di questo esempio, basato sulle prime tre righe del file
output di esempio:

Innanzitutto, l'utente immette 100 per il numeratore in risposta alla riga 7 nella suite di prova.

Successivamente, l'utente immette 0 per il denominatore in risposta alla riga 8 nella suite di prova.

A questo punto, abbiamo due valori interi, quindi la riga 9 tenta di dividere 100 per 0,

Pagina 365
ausing Python per sollevare un ZeroDivisionError. Il punto del programma in cui

si verifica un'eccezione è spesso indicato come il punto di sollevamento .

Quando si verifica un'eccezione in una suite di prova, termina immediatamente. Se ce ne sono

ad eccezione dei gestori che seguono la suite try, il controllo del programma viene trasferito alla prima. Se
non ci sono tranne gestori, si verifica un processo chiamato svolgimento dello stack , che noi
discuterne più avanti nel capitolo.

In questo esempio, ci sono tranne i gestori, quindi l'interprete cerca il primo


che corrisponde al tipo di eccezione sollevata:

La clausola tranne alle righe 10-11 gestisce ValueErrors. Questo non corrisponde al file

digitare ZeroDivisionError, in modo che la suite della clausola tranne non venga eseguita e
il controllo del programma si trasferisce al successivo tranne il gestore.

La clausola tranne alle righe 12-13 gestisce ZeroDivisionErrors. Questa è una partita

in modo che la suite della clausola tranne venga eseguita, visualizzando "Tentativo di divisione per

zero".

Quando una clausola tranne gestisce correttamente l'eccezione, l'esecuzione del programma

riprende con la clausola infine (se presente), quindi con l'istruzione successiva dopo
la dichiarazione try. In questo esempio, raggiungiamo la fine del ciclo, quindi l'esecuzione riprende
con la successiva iterazione del ciclo. Notare che dopo la gestione di un'eccezione, il controllo del programma
non senza tornare al punto di rilancio. Piuttosto, il controllo riprende dopo l'istruzione try.
Discuteremo a breve la clausola finalmente.

Flusso di controllo per un ValueError

Consideriamo ora il flusso di controllo, basato sulle successive tre righe del campione
produzione:

Innanzitutto, l'utente immette 100 per il numeratore in risposta alla riga 7 nella suite di prova.

Successivamente, l'utente inserisce hello per il denominatore in risposta alla riga 8 nel tentativo

suite. L'input non è un numero intero valido, quindi la funzione int solleva un'eccezione ValueError.

L'eccezione termina la suite di prova e il controllo del programma si trasferisce alla prima

eccetto handler. In questo caso, la clausola tranne alle righe 10-11 è una corrispondenza, quindi la sua suite
viene eseguito, visualizzando "È necessario immettere due numeri interi". Quindi, l'esecuzione del programma

c
Pagina 366
riprende con l'istruzione successiva dopo l'istruzione try. Di nuovo, questa è la fine del
ciclo, quindi l'esecuzione riprende con l'iterazione del ciclo successivo.

Flusso di controllo per una divisione di successo


Consideriamo ora il flusso di controllo, basato sulle ultime tre righe del campione
produzione:

Innanzitutto, l'utente immette 100 per il numeratore in risposta alla riga 7 nella suite di prova.

Successivamente, l'utente inserisce 7 come denominatore in risposta alla riga 8 nella suite di prova.

A questo punto, abbiamo due valori interi validi e il denominatore non è 0, quindi linea
9 divide con successo 100 per 7.

Quando non si verificano eccezioni nella suite di prova, l'esecuzione del programma riprende con la funzione else

clausola (se presente); in caso contrario, l'esecuzione del programma riprende con l'istruzione successiva
dopo l'istruzione try. Nella clausola else di questo esempio, viene visualizzato il risultato della divisione,
quindi termina il ciclo e il programma termina.

9.8.3 Rilevamento di più eccezioni in una clausola esclusa

È relativamente comune che una clausola try sia seguita da diverse clausole tranne a

gestire vari tipi di eccezioni. Se più di una suite sono identiche, puoi prenderle
quei tipi di eccezione specificandoli come una tupla in un unico gestore di eccezione, come in:

tranne ( tipo1 , tipo2 , ...) come nome_variabile :


La clausola as è facoltativa. In genere, i programmi non hanno bisogno di fare riferimento al catturato
oggetto eccezione direttamente. Se lo fai, puoi usare la variabile nella clausola as to
fare riferimento all'oggetto eccezione nella suite eccetto.

9.8.4 Quali eccezioni genera una funzione o un metodo?


Le eccezioni possono emergere tramite istruzioni in una suite try, tramite funzioni o metodi chiamati

direttamente o indirettamente da una suite di prova o tramite l'interprete Python mentre esegue il file
codice (ad esempio, ZeroDivisionErrors).

Prima di utilizzare qualsiasi funzione o metodo, leggi la relativa documentazione API in linea, che
specifica quali eccezioni vengono generate (se presenti) dalla funzione o dal metodo e indica

Pagina 367
spiega perché possono verificarsi tali eccezioni. Successivamente, leggi la documentazione API in linea per
ogni tipo di eccezione per vedere i potenziali motivi per cui si verifica tale eccezione.

9.8.5 Quale codice dovrebbe essere inserito in una suite di prova?

Metti in una suite di prova una sezione logica significativa di un programma in cui diversi file

le istruzioni possono sollevare eccezioni, invece di racchiudere un'istruzione try separata


attorno a ogni affermazione che solleva un'eccezione. Tuttavia, per una corretta eccezione
gestendo la granularità, ogni istruzione try dovrebbe includere una sezione di codice piccola
abbastanza che, quando si verifica un'eccezione, il contesto specifico sia noto e l'eccezione

i gestori possono elaborare l'eccezione correttamente. Se molte dichiarazioni in una suite di prova sollevano
gli stessi tipi di eccezione, possono essere necessarie più istruzioni try per determinarle

contesto dell'eccezione.

9.9 CLAUSOLA INFINE


I sistemi operativi in ​genere possono impedire a più di un programma di manipolare un file
file in una volta. Quando un programma termina l'elaborazione di un file, il programma dovrebbe chiuderlo a
rilascia la risorsa in modo che altri programmi possano accedervi. La chiusura del file aiuta a prevenire un file
perdita di risorse .

La clausola finale della dichiarazione try

Un'istruzione try può avere una clausola finalmente dopo ogni clausola tranne o l'altra
8
clausola. La clausola infine è garantita per l'esecuzione . In altre lingue che hanno

infine, questo rende la suite infine un luogo ideale per posizionare le risorse
codice di deallocazione per le risorse acquisite nella suite di prova corrispondente. In Python, noi

preferisci l'istruzione with per questo scopo e inserisci altri tipi di codice di "pulizia"
l'ultima suite.

8
L'unico motivo per cui una suite finalmente non verrà eseguita se il controllo del programma entra in
la suite di prova corrispondente è se l'applicazione termina per prima, ad esempio chiamando il file

funzione di uscita del modulo sys.

Esempio

La seguente sessione IPython dimostra che la clausola finalmente viene eseguita sempre,
indipendentemente dal fatto che si verifichi un'eccezione nella suite di prova corrispondente. Per prima cosa, andiamo

considera un'istruzione try in cui non si verificano eccezioni nella suite try:

lecca qui per visualizzare l'immagine del codice

r
C
Pagina 368
In [1]: prova :
...: print ( 'prova suite senza eccezioni sollevate' )
...: tranne :
...: print ( 'questo non verrà eseguito' )
...: altro :
...: print ( 'altrimenti viene eseguito perché nessuna eccezione nella suite di prova'
...: finalmente :
...: print ( 'alla fine viene sempre eseguito' )
...:
prova la suite senza eccezioni sollevate
altrimenti viene eseguito perché nessuna eccezione nella suite di prova
alla fine viene sempre eseguito

In 2]:

La suite try precedente visualizza un messaggio ma non solleva eccezioni. quando

il controllo del programma raggiunge con successo la fine della suite try, la clausola tranne è
saltato, la clausola else viene eseguita e la clausola finalmente mostra un messaggio

che viene sempre eseguito. Quando la clausola finalmente termina, il controllo del programma
continua con l'istruzione successiva dopo l'istruzione try. In una sessione IPython, il
successivo Nel prompt [] viene visualizzato.

Consideriamo ora un'istruzione try in cui si verifica un'eccezione nella suite try:

lecca qui per visualizzare l'immagine del codice

In [2]: prova :
...: print ( 'prova la suite che solleva un'eccezione' )
...: int ( 'ciao' )
...: print ( 'questo non verrà eseguito' )
...: tranne ValueError:
...: print ( 'si è verificato un errore ValueError' )
...: altro :
...: print ( 'altrimenti non verrà eseguito perché si è verificata un'eccezione' )
...: finalmente :
...: print ( 'alla fine viene sempre eseguito' )
...:
prova la suite che solleva un'eccezione
si è verificato un errore ValueError
alla fine viene sempre eseguito

In [3]:

Questa suite di prova inizia visualizzando un messaggio. La seconda affermazione tenta di farlo

converte la stringa 'hello' in un intero, che fa sì che la funzione int sollevi un

C
Pagina 369
ValueError. La suite di prova termina immediatamente, saltando l'ultima stampa
dichiarazione. La clausola tranne rileva l'eccezione ValueError e visualizza un file
Messaggio. La clausola else non viene eseguita perché si è verificata un'eccezione. Poi il

La clausola finalmente visualizza un messaggio che mostra che viene sempre eseguita. Quando il
la clausola finalmente termina, il controllo del programma continua con l'istruzione successiva
la dichiarazione try. In una sessione IPython, viene visualizzato il successivo prompt In [].

Combinando con Dichiarazioni e provare tranne Dichiarazioni

La maggior parte delle risorse che richiedono un rilascio esplicito, come file, connessioni di rete e
connessioni al database, hanno potenziali eccezioni associate all'elaborazione di quelle
risorse. Ad esempio, un programma che elabora un file potrebbe generare IOErrors. Per questo
motivo, un robusto codice di elaborazione dei file normalmente appare in una suite di prova contenente un con

dichiarazione per garantire che la risorsa venga rilasciata. Il codice è in una suite di prova, quindi
puoi intercettare ad eccezione dei gestori tutte le eccezioni che si verificano e non hai bisogno di un file

alla clausola infine perché l'istruzione with gestisce la deallocazione delle risorse.

Per dimostrarlo, prima supponiamo che tu stia chiedendo all'utente di fornire il nome di un file
file e forniscono quel nome in modo errato, come gradez.txt piuttosto che il file

abbiamo creato il file grades.txt precedente. In questo caso, la chiamata aperta solleva a

FileNotFoundError tentando di aprire un file inesistente:

lecca qui per visualizzare l'immagine del codice

In [3]: open ( 'gradez.txt' )

FileNotFoundError Traceback (la chiamata più recente last


ipythoninput3b7f41b2d5969> in <module> ()
> 1 aperto ( 'gradez.txt' )

FileNotFoundError : [Errno 2] Nessun file o directory di questo tipo: 'gradez.txt'

Per rilevare eccezioni come FileNotFoundError che si verificano quando si tenta di aprire un file

per la lettura, racchiudi l'istruzione with in una suite di prova, come in:

lecca qui per visualizzare l'immagine del codice

In [4]: prova :
...: con open ( 'gradez.txt' , 'r' ) come account:
...: print (f ' { "ID" : < 3 } { "Name" : < 7 } { "Grade" } ' )
...: per la registrazione nei conti:

C
<

...: student_id, nome, grado = record.split () Pagina 370


...: print (f ' {student_id: < 3 } {name: < 7 } {grade} ' )
...: tranne FileNotFoundError:
...: print ( 'Il nome del file che hai specificato non esiste' )
...:
Il nome del file specificato non esiste

9.10 SOLLEVARE ESPLICITAMENTE UN'ECCEZIONE


Hai visto varie eccezioni sollevate dal tuo codice Python. A volte potresti aver bisogno
per scrivere funzioni che sollevano eccezioni per informare i chiamanti degli errori che si verificano. Il

L' istruzione raise solleva esplicitamente un'eccezione. La forma più semplice di rilancio
dichiarazione è

raise ExceptionClassName

L'istruzione raise crea un oggetto della classe di eccezione specificata. Facoltativamente, il

il nome della classe di eccezione può essere seguito da parentesi contenenti argomenti per
inizializza l'oggetto eccezione, in genere per fornire una stringa di messaggio di errore personalizzata. Codice
che solleva un'eccezione prima dovrebbe rilasciare tutte le risorse acquisite prima dell'eccezione
si è verificato. Nella sezione successiva, mostreremo un esempio di come sollevare un'eccezione.

Nella maggior parte dei casi, quando è necessario sollevare un'eccezione, si consiglia di utilizzarne una
9
dei molti tipi di eccezione incorporati di Python elencati in:

9
Potresti essere tentato di creare classi di eccezioni personalizzate specifiche per il tuo
applicazione. Parleremo di più sulle eccezioni personalizzate nel prossimo capitolo.

ttps: //docs.python.org/3/library/exceptions.html
9.11 (OPZIONALE) SVOLGIMENTO PILA E
TRACCE
Ogni oggetto eccezione memorizza le informazioni che indicano la serie precisa di chiamate di funzione
che ha portato all'eccezione. Ciò è utile durante il debug del codice. Considera il
seguenti definizioni di funzione: funzione1 chiama funzione2 e funzione2

solleva un'eccezione:

lecca qui per visualizzare l'immagine del codice

In [1]: def function1 ():


...: funzione2 ()

h
C

...: Pagina 371

In [2]: def function2 ():


...: raise Exception ( 'Si è verificata un'eccezione' )
...:

La chiamata di function1 produce il seguente traceback. Per enfasi, abbiamo messo in grassetto
le parti del traceback che indicano le righe di codice che hanno portato all'eccezione:

lecca qui per visualizzare l'immagine del codice

In [3]: function1 ()

Eccezione Traceback (la chiamata più recente per ultima


ipythoninput3c0b3cafe2087> in <module> ()
> 1 funzione1 ()

<ipythoninput1a9f4faeeeb0c> in function1 ()
1 def funzione1 ():
> 2 funzione2 ()
3

<ipythoninput2c65e19d6b45b> in function2 ()
1 def funzione 2 ():
>2 solleva eccezione ( 'Si è verificata un'eccezione' )

Eccezione : si è verificata un'eccezione

Dettagli Traceback

Il traceback mostra il tipo di eccezione che si è verificata (Eccezione) seguita da


stack di chiamate di funzione completo che ha portato al punto di sollevamento. La chiamata alla funzione inferiore dello stack
è elencato per primo e l'inizio è l' ultimo , quindi l'interprete visualizza il testo seguente come file
promemoria:

Traceback (la chiamata più recente per ultima)

In questo traceback, il testo seguente indica il fondo dello stack di chiamate di funzione: il file
chiamata funzione1 nello snippet [3] (indicato da ipythoninput3):

<ipythoninput3c0b3cafe2087> in <module> ()
> 1 funzione1 ()

C
<
Pagina 372
Successivamente, vediamo quella funzione1 chiamata funzione2 dalla riga 2 nello snippet [1]:

<ipythoninput1a9f4faeeeb0c> in function1 ()
1 def funzione1 ():
> 2 funzione2 ()
3

Infine, vediamo il punto di aumento: in questo caso, la riga 2 nello snippet [2] ha sollevato l'eccezione:

<ipythoninput2c65e19d6b45b> in function2 ()
1 def funzione 2 ():
>2 solleva eccezione ( 'Si è verificata un'eccezione' )

Stack Svolgimento

Nei nostri precedenti esempi di gestione delle eccezioni, il punto di sollevamento si è verificato in una suite di prova,
e l'eccezione è stata gestita in una delle corrispondenti istruzioni try ad eccezione

gestori. Quando un'eccezione non viene catturata in una determinata funzione, impilare lo svolgimento
si verifica. Consideriamo lo svolgimento dello stack nel contesto di questo esempio:

Nella funzione2, l'istruzione raise solleva un'eccezione. Questo non è in una suite di prova,

così la funzione2 termina, il suo stack frame viene rimosso dallo stack di chiamata di funzione,
e il controllo ritorna all'istruzione nella funzione1 che ha chiamato la funzione2.

In funzione1, l'istruzione che ha chiamato funzione2 non è in una suite di prova, quindi

function1 termina, il suo stack frame viene rimosso dallo stack functioncall e
il controllo ritorna all'istruzione che ha chiamato function1 — snippet [3] in

Sessione IPython.

La chiamata nella chiamata snippet [3] non è in una suite di prova, quindi la chiamata di funzione termina.
Perché l'eccezione non è stato catturato (conosciuto come un eccezione non rilevata ),
IPython mostra il traceback, quindi attende il prossimo input. Se ciò è avvenuto in un file
0
script tipico, lo script terminerebbe.

0
Nelle applicazioni più avanzate che utilizzano thread, un'eccezione non rilevata
termina solo il thread in cui si verifica l'eccezione, non necessariamente l'intero
applicazione.

Suggerimento per leggere i trackback

Chiamerai spesso funzioni e metodi che appartengono a librerie di codice che non hai

Pagina 373
Scrivi. A volte quelle funzioni e metodi sollevano eccezioni. Durante la lettura di un file
traceback, inizia dalla fine del traceback e leggi prima il messaggio di errore. Poi,
leggere verso l'alto attraverso il traceback, cercando la prima riga che indica il codice
scritto nel tuo programma. In genere, questa è la posizione nel codice che ha portato al file
eccezione.

Eccezioni in infine Suites

Sollevare un'eccezione in una suite finalmente può portare a problemi sottili e difficili da trovare. Se
si verifica un'eccezione e non viene elaborata nel momento in cui viene eseguita la suite infine, stack
si verifica lo svolgimento. Se la suite infine solleva una nuova eccezione, la suite non lo fa
catch, la prima eccezione viene persa e la nuova eccezione viene passata al successivo contenitore

dichiarazione di prova. Per questo motivo, una suite finalmente dovrebbe sempre racchiudere in una prova
dichiarazione qualsiasi codice che possa sollevare un'eccezione, in modo che le eccezioni siano
elaborati all'interno di quella suite.

9.12 INTRO TO DATA SCIENCE: LAVORARE CON CSV


FILE
In questo libro, lavorerai con molti set di dati mentre presentiamo la datascience
concetti. CSV (valori separati da virgole) è un formato di file particolarmente popolare. Nel
in questa sezione, dimostreremo l'elaborazione dei file CSV con una libreria standard Python
modulo e panda.

9.12.1 Modulo libreria standard Python csv


1
Il modulo csv fornisce funzioni per lavorare con i file CSV. Molti altri messaggi di errore Python
le biblioteche hanno anche il supporto CSV incorporato.

1
ttps: //docs.python.org/3/library/csv.html .

Scrittura su un file CSV

Creiamo un file accounts.csv utilizzando il formato CSV. Il modulo csv's

la documentazione consiglia di aprire i file CSV con l'argomento parola chiave aggiuntivo
newline = '' per garantire che le nuove righe vengano elaborate correttamente:

lecca qui per visualizzare l'immagine del codice

In [1]: import csv

In [2]: con aperta ( 'accounts.csv' , mode = 'w' , a capo = '' ) come i conti:

C
1h

...: writer = csv.writer (account) Pagina 374


...: writer.writerow ([ 100 , 'Jones' , 24.98 ])
...: writer.writerow ([ 200 , 'Doe' , 345.67 ])
...: writer.writerow ([ 300 , 'White' , 0.00 ])
...: writer.writerow ([ 400 , 'Stone' , 42.16 ])
...: writer.writerow ([ 500 , 'Rich' , 224.62 ])
...:

L' estensione del file .csv indica un file CSVformat. Lo scrittore del modulo csv

la funzione restituisce un oggetto che scrive i dati CSV per l'oggetto file specificato. Ogni chiamata a
il metodo writerow del writer riceve un iterabile da memorizzare nel file. Eccoci qui

utilizzando elenchi. Per impostazione predefinita, writerow delimita i valori con virgole, ma è possibile specificarli
2
delimitatori personalizzati. Dopo lo snippet precedente, accounts.csv contiene:

2
TTP: //docs.python.org/3/library/csv.html#csvfmtparams .

100, Jones, 24.98


200, Doe, 345.67
300, bianco, 0,00
400, Stone, 42.16
500, Rich, 224.62

I file CSV generalmente non contengono spazi dopo le virgole, ma alcune persone li usano per
migliorare la leggibilità. Le chiamate writerow sopra possono essere sostituite con una writerows
call che restituisce un elenco separato da virgole di iterabili che rappresentano i record.

Se scrivi dati che contengono virgole all'interno di una data stringa, writerow le racchiude

stringa tra virgolette doppie. Ad esempio, considera il seguente elenco Python:


[ 100 , "Jones, Sue" , 24,98 ]

La stringa "Jones, Sue" con virgolette singole contiene una virgola che separa il cognome

e il nome. In questo caso, writerow produrrebbe il record come

100, "Jones, Sue", 24.98

Le virgolette intorno a "Jones, Sue" indicano che si tratta di un singolo valore. Programmi
leggerlo da un file CSV spezzerebbe il record in tre parti: 100, "Jones,

Sue 'e 24.98.

lettura da un file CSV


h1R

Lettura da un file CSV Pagina 375

Ora leggiamo i dati CSV dal file. Il frammento di codice seguente legge i record da
file accounts.csv e visualizza il contenuto di ogni record, producendo lo stesso
output che abbiamo mostrato in precedenza:

lecca qui per visualizzare l'immagine del codice

In [3]: con account aperti ( 'accounts.csv' , 'r' , newline = '' ) come account:
...: print (f ' { "Account" : < 10 } { "Name" : < 10 } { "Balance" :> 10 } ' )
...: reader = csv.reader (account)
...: per la registrazione nel lettore:
...: account, nome, saldo = record
...: print (f ' {account: < 10 } {name: < 10 } {balance:> 10 } ' )
...:
Saldo nome account
100 Jones 24.98
200 Doe 345.67
300 Bianco 0.0
400 Pietra 42.16
500 Rich 224.62

La funzione di lettura del modulo csv restituisce un oggetto che legge i dati CSVformat
dall'oggetto file specificato. Proprio come puoi scorrere un oggetto file, puoi farlo
iterare attraverso l'oggetto lettore una registrazione di valori limitati dalla comunicazione alla volta. Il
L'istruzione for precedente restituisce ogni record come un elenco di valori, in cui scompattiamo

le variabili account, nome e saldo, quindi vengono visualizzate.

Attenzione: virgole nei campi dati CSV

Fai attenzione quando lavori con stringhe contenenti virgole incorporate, come il nome

"Jones, Sue". Se lo inserisci accidentalmente come le due stringhe "Jones" e "Sue",


quindi writerow creerebbe, ovviamente, un record CSV con quattro campi, non tre .
I programmi che leggono i file CSV in genere si aspettano che ogni record abbia lo stesso numero di file
campi, altrimenti si verificano problemi. Ad esempio, considera i seguenti due elenchi:

[ 100 , "Jones" , "Sue" , 24,98 ]


[ 200 , "Doe" , 345,67 ]

Il primo elenco contiene quattro valori e il secondo ne contiene solo tre . Se questi due
record sono stati scritti nel file CSV, quindi letti in un programma utilizzando il precedente
snippet, la seguente istruzione fallisce quando si tenta di decomprimere il fourfield
registrare solo in tre variabili:

C
Pagina 376
account, nome, saldo = record

Attenzione: virgole e virgole aggiuntive mancanti nei file CSV

Fai attenzione durante la preparazione e l'elaborazione dei file CSV. Ad esempio, supponiamo che il tuo file sia
composto da record, ciascuno con quattro valori int separati da virgole, ad esempio:

100 , 85 , 77 , 9

Se ometti accidentalmente una di queste virgole, come in:

100 , 8577 , 9

quindi il record ha solo tre campi, uno con il valore non valido 8577.

Se metti due virgole adiacenti dove è previsto solo uno, come in:

100 , 85 , 77 , 9

allora hai cinque campi invece di quattro , e uno dei campi sarebbe erroneamente
vuoto . Ciascuno di questi errori correlati potrebbe confondere i programmi che tentano di elaborare
il disco.

9.12.2 Lettura di file CSV in Pandas DataFrame

Nelle sezioni Intro to Data Science dei due capitoli precedenti, ne abbiamo introdotti molti
i fondamenti dei panda. Qui, dimostriamo la capacità dei panda di caricare file in formato CSV,
quindi eseguire alcune attività di analisi dei dati di base.

Set di dati

Negli studi di casi di datascience, utilizzeremo vari set di dati gratuiti e aperti per
dimostrare i concetti di apprendimento automatico e di elaborazione del linguaggio naturale. C'e 'un
enorme varietà di set di dati gratuiti disponibili online. Il popolare repository Rdatasets
fornisce collegamenti a oltre 1100 set di dati gratuiti in formato CSV (valori separati da virgole).
Questi erano originariamente forniti con il linguaggio di programmazione R per le persone che imparavano
e lo sviluppo di software statistico, sebbene non siano specifici per R. Lo sono
ora disponibile su GitHub all'indirizzo:

Pagina 377
ttps: //vincentarelbundock.github.io/Rdatasets/datasets.html

Questo repository è così popolare che esiste un modulo pydataset specifico per

accedendo a Rdatasets. Per istruzioni sull'installazione di pydataset e sull'accesso ai set di dati


con esso, vedi:

ttps: //github.com/iamaziz/PyDataset

Un'altra grande fonte di set di dati è:

ttps: //github.com/awesomedata/awesomepublicdatasets
Un set di dati di machine learning comunemente usato per i principianti è il disastro del Titanic
set di dati , che elenca tutti i passeggeri e se sono sopravvissuti quando la nave
Il Titanic colpì un iceberg e affondò dal 14 al 15 aprile 1912. Lo useremo qui per mostrare come
caricare un dataset, visualizzare alcuni dei suoi dati e visualizzare alcune statistiche descrittive. Scaveremo
approfondire una varietà di set di dati popolari nei capitoli di datascience più avanti nel libro.

Lavorare con file CSV memorizzati localmente

Puoi caricare un set di dati CSV in un DataFrame con la funzione panda read_csv .
Quanto segue carica e visualizza il file CSV accounts.csv che hai creato in precedenza

in questo capitolo:

lecca qui per visualizzare l'immagine del codice

In [1]: importa i panda come pd

In [2]: df = pd.read_csv ( 'accounts.csv' ,


...: names = [ 'account' , 'name' , 'balance' ])
...:

In [3]: df
Fuori [3]:
saldo del nome del conto
0100 Jones 24.98
1200 Doe 345.67
2300 Bianco 0.00
3400 Pietra 42.16
4500 Ricco 224.62

L'argomento names specifica i nomi delle colonne del DataFrame. Senza questo

C
h

Pagina 378
argomento, read_csv presume che la prima riga del file CSV sia un elenco limitato dalla communità di

nomi di colonne.

Per salvare un DataFrame in un file utilizzando il formato CSV, chiama il metodo DataFrame to_csv :

lecca qui per visualizzare l'immagine del codice

In [4]: ​df.to_csv ( 'accounts_from_dataframe.csv' , index = False )

L'argomento della parola chiave index = False indica che i nomi delle righe (0–4 a ​sinistra di

l'output di DataFrame nello snippet [3]) non viene scritto nel file. Il file risultante
contiene i nomi delle colonne come prima riga:

conto, nome, saldo


100, Jones, 24.98
200, Doe, 345.67
300, bianco, 0,0
400, Stone, 42.16
500, Rich, 224.62

9.12.3 Lettura del set di dati di Titanic Disaster


Il set di dati del disastro del Titanic è uno dei set di dati di machine learning più popolari. Il
dataset è disponibile in molti formati, incluso CSV.

Caricamento del set di dati Titanic tramite un URL

Se hai un URL che rappresenta un set di dati CSV, puoi caricarlo in un DataFrame con
read_csv. Carichiamo il dataset Titanic Disaster direttamente da GitHub:

lecca qui per visualizzare l'immagine del codice

In [1]: importa i panda come pd

In [2]: titanic = pd.read_csv ( 'https://vincentarelbundock.github.io/' +


...: "Rdatasets / csv / carData / TitanicSurvival.csv" )
...:

Visualizzazione di alcune righe nel set di dati del Titanic

Questo set di dati contiene oltre 1300 righe, ciascuna delle quali rappresenta un passeggero. Secondo
3
Wikipedia, c'erano circa 1317 passeggeri e 815 di loro sono morti. Per grandi

1C

Pagina 379
set di dati, visualizzando il DataFrame mostra solo le prime 30 righe, seguite da "..." e

le ultime 30 righe. Per risparmiare spazio, visualizziamo le prime cinque e le ultime cinque righe con
Metodi DataFrame head and tail . Entrambi i metodi restituiscono cinque righe per impostazione predefinita, ma
puoi specificare il numero di righe da visualizzare come argomento:

3
ttps: //en.wikipedia.org/wiki/Passengers_of_the_RMS_Titanic .

lecca qui per visualizzare l'immagine del codice

In [3]: pd.set_option ( 'precision' , 2 ) # formato per valori in virgola mobile

n [4]: ​titanic.head ()
Fuori [4]:
Innominato: 0 è sopravvissuto all'età del sesso passengerClas
Allen, Miss. Elisabeth Walton sì donna 29.00 1s
Allison, maestro. Hudson Trevor sì maschio 0,92 1s
Allison, Miss. Helen Loraine nessuna femmina 2.00 1s
Allison, Mr. Hudson Joshua Crei nessun maschio 30.00 1s
Allison, Mrs.Hudson J C (Bessi no female 25.00 1s

n [5]: titanic.tail ()
Fuori [5]:
Innominato: 0 è sopravvissuto all'età del sesso passengerClass
1304 Zabour, Miss. Hileni nessuna donna 14,50 3 °
1305 Zabour, Miss. Thamine nessuna femmina NaN 3rd
1306 Zakarian, Sig. Mapriededer nessun maschio 26,50 3 °
1307 Zakarian, Sig.Ortin nessun maschio 27,00 3 °
1308 Zimmerman, Sig. Leo no maschio 29,00 3 °

Nota che i panda regolano la larghezza di ogni colonna, in base al valore più ampio nella colonna
o in base al nome della colonna, a seconda di quale sia il più ampio. Inoltre, nota il valore nell'età
la colonna della riga 1305 è NaN (non un numero), che indica un valore mancante nel set di dati.

Personalizzazione dei nomi delle colonne

La prima colonna di questo set di dati ha un nome strano ("Senza nome: 0"). Possiamo pulire

ciò impostando i nomi delle colonne. Cambiamo "Senza nome: 0" in "nome" e andiamo
abbreviare "passengerClass" in "class":

lecca qui per visualizzare l'immagine del codice

In [6]: titanic.columns = [ 'name' , ' survived ' , 'sex' , 'age' , 'class' ]

In [7]: titanic.head ()
Fuori [7]:

1C
01234iho
io
Pagina 380
nome sopravvissuto alla classe di età sessuale
0 Allen, Miss. Elisabeth Walton sì donna 29.00 1 °
1 Allison, maestro. Hudson Trevor sì maschio 0,92 1 °
2 Allison, Miss. Helen Loraine nessuna femmina 2.00 1 °
3 Allison, Mr. Hudson Joshua Crei nessun maschio 30.00 1 °
4 Allison, Mrs.Hudson J C (Bessi no female 25.00 1st

9.12.4 Analisi dei dati semplice con il set di dati di Titanic Disaster
Ora puoi usare i panda per eseguire alcune semplici analisi. Ad esempio, diamo un'occhiata a
alcune statistiche descrittive. Quando chiami Descrivi su un DataFrame contenente entrambi
colonne numeriche e non numeriche, descrivere calcola queste statistiche solo per
colonne numeriche, in questo caso solo la colonna dell'età:

In [8]: titanic.describe ()
Fuori [8]:
età
contare 1046.00
significa 29,88
std 14.41
min 0,17
25% 21.00
50% 28.00
75% 39,00
max 80,00

Notare la discrepanza nel conteggio (1046) rispetto al numero di righe del set di dati (1309: il
l'indice dell'ultima riga era 1308 quando abbiamo chiamato tail). Solo 1046 (il conteggio sopra) del

i record contenevano un valore di età. Gli altri erano mancanti e contrassegnati come NaN, come in fila

1305. Quando si eseguono i calcoli, Pandas ignora i dati mancanti ( NaN ) per impostazione predefinita .
Per le 1046 persone con età valida, l'età media (media) era di 29,88 anni. Il
il passeggero più giovane (min) aveva poco più di due mesi (0,17 * 12 è 2,04) e il

il più vecchio (massimo) era 80. L'età media era 28 (indicata dal 50% quartile). Il 25%
quartile è l'età media nella prima metà dei passeggeri (ordinati per età), e il 75%
quartile è la mediana della seconda metà dei passeggeri.

Supponiamo che tu voglia determinare alcune statistiche sulle persone che sono sopravvissute. Noi possiamo
confronta la colonna sopravvissuta con "sì" per ottenere una nuova serie contenente

Valori Vero / Falso, quindi utilizza Descrivi per riepilogare i risultati:

lecca qui per visualizzare l'immagine del codice

In [9]: (titanic.survived == 'yes' ) .describe ()

Fuori [9]: Pagina 381


contare 1309
unico 2
top False
freq 809
Nome: sopravvissuto, dtype: object

Per i dati non numerici, descrivere visualizza diverse statistiche descrittive:

count è il numero totale di elementi nel risultato.

unico è il numero di valori univoci (2) nel risultato: Vero (sopravvissuto) e


Falso (morto).
top è il valore che ricorre più di frequente nel risultato.

freq è il numero di occorrenze del valore superiore.

9.12.5 Istogramma dell'età dei passeggeri


La visualizzazione è un bel modo per conoscere i tuoi dati. Pandas ha molti builtin
capacità di visualizzazione implementate con Matplotlib. Per usarli, prima
abilita il supporto Matplotlib in IPython:

In [10]:% matplotlib

Un istogramma visualizza la distribuzione dei dati numerici su un intervallo di valori. UN

Il metodo hist di DataFrame analizza automaticamente i dati di ciascuna colonna numerica e


produce un istogramma corrispondente. Per visualizzare gli istogrammi di ogni dato numerico
colonna, chiama hist sul tuo DataFrame:

lecca qui per visualizzare l'immagine del codice

In [11]: histogram = titanic.hist ()

Il set di dati del Titanic contiene solo una colonna di dati numerici, quindi mostra il diagramma
un istogramma per la distribuzione per età. Per i set di dati con più colonne numeriche,
hist crea un istogramma separato per ogni colonna numerica.

C
Pagina 382

9.13 WRAP-UP
In questo capitolo abbiamo introdotto l'elaborazione dei file di testo e la gestione delle eccezioni. I file sono
utilizzato per memorizzare i dati in modo persistente. Abbiamo discusso gli oggetti file e menzionato che Python
visualizza un file come una sequenza di caratteri o byte. Abbiamo anche menzionato il file standard
oggetti che vengono creati automaticamente quando inizia l'esecuzione di un programma Python.

Abbiamo mostrato come creare, leggere, scrivere e aggiornare file di testo. Ne abbiamo presi in considerazione diversi
formati di file più diffusi: testo semplice, JSON (JavaScript Object Notation) e CSV (virgola
valori separati). Abbiamo usato la funzione builtin open e l'istruzione with per aprire
un file, scrivere o leggere dal file e chiudere automaticamente il file per impedire la risorsa
perde quando l'istruzione with termina. Abbiamo usato la libreria standard di Python

json per serializzare gli oggetti in formato JSON e archiviarli in un file, caricare JSON
oggetti da un file, deserializzali in oggetti Python e stampa in modo carino un oggetto JSON
per la leggibilità.

Abbiamo discusso di come le eccezioni indicano problemi di tempo di esecuzione e ne abbiamo elencati i vari
eccezioni che hai già visto. Abbiamo mostrato come gestire le eccezioni avvolgendo
codice nelle istruzioni try che forniscono clausole tranne per gestire tipi specifici di

eccezioni che possono verificarsi nella suite di prova, rendendo i tuoi programmi più robusti e
tollerante agli errori.

Pagina 383
Abbiamo discusso la clausola finalmente dell'istruzione try per l'esecuzione del codice if flusso del programma

inserito nella suite di prova corrispondente. Puoi usare l'istruzione with o una try
la clausola finalmente dell'istruzione per questo scopo: preferiamo l'istruzione with.

Nella sezione Intro to Data Science, abbiamo utilizzato sia il file csv della Python Standard Library

modulo e capacità della libreria pandas per caricare, manipolare e archiviare dati CSV.
Infine, abbiamo caricato il set di dati del disastro del Titanic in un DataFrame panda, modificato

alcuni nomi di colonne per la leggibilità, visualizzati la testa e la coda del set di dati e
eseguito semplice analisi dei dati. Nel prossimo capitolo, discuteremo di Python
capacità di programmazione orientata agli oggetti.

https://avxhm.se/blogs/hill0
W
Pagina 384

laylist

storia
10. Programmazione orientata agli oggetti
opiche
Obiettivi

In questo capitolo potrai:


guadagnando Pat

Crea classi e oggetti personalizzati di tali classi.


ffers & Dea

Comprendi i vantaggi della creazione di classi preziose.


ighlights

Controlla l'accesso agli attributi.


ettings

Apprezza il valore dell'orientamento agli oggetti.


Supporto

Usa i metodi speciali di Python __repr__, __str__ e __format__ per ottenere un oggetto
Disconnessione
rappresentazioni di stringa.

Usa metodi speciali Python per sovraccaricare (ridefinire) gli operatori per usarli con oggetti di
nuove classi.

Eredita metodi, proprietà e attributi da classi esistenti a nuove classi, quindi


personalizzare quelle classi.

Comprendere le nozioni di ereditarietà delle classi base (superclassi) e delle classi derivate
(sottoclassi).

Comprendere la dattilografia e il polimorfismo che consentono la "programmazione in generale".

Comprendere l'oggetto della classe da cui tutte le classi ereditano le capacità fondamentali.

Confronta composizione ed eredità.

Crea casi di test in docstrings ed esegui questi test con doctest,

Comprendere gli spazi dei nomi e il modo in cui influenzano l'ambito.

Contorno

0.1 Introduzione

0.2 Account di classe personalizzato

0.2.1 Account della classe TestDriving Pagina 385

0.2.2 Definizione della classe di conto

0.2.3 Composizione: riferimenti a oggetti come membri di classi

0.3 Controllo dell'accesso agli attributi

0.4 Proprietà per l'accesso ai dati

0.4.1 TestDriving Class Time

0.4.2 Definizione dell'orario di lezione

0.4.3 Note di progettazione per la definizione del tempo di lezione


0.5 Simulazione di attributi "privati"

0.6 Case Study: Mescolamento di carte e simulazione di negoziazione

0.6.1 Classi TestDriving Card e DeckOfCards

0.6.2 Carta di classe — Introduzione agli attributi di classe

0.6.3 Classe DeckOfCards

0.6.4 Visualizzazione delle immagini dei biglietti con Matplotlib

0.7 Ereditarietà: classi base e sottoclassi

0.8 Costruire una gerarchia di ereditarietà; Introduzione al polimorfismo

0.8.1 Commissione di Classe Base Dipendente

0.8.2 Sottoclasse SalariedCommissionEmployee

0.8.3 Commissioni di elaborazioneDipendenti e dipendenti della Commissione stipendiati

olymorphically

0.8.4 Una nota sulla programmazione ObjectBased e ObjectOriented

0.9 Duck Typing and Polymorphism

0.10 Sovraccarico dell'operatore

0.10.1 Complesso di classi TestDriving

0.10.2 Definizione del complesso di classi

1P

0.11 Gerarchia delle classi di eccezioni ed eccezioni personalizzate


Pagina 386

0.12 Tuple con nome

0.13 Una breve introduzione alle nuove classi di dati di Python 3.7

0.13.1 Creazione di una classe di dati della carta

0.13.2 Utilizzo della classe di dati della carta

0.13.3 Vantaggi delle classi di dati rispetto alle tuple con nome

0.13.4 Vantaggi delle classi di dati rispetto alle classi tradizionali

0.14 Unit test con Docstrings e doctest

0.15 Spazi dei nomi e ambiti

0.16 Introduzione alla scienza dei dati: serie storiche e regressione lineare semplice

0.17 WrapUp

10.1 INTRODUZIONE
La sezione 1.2 ha introdotto la terminologia e i concetti di base della programmazione orientata agli oggetti.
Tutto in Python è un oggetto, quindi hai utilizzato costantemente oggetti durante tutto questo
libro. Proprio come le case sono costruite da progetti, gli oggetti sono costruiti da classi, una delle principali
tecnologie di programmazione orientata agli oggetti. Costruire un nuovo oggetto anche da una grande classe lo è
semplice: in genere scrivi una dichiarazione.

Creazione di classi preziose


Hai già utilizzato molte classi create da altre persone. In questo capitolo creerai il tuo file
possedere classi personalizzate . Ti concentrerai sulla "creazione di classi preziose" che ti aiuteranno a soddisfare le
requisiti delle applicazioni che creerai. Userai la programmazione orientata agli oggetti con i suoi file
tecnologie di base di classi, oggetti, ereditarietà e polimorfismo. Applicazioni software
stanno diventando più grandi e più riccamente funzionali. La programmazione orientata agli oggetti lo fa
più facile per te progettare, implementare, testare, eseguire il debug e aggiornare tali margini della pratica
applicazioni. Leggere sezioni da 10.1 a 0.9 per un'introduzione intensiva di codice a questi
tecnologie. La maggior parte delle persone può ezioni
saltareda 10.10 a 0.15, che forniscono ulteriori
prospettive su queste tecnologie e presentare funzionalità correlate aggiuntive.

Librerie di classi e programmazione basata su oggetti

La stragrande maggioranza della programmazione orientata agli oggetti che farai in Python è basata sugli oggetti
programmazione in cui crei e utilizzi principalmente oggetti di classi esistenti . Sei stato
facendo questo in tutto il libro con tipi incorporati come int, float, str, list, tuple, dict

1S

nd set, con tipi di libreria standard Python come Decimal e con array NumPy,
Pagina 387

Figure e assi Matplotlib e serie di panda e DataFrame.

Per trarre il massimo vantaggio da Python è necessario familiarizzare con molti elementi preesistenti
classi. Nel corso degli anni, la comunità opensource di Python ha creato un numero enorme
di classi preziose e li ha impacchettati in librerie di classi. Questo lo rende facile da riutilizzare
classi esistenti piuttosto che "reinventare la ruota". Classi di libreria opensource ampiamente utilizzate
hanno maggiori probabilità di essere accuratamente testati, privi di bug, ottimizzati per le prestazioni e portatili su un file
ampia gamma di dispositivi, sistemi operativi e versioni di Python. Troverai abbondante Python
librerie su Internet su siti come GitHub, BitBucket, Source Forge e altri ancora, più facilmente
installato con conda o pip. Questa è una delle ragioni principali della popolarità di Python. La stragrande maggioranza

delle classi di cui avrai bisogno saranno probabilmente disponibili gratuitamente nelle librerie opensource.

Creazione di classi personalizzate

Le classi sono nuovi tipi di dati. Ogni classe della libreria standard Python e classe della libreria di terze parti
è un tipo personalizzato creato da qualcun altro. In questo capitolo, svilupperai applicazioni specifiche
classi, come CommissionEmployee, Time, Card, DeckOfCards e altro.

La maggior parte delle applicazioni che creerai per il tuo uso personale normalmente non usa classi personalizzate
o solo alcuni. Se diventi parte di un team di sviluppo nell'industria, potresti lavorarci su
applicazioni che contengono centinaia o addirittura migliaia di classi. Puoi contribuire con il tuo
classi personalizzate alla comunità opensource di Python, ma non sei obbligato a farlo.
Le organizzazioni hanno spesso politiche e procedure relative al codice di opensourcing.

Eredità

Forse la cosa più eccitante è l'idea che nuove classi possano essere formate attraverso l'ereditarietà e
composizione da classi in abbondanti librerie di classi . Alla fine, verrà costruito il software
prevalentemente da componenti standardizzati e riutilizzabili proprio come l'hardware
costruito da parti intercambiabili oggi. Questo aiuterà ad affrontare le sfide di
sviluppare software sempre più potenti.

Quando crei una nuova classe, invece di scrivere tutto il nuovo codice, puoi designare che il nuovo
class deve essere formato inizialmente ereditando gli attributi (variabili) e i metodi (la classe
versione delle funzioni) di una classe base definita in precedenza (chiamata anche superclasse ). Il nuovo
è chiamata classe derivata (o sottoclasse ). Dopo aver ereditato, personalizzi il file
classe derivata per soddisfare le esigenze specifiche dell'applicazione. Per ridurre al minimo la personalizzazione
sforzo, dovresti sempre provare ad ereditare dalla classe base più vicina alle tue esigenze. Fare
in modo efficace, dovresti familiarizzare con le librerie di classi che sono orientate a
tipi di applicazioni che creerai.

Polimorfismo

Spieghiamo e dimostriamo il polimorfismo , che consente di programmare comodamente


"In generale" piuttosto che "nello specifico". È sufficiente inviare la stessa chiamata al metodo agli oggetti
possibilmente di molti tipi diversi . Ogni oggetto risponde "facendo la cosa giusta". Quindi lo stesso
un'
La chiamata etodo assume "molte forme", da cui il termine "polimorfismo". Ti spiegheremo come farlo
Pagina 388

implementare il polimorfismo attraverso l'ereditarietà e una funzionalità Python chiamata dattilografia. Bene
spiegare entrambi e mostrare esempi di ciascuno.

Un caso di studio divertente: simulazione di mescolamento e scambio di carte

Hai già utilizzato una simulazione di dierolling basata su numeri casuali e li hai utilizzati
tecniche per implementare il popolare gioco di dadi craps. Qui, presentiamo un cardshufflingand
simulazione di negoziazione, che puoi utilizzare per implementare i tuoi giochi di carte preferiti. Userai
Matplotlib con attraenti immagini di carte di dominio pubblico per visualizzare l'intero mazzo di carte sia
prima e dopo che il mazzo viene mescolato.

Classi di dati

Le nuove classi di dati di Python 3.7 ti aiutano a costruire classi più velocemente utilizzando una notazione più concisa
e generando automaticamente porzioni delle classi. La prima reazione della comunità Python ai dati
le lezioni sono state positive. Come con qualsiasi nuova funzionalità importante, potrebbe essere necessario del tempo prima che sia ampiamente diffusa
Usato. Presentiamo lo sviluppo delle classi con le tecnologie più vecchie e più recenti.

Altri concetti introdotti in questo capitolo

Altri concetti che presentiamo includono:

Come specificare che determinati identificatori dovrebbero essere usati solo all'interno di una classe e non essere
accessibile ai clienti della classe.

Metodi speciali per creare rappresentazioni di stringa degli oggetti delle classi e specificare
come gli oggetti delle tue classi funzionano con gli operatori incorporati di Python (un processo chiamato
sovraccarico dell'operatore ).

Un'introduzione alla gerarchia delle classi di eccezioni Python e alla creazione di eccezioni personalizzate
classi.

Testare il codice con il modulo doctest della Python Standard Library.

Come Python usa gli spazi dei nomi per determinare gli ambiti degli identificatori.

10.2 CONTO CLASSE PERSONALIZZATO


Cominciamo con una classe di conto bancario che contiene il nome e il saldo del titolare del conto. Un

la classe del conto corrente bancario potrebbe includere molte altre informazioni, come indirizzo,
data di nascita, numero di telefono, numero di conto e altro. La classe Account accetta

depositi che aumentano il saldo e prelievi che diminuiscono il saldo.

10.2.1 Conto della classe di prova

Ogni nuova classe creata diventa un nuovo tipo di dati che può essere utilizzato per creare oggetti. Questo è
uno dei motivi per cui si dice che Python sia un linguaggio estensibile . Prima di guardare in classe

m
Pagina 389
Definizione dell'account, dimostriamo le sue capacità.

Importazione di account classi e decimali

Per utilizzare la nuova classe Account, avvia la tua sessione IPython dalla cartella degli esempi ch10,
quindi importa l'account della classe:

lecca qui per visualizzare l'immagine del codice

In [1]: da account import Account

Il conto di classe mantiene e manipola il saldo del conto come un decimale, quindi anche noi

import class Decimal:


lecca qui per visualizzare l'immagine del codice

In [2]: da decimal import Decimal

Crea un oggetto account con un'espressione del costruttore

Per creare un oggetto Decimal, possiamo scrivere:

valore = Decimale ( '12 .34 ' )

Questa è nota come espressione del costruttore perché costruisce e inizializza un oggetto di
classe, simile al modo in cui una casa è costruita da un progetto poi dipinto con l'acquirente
colori preferiti. Le espressioni del costruttore creano nuovi oggetti e inizializzano i dati utilizzando
argomento / i specificato / i tra parentesi. Le parentesi che seguono il nome della classe sono obbligatorie,
anche se non ci sono argomenti.

Usiamo un'espressione del costruttore per creare un oggetto Account e inizializzarlo con un file
nome del titolare del conto (una stringa) e saldo (un decimale):

lecca qui per visualizzare l'immagine del codice

In [3]: account1 = Account ( 'John Green' , Decimal ( '50 .00 ' ))

Ottenere il nome e il saldo di un account

Accediamo al nome dell'oggetto Account e agli attributi del saldo:

lecca qui per visualizzare l'immagine del codice

In [4]: ​account1.name
Uscita [4]: ​"John Green"

C
In [5]: account1.balance Pagina 390
Fuori [5]: Decimale ('50 .00 ')

Depositare denaro su un conto

Il metodo di deposito di un conto riceve un importo in dollari positivo e lo aggiunge al saldo:

lecca qui per visualizzare l'immagine del codice

In [6]: account1.deposit (Decimal ( '25 .53 ' ))

In [7]: account1.balance
Fuori [7]: Decimale ('75 .53 ')

I metodi dell'account eseguono la convalida

I metodi dell'account di classe convalidano i loro argomenti. Ad esempio, se l'importo di un deposito è


negativo, il deposito genera un'eccezione ValueError:

lecca qui per visualizzare l'immagine del codice

In [8]: account1.deposit (Decimal ( '123.45' ))

ValueError Traceback (la chiamata più recente per ultima)


<ipythoninput827dc468365a7> in <module> ()
> 1 account1.deposit (Decimale ( '123.45' ))

~ / Documents / examples / ch10 / account.py in deposito (self, amount)


21 # se l'importo è inferiore a 0,00, solleva un'eccezione
22 se importo <Decimale ( '0.00' ):
> 23 raise ValueError ( 'L'importo del deposito deve essere positivo.' )
24
25 self.balance + = importo

ValueError : l'importo del deposito deve essere positivo.


10.2.2 Definizione della classe di conto

Ora, diamo un'occhiata alla definizione della classe di Account, che si trova nel file account.py.

Definizione di una classe

Una definizione di classe inizia con la parola chiave class (riga 5) seguita dal nome della classe e da a
due punti (:). Questa riga è chiamata intestazione della classe . La guida allo stile per il codice Python

consiglia di iniziare ogni parola in un nome di classe composto da più parole con una lettera maiuscola
(ad esempio, CommissionEmployee). Ogni istruzione nella suite di una classe è rientrata.

lecca qui per visualizzare l'immagine del codice

1 # account.py

C
2 "" "Definizione della classe di conto." "" Pagina 391
3 da decimale importazione decimale
4
Conto di 5 classi :
6 "" "Classe di conto per mantenere il saldo di un conto bancario." ""
7

Ogni classe fornisce tipicamente una docstring descrittiva (riga 6). Quando fornito, deve apparire
nella riga o nelle righe immediatamente successive all'intestazione della classe. Per visualizzare la docstring di qualsiasi classe in
IPython, digita il nome della classe e un punto interrogativo, quindi premi Invio :

lecca qui per visualizzare l'immagine del codice

In [9]: Account?
firma nit: conto (nome, saldo)
Docstring: classe di conto per mantenere il saldo di un conto bancario.
Init docstring: inizializza un oggetto Account.
File: ~ / Documents / examples / ch10 / account.py
Tipo: tipo

L'identificatore Account è sia il nome della classe che il nome utilizzato in un'espressione del costruttore
per creare un oggetto Account e invocare il metodo __init__ della classe. Per questa ragione,

Il meccanismo di aiuto di IPython mostra sia la docstring della classe ("Docstring:") e il file

docstring del metodo __init__ ("Init docstring:").

Inizializzazione degli oggetti account: metodo __init__

L'espressione del costruttore nello snippet [3] della sezione precedente:

lecca qui per visualizzare l'immagine del codice

account1 = Account ( 'John Green' , Decimal ( '50 .00 ' ))

crea un nuovo oggetto, quindi inizializza i suoi dati chiamando il metodo __init__ della classe . Ogni
la nuova classe che crei può fornire un metodo __init__ che specifica come inizializzare un file

attributi dei dati dell'oggetto. Restituendo un valore diverso da None da __init__ si ottiene un

TypeError. Ricorda che None viene restituito da qualsiasi funzione o metodo che non contiene un file

dichiarazione di ritorno. Il metodo __init__ dell'account di classe (righe 8-16) inizializza un account
nome dell'oggetto e attributi del saldo se il saldo è valido:

lecca qui per visualizzare l'immagine del codice

8 def __init __ (self, name, balance):


9 "" "Inizializza un oggetto Account." ""
10
11 # se il saldo è inferiore a 0,00, solleva un'eccezione
12 se saldo <Decimale ( '0.00' ):
13 raise ValueError ( 'Il saldo iniziale deve essere> = a 0.00.' )
C
io

14 Pagina 392
15 self.name = nome
16 self.balance = equilibrio
17

Quando chiami un metodo per un oggetto specifico, Python passa implicitamente un riferimento a quello
oggetto come primo argomento del metodo. Per questo motivo, tutti i metodi di una classe devono specificare at
almeno un parametro. Per convenzione la maggior parte dei programmatori Python chiama il primo metodo
parametro self. I metodi di una classe devono usare quel riferimento (self) per accedere all'oggetto
attributi e altri metodi. Il metodo __init__ dell'account di classe specifica anche i parametri

per il nome e l'equilibrio.

L'istruzione if convalida il parametro balance. Se il saldo è inferiore a 0,00,

__init__ solleva un'eccezione ValueError, che termina il metodo __init__. Altrimenti, il file
Il metodo crea e inizializza il nome del nuovo oggetto Account e gli attributi del saldo.

Quando viene creato un oggetto della classe Account, non ha ancora alcun attributo. Loro sono

aggiunto dinamicamente tramite assegnazioni del modulo:

se stesso. nome_attributo = valore

Le classi Python possono definire molti metodi speciali , come __init__, ognuno identificato da
doubleundercores iniziale e finale (__) nel nome del metodo. Oggetto classe Python ,

di cui parleremo più avanti in questo capitolo, definisce i metodi speciali disponibili per tutti
Oggetti Python.

Deposito metodo

Il metodo di deposito della classe Conto aggiunge un importo positivo al saldo del conto
attributo. Se l'argomento importo è minore di 0,00, il metodo genera un'eccezione ValueError,

indicando che sono consentiti solo importi di deposito positivi. Se l'importo è valido, la riga 25 aggiunge
all'attributo balance dell'oggetto.

lecca qui per visualizzare l'immagine del codice

18 deposito def (auto, importo):


19 "" "Deposita denaro sul conto." ""
20
21 # se l'importo è inferiore a 0,00, solleva un'eccezione
22 se importo <Decimale ( '0.00' ):
23 raise ValueError ( 'importo deve essere positivo.' )
24
25 self.balance + = importo

10.2.3 Composizione: riferimenti a oggetti come membri di classi


Un account ha un nome e un account ha un saldo. Ricorda che “tutto in Python

è un oggetto. " Ciò significa che gli attributi di un oggetto sono riferimenti a oggetti di altre classi. Pagina 393

Ad esempio, l'attributo name di un oggetto Account è un riferimento a un oggetto stringa e un file

L'attributo del saldo dell'oggetto Conto è un riferimento a un oggetto Decimale. Incorporamento


i riferimenti a oggetti di altri tipi sono una forma di riutilizzabilità del software nota come composizione
ed è a volte indicato come la relazione "ha una" . Più avanti in questo capitolo, lo faremo
discutere l' eredità , che stabilisce le relazioni "è un" .

10.3 CONTROLLO DELL'ACCESSO AGLI ATTRIBUTI


I metodi di Class Account convalidano i loro argomenti per garantire che il saldo sia sempre

valido, ovvero sempre maggiore o uguale a 0,00. Nell'esempio precedente, abbiamo utilizzato l'estensione
nome degli attributi e saldo solo per ottenere i valori di quegli attributi. Si scopre che noi
può anche utilizzare questi attributi per modificare i propri valori. Considera l'oggetto Account in
seguente sessione IPython:
lecca qui per visualizzare l'immagine del codice

In [1]: da account import Account

In [2]: da decimal import Decimal

In [3]: account1 = Account ( 'John Green' , Decimal ( '50 .00 ' ))

In [4]: ​account1.balance
Fuori [4]: ​Decimale ('50 .00 ')

Inizialmente, account1 contiene un saldo valido. Ora, impostiamo l'attributo balance su un file

valore negativo non valido , quindi visualizzare il saldo:

lecca qui per visualizzare l'immagine del codice

In [5]: account1.balance = Decimal ( '1000.00' )

In [6]: account1.balance
In uscita [6]: decimale ("1000,00")

L'output dello snippet [6] mostra che il saldo di account1 è ora negativo. Come potete vedere,
a differenza dei metodi, gli attributi dei dati non possono convalidare i valori assegnati loro.

Incapsulamento

Il codice client di una classe è qualsiasi codice che utilizza gli oggetti della classe. La maggior parte orientata agli oggetti
i linguaggi di programmazione consentono di incapsulare (o nascondere ) i dati di un oggetto dal client
codice. Tali dati in queste lingue si dice che siano dati privati .

Leading Underscore (_) Naming Convention

Python non ha dati privati. Invece, usi le convenzioni di denominazione per progettare le classi

che incoraggiano un uso corretto. Per convenzione, i programmatori Python sanno che qualsiasi attributo
Pagina 394

il nome che inizia con un trattino basso (_) è solo per uso interno di una classe . Il codice client dovrebbe

usa i metodi della classe e, come vedrai nella prossima sezione, le proprietà della classe per
interagire con gli attributi dei dati di uso interno di ogni oggetto. Attributi i cui identificatori non lo fanno
iniziano con un trattino basso (_) sono considerati pubblicamente accessibili per l'uso nel codice client. Nel
nella prossima sezione, definiremo una classe Time e utilizzeremo queste convenzioni di denominazione. Tuttavia, anche

quando usiamo queste convenzioni, gli attributi sono sempre accessibili.

10.4 PROPRIETÀ DI ACCESSO AI DATI


Sviluppiamo una classe Time che memorizzi l'ora nel formato 24 ore con le ore nel formato

intervallo 0–23 e minuti e secondi ciascuno nell'intervallo 0–59. Per questo corso, forniremo
proprietà , che sembrano attributi di dati ai programmatori di codice client, ma controllano il file
modo in cui ottengono e modificano i dati di un oggetto. Ciò presuppone che altri programmatori
segui le convenzioni di Python per utilizzare correttamente gli oggetti della tua classe.

10.4.1 Durata della lezione di guida

Prima di esaminare la definizione della classe Time, dimostriamo le sue capacità. Innanzitutto, assicurati che
sei nella cartella ch10, quindi importa la classe Time da timewithproperties.py:

lecca qui per visualizzare l'immagine del codice

In [1]: from timewithproperties import Time

Creazione di un oggetto temporale

Quindi, creiamo un oggetto Time. Il metodo __init__ di Class Time ha ore, minuti e

secondi parametri, ciascuno con un valore di argomento predefinito pari a 0. Qui, specifichiamo l'ora e
minuto: il secondo valore predefinito è 0:
lecca qui per visualizzare l'immagine del codice

In [2]: wake_up = Time (hour = 6 , minute = 30 )

Visualizzazione di un oggetto temporale

Class Time definisce due metodi che producono rappresentazioni di stringa dell'oggetto Time. quando
si valuta una variabile in IPython come nello snippet [3], IPython chiama __repr__ dell'oggetto

metodo speciale per produrre una rappresentazione di stringa dell'oggetto. Il nostro __repr__
l'implementazione crea una stringa nel seguente formato:

lecca qui per visualizzare l'immagine del codice

In [3]: wake_up

C
Out [3]: Time (ora = 6, minuti = 30, secondi = 0) Pagina 395

Forniremo anche il metodo speciale __str__, che viene chiamato quando un oggetto viene convertito
1
su una stringa, ad esempio quando esegui l'output dell'oggetto con print . La nostra implementazione di __str__
crea una stringa in formato 12 ore:

1
Se una classe non fornisce __str__ e un oggetto della classe viene convertito in una stringa, il file

viene invece chiamato il metodo __repr__ della classe.

In [4]: ​print (wake_up)


6:30:00

Ottenere un attributo tramite una proprietà

Tempo di classe fornisce ora, minuti e secondi proprietà , che forniscono la comodità
di attributi di dati per ottenere e modificare i dati di un oggetto. Tuttavia, come vedrai,
le proprietà sono implementate come metodi, quindi possono contenere logica aggiuntiva, come
specificando il formato in cui restituire il valore di un attributo di dati o convalidando un nuovo valore
prima di usarlo per modificare un attributo di dati. Qui, otteniamo il valore orario dell'oggetto wake_up:

In [5]: wake_up.hour
Fuori [5]: 6

Sebbene questo frammento sembri ottenere semplicemente il valore dell'attributo dei dati di un'ora, in realtà è una chiamata a
un metodo hour che restituisce il valore di un attributo di dati (che abbiamo chiamato _hour, come farai

vedere nella sezione successiva).

Impostazione dell'ora

È possibile impostare un nuovo orario con il metodo set_time dell'oggetto Time. Come il metodo __init__,
Il metodo set_time fornisce i parametri di ora, minuti e secondi, ciascuno con un valore predefinito

0:

lecca qui per visualizzare l'immagine del codice

In [6]: wake_up.set_time (ora = 7 , minuto = 45 )

In [7]: wake_up
Out [7]: Time (ora = 7, minuti = 45, secondi = 0)

Impostazione di un attributo tramite una proprietà

Class Time supporta anche l'impostazione di ore, minuti e secondi individualmente tramite il suo
proprietà. Cambiamo il valore dell'ora in 6:

lecca qui per visualizzare l'immagine del codice


C
Pagina 396
In [8]: wake_up.hour = 6

In [9]: wake_up
Out [9]: Time (ora = 6, minuti = 45, secondi = 0)

Sebbene lo snippet [8] sembri semplicemente assegnare un valore a un attributo di dati, in realtà è una chiamata a

un metodo ora che richiede 6 come argomento. Il metodo convalida il valore, quindi lo assegna
a un attributo di dati corrispondente (che abbiamo chiamato _hour, come vedrai nella sezione successiva).

Tentativo di impostare un valore non valido

Per dimostrare che le proprietà della classe Time convalidano i valori che le assegni, proviamo a farlo
assegna un valore non valido alla proprietà hour, che risulta in un ValueError:

lecca qui per visualizzare l'immagine del codice

In [10]: wake_up.hour = 100

ValueError Traceback (la chiamata più recente per ultima)


<ipythoninput101fce0716ef14> in <module> ()
> 1 wake_up.hour = 100

~ / Documents / examples / ch10 / timewithproperties.py in hour (self, hour)


20 "" "Imposta l'ora." ""
21 in caso contrario ( 0 <= ora < 24 ):
> 22 raise ValueError (f 'Hour ( {hour} ) deve essere 023' )
23
24 self._hour = ora

ValueError : Hour (100) deve essere 023

10.4.2 Definizione dell'orario di lezione

Ora che abbiamo visto la classe Time in azione, diamo un'occhiata alla sua definizione.

Ora della lezione: metodo __init__ con valori dei parametri predefiniti

Il metodo __init__ di Class Time specifica i parametri di ora, minuti e secondi, ciascuno con
un argomento predefinito di 0. Simile al metodo __init__ della classe Account, ricorda che self

è un riferimento all'oggetto Time che viene inizializzato. Le dichiarazioni contenenti

self.hour, self.minute e self.second sembrano creare ora, minuto e

secondi attributi per il nuovo oggetto Time (self). Tuttavia, queste affermazioni chiamano effettivamente
metodi che implementano della classe ora, minuti e secondi proprietà (righe 13-50).

Questi metodi creano quindi attributi denominati _hour, _minute e _second che si intendono
da utilizzare solo all'interno della classe:

lecca qui per visualizzare l'immagine del codice

1 # timewithproperties.py
2 "" "Tempo di lezione con proprietà di lettura e scrittura." ""

C
3 Pagina 397
4 ore di lezione :
5 "" "Orario delle lezioni con proprietà di lettura e scrittura." ""
6
7 def __init __ (self, hour = 0 , minute = 0 , second = 0 ):
8 "" "Inizializza ogni attributo." ""
9 self.hour = ora # 023
10 self.minute = minuto # 059
11 self.second = secondo # 059
12

Tempo di lezione: proprietà di lettura-scrittura ora

Le linee 13-24 definiscono un accessibile al pubblico proprietà readwrite denominata ora che
manipola un attributo di dati denominato _hour. Denominazione con un solo punto in meno (_)

la convenzione indica che il codice client non deve accedere direttamente a _hour. Come hai visto nel file
snippet della sezione precedente [5] e [8], le proprietà sembrano attributi di dati ai programmatori
lavorare con gli oggetti Time. Tuttavia, si noti che le proprietà vengono implementate come metodi .
Ogni proprietà definisce un metodo getter che ottiene (ovvero, restituisce) il valore di un attributo di dati
e può opzionalmente definire un metodo setter che imposta il valore di un attributo di dati:

lecca qui per visualizzare l'immagine del codice

13 @property
14 def ora (auto):
15 "" "Restituisci l'ora." ""
16 return self._hour
17
18 @ hour.setter
19 def ora (self, hour):
20 "" "Imposta l'ora." ""
21 in caso contrario ( 0 <= ora < 24 ):
22 raise ValueError (f 'Hour ( {hour} ) deve essere 023' )
23
24 self._hour = ora
25

Il decoratore @property precede il metodo getter della proprietà , che riceve solo un file

parametro personale. Dietro le quinte, un decoratore aggiunge codice alla funzione decorata, in questo
case per far funzionare la funzione hour con la sintassi degli attributi. Il nome del metodo getter è

nome della proprietà. Questo metodo getter restituisce il valore dell'attributo dati _hour. Il seguente
l'espressione clientcode richiama il metodo getter :

wake_up.hour

Puoi anche usare il metodo getter all'interno della classe, come vedrai a breve.

Un decoratore della forma @ property_name .setter (in questo caso, @ hour.setter)

precede il metodo setter della proprietà . Il metodo riceve due parametri: self e a
parametro (ora) che rappresenta il valore da assegnare alla proprietà. Se l'ora

C
Pagina 398
il valore del parametro è valido, questo metodo lo assegna all'attributo _hour dell'oggetto self;
in caso contrario, il metodo genera un'eccezione ValueError. La seguente espressione di codice client richiama

il setter assegnando un valore alla proprietà:

wake_up.hour = 8

Abbiamo anche invocato questo setter all'interno della classe alla riga 9 di __init__:

self.hour = ora

L'uso del setter ci ha permesso di convalidare l' argomento hour di __init __ prima di creare e
inizializzando l'attributo _hour dell'oggetto, che si verifica la prima volta che la proprietà hour è
setter viene eseguito come risultato della riga 9. Una proprietà readwrite ha sia un getter che un setter . UN
la proprietà readonly ha solo un getter .

Orario delle lezioni: minuti e secondi Proprietà di lettura-scrittura

Le righe 26–37 e 39–50 definiscono le proprietà dei minuti e dei secondi di lettura e scrittura. Ogni proprietà

setter assicura che il suo secondo argomento sia compreso tra 0 e 59 (l'intervallo di valori valido per
minuti e secondi):

lecca qui per visualizzare l'immagine del codice

26 @property
27 def minuto (auto):
28 "" "Restituisci il minuto." ""
29 return self._minute
30
31 @ minute.setter
32 def minuto (self, minute):
33 "" "Imposta i minuti." ""
34 in caso contrario ( 0 <= minuto < 60 ):
35 raise ValueError (f 'Minute ( {minute} ) deve essere 059' )
36
37 self._minute = minuto
38
39 @property
40 def secondo (auto):
41 "" "Restituisci il secondo." ""
42 return self._second
43
44 @ second.setter
45 def secondo (self, second):
46 "" "Imposta i secondi." ""
47 in caso contrario ( 0 <= secondo < 60 ):
48 raise ValueError (f 'Second ( {second} ) deve essere 059' )
49
50 self._second = secondo
51

Orario delle lezioni: metodo set_time

Forniamo il metodo set_time come un modo conveniente per modificare tutti e tre gli attributi con un file
Pagina 399

chiamata a metodo singolo . Le righe 54–56 richiamano i setter per l'ora, i minuti e i secondi
proprietà:

lecca qui per visualizzare l'immagine del codice

52 def set_time (self, hour = 0 , minute = 0 , second = 0 ):


53 "" "Imposta i valori di ora, minuti e secondi." ""
54 self.hour = ora
55 self.minute = minuto
56 self.second = secondo
57

Orario delle lezioni: metodo speciale __repr__

Quando si passa un oggetto alla funzione incorporata repr, cosa che accade implicitamente quando si
valuta una variabile in una sessione IPython: lo speciale __repr__ della classe corrispondente
viene chiamato il metodo per ottenere una rappresentazione di stringa dell'oggetto:

lecca qui per visualizzare l'immagine del codice

58 def __repr __ (self):


59 "" "Stringa ora di ritorno per repr ()." ""
60 return (f 'Time (hour = {self.hour} , minute = {self.minute} ,' +
61 f 'secondo = {self.second} )' )
62

La documentazione di Python indica che __repr__ restituisce la stringa "ufficiale"


rappresentazione dell'oggetto. In genere questa stringa ha l'aspetto di un'espressione del costruttore that
2
crea e inizializza l'oggetto , come in:

2
ttps: //docs.python.org/3/reference/datamodel.html .

"Ora (ora = 6, minuti = 30, secondi = 0)"

che è simile all'espressione del costruttore nello snippet della sezione precedente [2]. Pitone

ha una funzione incorporata eval che potrebbe ricevere la stringa precedente come argomento e usarla
per creare e inizializzare un oggetto Time contenente i valori specificati nella stringa.

Orario delle lezioni: metodo speciale __str__

Per la nostra classe Time definiamo anche il metodo speciale __str__ . Questo metodo è chiamato
implicitamente quando converti un oggetto in una stringa con la funzione incorporata str, come quando

si stampa un oggetto o si chiama str esplicitamente. La nostra implementazione di __str__ crea una stringa
in formato 12 ore, ad esempio "7:59:59 AM" o "12: 30: 45 PM":

lecca qui per visualizzare l'immagine del codice


C
h
Pagina 400
63 def __str __ (self):
64 "" "Tempo di stampa in formato 12 ore." ""
65 return (( '12' if self.hour in ( 0 , 12 ) else str (self.hour% 12 )) +
66 f ': {self.minute: 0 > 2 } : {self.second: 0 > 2 } ' +
67 ( 'AM' se self.hour < 12 else 'PM' ))

10.4.3 Note di progettazione per la definizione del tempo di lezione

Consideriamo alcuni problemi di progettazione delle classi nel contesto della nostra lezione Time.

Interfaccia di una classe

Le proprietà ei metodi di Class Time definiscono l' interfaccia pubblica della classe , ovvero l'insieme di

proprietà e metodi che i programmatori dovrebbero usare per interagire con gli oggetti della classe.

Gli attributi sono sempre accessibili

Sebbene abbiamo fornito un'interfaccia ben definita, Python non ti impedisce di farlo direttamente
manipolare gli attributi dei dati _hour, _minute e _second, come in:

lecca qui per visualizzare l'immagine del codice

In [1]: from timewithproperties import Time

In [2]: wake_up = Time (hour = 7 , minute = 45 , second = 30 )

In [3]: wake_up._hour
Uscita [3]: 7

In [4]: ​wake_up._hour = 100

In [5]: wake_up
Out [5]: Time (ora = 100, minuti = 45, secondi = 30)

Dopo lo snippet [4], l'oggetto wake_up contiene dati non validi . A differenza di molti altri oggetti
linguaggi di programmazione orientati, come C ++, Java e C #, attributi di dati in Python
non può essere nascosto dal codice client. Il tutorial di Python dice: "niente in Python lo fa
3
possibile imporre l'occultamento dei dati: è tutto basato sulla convenzione. "

3
TTP: //docs.python.org/3/tutorial/classes.html#randomremarks .

Rappresentanza interna dei dati

Abbiamo scelto di rappresentare l'ora come tre valori interi per ore, minuti e secondi. It
sarebbe perfettamente ragionevole rappresentare il tempo internamente come il numero di secondi trascorsi da allora
mezzanotte. Anche se dovremmo reimplementare le proprietà ora, minuti e secondi,
i programmatori potrebbero utilizzare la stessa interfaccia e ottenere gli stessi risultati senza esserne consapevoli
questi cambiamenti. Lasciamo a te il compito di apportare questa modifica e mostrare il codice client utilizzando Time
gli oggetti non hanno bisogno di cambiare.

volving dettagli di implementazione di una classe


E
hC
Evoluzione dei dettagli di implementazione di una classe Pagina 401

Quando si progetta una classe, considerare attentamente l'interfaccia della classe prima di creare quella classe
disponibile per altri programmatori. Idealmente, progetterai l'interfaccia in modo tale che il codice esistente
non si interromperà se aggiorni i dettagli di implementazione della classe, ovvero i dati interni
rappresentazione o come vengono implementati i suoi corpi di metodo.

Se i programmatori Python seguono le convenzioni e non accedono agli attributi che iniziano con
sottolineature principali, quindi i progettisti di classe possono evolvere i dettagli di implementazione della classe senza
violazione del codice client.

Proprietà

Può sembrare che fornire proprietà sia con setter che con getter non abbia alcun vantaggio
accedere direttamente agli attributi dei dati, ma ci sono sottili differenze. Un getter sembra consentire
client per leggere i dati a piacimento, ma il getter può controllare la formattazione dei dati. Un setter
può esaminare i tentativi di modificare il valore di un attributo di dati per impedire che i dati siano
impostato su un valore non valido.

Metodi di utilità

Non tutti i metodi devono servire come parte dell'interfaccia di una classe. Alcuni servono come metodi di utilità
utilizzati solo all'interno della classe e non sono destinati a far parte dell'interfaccia pubblica della classe utilizzata
per codice cliente. Tali metodi dovrebbero essere denominati con un unico trattino basso iniziale. In altro
linguaggi orientati agli oggetti come C ++, Java e C #, tali metodi sono tipicamente implementati come
metodi privati.

Modulo datetime

Nello sviluppo professionale di Python, piuttosto che costruire le tue classi per rappresentare
volte e date, in genere utilizzerai il modulo datetime della libreria standard Python

capacità. Per ulteriori dettagli sul modulo datetime, vedere:

ttps: //docs.python.org/3/library/datetime.html

10.5 SIMULAZIONE DI ATTRIBUTI “PRIVATI”


Nei linguaggi di programmazione come C ++, Java e C #, le classi indicano esplicitamente quale classe
i membri sono pubblicamente accessibili . Membri della classe a cui non è possibile accedere al di fuori di una classe
le definizioni sono private e visibili solo all'interno della classe che le definisce. Pitone
i programmatori utilizzano spesso attributi "privati" per dati o metodi di utilità essenziali per un file
il funzionamento interno della classe ma non fa parte dell'interfaccia pubblica della classe.

Come hai visto, gli attributi degli oggetti Python sono sempre accessibili. Tuttavia, Python ha un'estensione
convenzione di denominazione per attributi "privati". Supponiamo di voler creare un oggetto di classe
Tempo e per evitare la seguente dichiarazione di assegnazione:

Pagina 402
wake_up._hour = 100

ciò imposterebbe l'ora su un valore non valido. Invece di _hour, possiamo denominare l'attributo

__ora con due trattini bassi iniziali . Questa convenzione indica che __hour è "privato"
e non dovrebbe essere accessibile ai client della classe. Per impedire ai client di accedere
Attributi "privati", Python li rinomina facendo precedere il nome dell'attributo con

_ ClassName , come in _Time__hour. Questo si chiama alterazione del nome . Se provi ad assegnare a
__ora, come in

wake_up .__ ora = 100

Python solleva un'eccezione AttributeError, indicando che la classe non ha __ora


attributo. Lo mostreremo momentaneamente.

Il completamento automatico IPython mostra solo gli attributi "pubblici"

Inoltre, IPython non mostra attributi con uno o due trattini bassi iniziali quando si
prova a completare automaticamente un'espressione come

svegliati.

premendo Tab . Lo sono solo gli attributi che fanno parte dell'interfaccia "pubblica" dell'oggetto wake_up

visualizzato nell'elenco di completamento automatico IPython.

Dimostrazione di attributi "privati"

Per dimostrare la manipolazione dei nomi, considera la classe PrivateClass con un dato "pubblico"

attributo public_data e un attributo dati "privato" __private_data:


lecca qui per visualizzare l'immagine del codice

1 # private.py
2 "" "Classe con attributi pubblici e privati." ""
3
4 classi PrivateClass:
5 "" "Classe con attributi pubblici e privati." ""
6
7 def __init __ (self):
8 "" "Inizializza gli attributi public e private." ""
9 self.public_data = "public" # attributo pubblico
10 self .__ private_data = "private" # attributo privato

Creiamo un oggetto della classe PrivateData per dimostrare questi attributi di dati:

lecca qui per visualizzare l'immagine del codice

In [1]: da privati importazione PrivateClass

C
Pagina 403
In [2]: my_object = PrivateClass ()

Lo snippet [3] mostra che possiamo accedere direttamente all'attributo public_data:

lecca qui per visualizzare l'immagine del codice

In [3]: my_object.public_data
Out [3]: "public"

Tuttavia, quando tentiamo di accedere a __private_data direttamente nello snippet [4], otteniamo un

AttributeError che indica che la classe non ha un attributo con quel nome:

lecca qui per visualizzare l'immagine del codice

In [4]: ​my_object .__ private_data

AttributeError Traceback (la chiamata più recente per ultima)


<ipythoninput4d896bfdf2053> in <module> ()
> 1 mio_oggetto .__ dati_privati

AttributeError : l'oggetto "PrivateClass" non ha l'attributo "__private_data"

Ciò si verifica perché python ha cambiato il nome dell'attributo. Sfortunatamente, l'attributo


__private_data è ancora accessibile indirettamente.

10.6 CASO DI STUDIO: TRASMISSIONE E CONTRATTO DI CARTE


SIMULAZIONE
Il nostro prossimo esempio presenta due classi personalizzate che puoi utilizzare per mescolare e distribuire un mazzo di
carte. Class Card rappresenta una carta da gioco che ha una faccia ('Asso', '2', '3',, 'Jack',

"Queen", "King") e un seme ("Hearts", "Diamonds", "Clubs", "Spades"). Classe


DeckOfCards rappresenta un mazzo di 52 carte da gioco come un elenco di oggetti Carta. Per prima cosa, testeremo
guidare queste classi in una sessione IPython per dimostrare il mescolamento e la gestione delle carte
capacità e visualizzare le carte come testo. Quindi esamineremo le definizioni delle classi. Finalmente,
useremo un'altra sessione IPython per visualizzare le 52 carte come immagini usando Matplotlib. Bene
mostrarti dove trovare belle immagini di schede di dominio pubblico.

10.6.1 Classi di guida di prova Card e DeckOfCards

Prima di esaminare le classi Card e DeckOfCards, usiamo una sessione IPython per
dimostrare le loro capacità.

Creare, mescolare e distribuire le carte

Per prima cosa, importa la classe DeckOfCards da deck.py e crea un oggetto della classe:
lecca qui per visualizzare l'immagine del codice
C
Pagina 404
In [1]: dal mazzo importa DeckOfCards

In [2]: deck_of_cards = DeckOfCards ()

Il metodo DeckOfCards __init__ crea gli oggetti 52 Card in ordine per seme e per faccia
all'interno di ogni seme. Puoi vederlo stampando l'oggetto deck_of_cards, che chiama il file

Metodo __str__ della classe DeckOfCards per ottenere la rappresentazione della stringa del mazzo. Leggi ciascuno
riga a sinistra e destra per confermare che tutte le carte siano visualizzate in ordine da ogni seme (cuori,

Quadri, fiori e picche):

lecca qui per visualizzare l'immagine del codice

In [3]: print (deck_of_cards)


Asso di cuori 2 di cuori 3 di cuori 4 di cuori
5 di cuori 6 di cuori 7 di cuori 8 di cuori
9 di cuori 10 di cuori Fante di cuori Regina di cuori
Re di cuori Asso di quadri 2 di quadri 3 di quadri
4 di quadri 5 di quadri 6 di quadri 7 di quadri
8 di quadri 9 di quadri 10 di quadri Fante di quadri
Regina di quadri Re di quadri Asso di fiori 2 di fiori
3 di Club 4 di Club 5 di Club 6 di Club
7 di Club 8 di Club 9 di Club 10 di Club
Fante di fiori Regina di fiori Re di fiori Asso di picche
2 di picche 3 di picche 4 di picche 5 di picche
6 di picche 7 di picche 8 di picche 9 di picche
10 di picche Jack di picche Regina di picche Re di picche

Quindi, mescoliamo il mazzo e stampiamo di nuovo l'oggetto deck_of_cards. Non abbiamo specificato a

seme per la riproducibilità, quindi ogni volta che mescoli, otterrai risultati diversi:

lecca qui per visualizzare l'immagine del codice

In [4]: ​deck_of_cards.shuffle ()

In [5]: print (deck_of_cards)


Re di cuori Regina di fiori Regina di quadri 10 di fiori
5 di cuori 7 di cuori 4 di cuori 2 di cuori
5 di fiori 8 di quadri 3 di cuori 10 di cuori
8 di picche 5 di picche Regina di picche Asso di fiori
8 di fiori 7 di picche fante di quadri 10 di picche
4 di quadri 8 di cuori 6 di picche Re di picche
9 di cuori 4 di picche 6 di fiori re di fiori
3 di picche 9 di quadri 3 di fiori Asso di picche
Asso di cuori 3 di quadri 2 di quadri 6 di cuori
Re di quadri Fante di picche Fante di fiori 2 di picche
5 di quadri 4 di fiori Regina di cuori 9 di fiori
10 di quadri 2 di fiori Asso di quadri 7 di quadri
9 di picche fante di cuori 6 di quadri 7 di fiori

Trattare carte

C
Pagina 405
Possiamo distribuire una carta alla volta chiamando il metodo deal_card. IPython chiama il restituito

Metodo __repr__ dell'oggetto scheda per produrre l'output della stringa mostrato nel prompt Out []:

lecca qui per visualizzare l'immagine del codice

In [6]: deck_of_cards.deal_card ()
Fuori [6]: Carta (faccia = "Re", seme = "Cuori")

Altre caratteristiche della Class Card

Per dimostrare il metodo __str__ della carta della classe, distribuiamo un'altra carta e passiamola al
funzione str incorporata:

lecca qui per visualizzare l'immagine del codice


In [7]: card = deck_of_cards.deal_card ()

In [8]: str (carta)


Fuori [8]: "Queen of Clubs"

Ogni scheda ha un nome file immagine corrispondente, che puoi ottenere tramite nome_immagine

proprietà di sola lettura. Lo useremo presto quando visualizzeremo le carte come immagini:

lecca qui per visualizzare l'immagine del codice

In [9]: card.image_name
Uscita [9]: "Queen_of_Clubs.png"

10.6.2 Carta di classe — Introduzione agli attributi di classe

Ogni oggetto Card contiene tre proprietà di stringa che rappresentano la faccia, il seme e il

nome_immagine (un nome file contenente un'immagine corrispondente). Come hai visto in precedenza
la sessione IPython della sezione, la classe Card fornisce anche metodi per inizializzare una Card e per
ottenere varie rappresentazioni di stringhe.

Attributi di classe FACCE e ABITI

Ogni oggetto di una classe ha le proprie copie degli attributi dei dati della classe. Ad esempio, ciascuno

L'oggetto Account ha un nome e un saldo propri. A volte, un attributo dovrebbe essere condiviso
da tutti gli oggetti di una classe. Un attributo di classe (chiamato anche variabile di classe ) rappresenta la classe
ampia informazione. Appartiene alla classe , non a un oggetto specifico di quella classe. Carta di classe

definisce due attributi di classe (righe 5-7):

FACCE è un elenco dei nomi dei volti delle carte.

SUITS è un elenco dei nomi dei semi delle carte.

lecca qui per visualizzare l'immagine del codice


Pagina 406

1 # card.py
2 "" "Classe di carte che rappresenta una carta da gioco e il nome del file di immagine." ""
3
Tessera 4 classi :
5 FACCE = [ "Asso" , "2" , "3" , "4" , "5" , "6" ,
6 "7" , "8" , "9" , "10" , "Jack" , "Queen" , "King" ]
7 SUITS = [ "Hearts" , "Diamonds" , "Clubs" , "Spades" ]
8

Si definisce un attributo di classe assegnandogli un valore all'interno della definizione della classe, ma non
all'interno di uno qualsiasi dei metodi o delle proprietà della classe (nel qual caso sarebbero variabili locali).

FACCE e SUITS sono costanti che non devono essere modificate. Ricorda che lo stile
4
La guida per il codice Python consiglia di denominare le costanti con tutte le lettere maiuscole.

4
Ricorda che Python non ha costanti vere, quindi FACES e SUITS sono ancora modificabili.

Useremo gli elementi di questi elenchi per inizializzare ogni scheda che creiamo. Tuttavia, non abbiamo bisogno di un file
copia separata di ogni lista in ogni oggetto Card. È possibile accedere agli attributi di classe tramite qualsiasi

oggetto della classe, ma in genere si accede tramite il nome della classe (come in, Card.FACES o

Card.SUITS). Gli attributi della classe esistono non appena si importa la definizione della loro classe.

Metodo carta __init__

Quando crei un oggetto Card, il metodo __init__ definisce _face e _suit dell'oggetto

attributi dei dati:

lecca qui per visualizzare l'immagine del codice


9 def __init __ (self, face, suit):
10 "" "Inizializza una carta con una faccia e un seme." ""
11 self._face = faccia
12 self._suit = seme
13

Proprietà di sola lettura face, suit e image_name

Una volta che una carta è stata creata, la sua faccia, seme e nome_immagine non cambiano, quindi implementiamo

queste come proprietà di sola lettura (righe 14–17, 19–22 e 24–27). Proprietà viso e vestito
restituisce gli attributi di dati corrispondenti _face e _suit. Una proprietà non è richiesta

hanno un attributo di dati corrispondente. A dimostrazione di ciò, la proprietà Card nome_immagine


value viene creato dinamicamente ottenendo la rappresentazione di stringa dell'oggetto Card con

str (self), sostituendo eventuali spazi con trattini bassi e aggiungendo il nome del file ".png"
estensione. Quindi, "Ace of Spades" diventa "Ace_of_Spades.png". Useremo questo file

nome per caricare un'immagine in formato PNG che rappresenta la Card. PNG (Portable Network Graphics)
è un formato di immagine popolare per le immagini basate sul Web.

lecca qui per visualizzare l'immagine del codice


Pagina 407

14 @property
15 def face (self):
16 "" "Restituisce il valore self._face della Carta." ""
17 return self._face
18
19 @property
20 def seme (auto):
21 "" "Restituisci il valore self._suit della Carta." ""
22 return self._suit
23
24 @property
25 def image_name (self):
26 "" "Restituisce il nome del file immagine della scheda." ""
27 return str (self) .replace ( '' , '_' ) + '.png'
28

Metodi che restituiscono rappresentazioni di stringa di una carta

Class Card fornisce tre metodi speciali che restituiscono rappresentazioni di stringa. Come in classe

Time, il metodo __repr__ restituisce una rappresentazione di stringa che assomiglia a un costruttore
espressione per creare e inizializzare un oggetto Card:

lecca qui per visualizzare l'immagine del codice

29 def __repr __ (self):


30 "" "Restituisce la rappresentazione della stringa per repr ()." ""
31 return f "Card (face = ' {self.face} ', suit = ' {self.suit} ')"
32

Il metodo __str__ restituisce una stringa del formato " faccia del seme ", come "Asso di cuori":

lecca qui per visualizzare l'immagine del codice

33 def __str __ (self):


34 "" "Restituisce la rappresentazione in formato stringa per str ()." ""
35 return f ' {self.face} di {self.suit} '
36

Quando la sessione IPython della sezione precedente ha stampato l'intero mazzo, hai visto che il file Cards

sono stati visualizzati in quattro colonne allineate a sinistra. Come vedrai nel metodo __str__ della classe

DeckOfCards, usiamo fstrings per formattare le carte in campi di 19 caratteri ciascuno. Classe

Il metodo speciale di Card __format__ viene chiamato quando un oggetto Card viene formattato come una stringa,
come in una stringa:

lecca qui per visualizzare l'immagine del codice

37 def __format __ (self, format):


38 "" "Restituisce una rappresentazione di stringa formattata per str ()." ""

C
39 return f ' {str (self): {format}} ' Pagina 408

Il secondo argomento di questo metodo è la stringa di formato utilizzata per formattare l'oggetto. Per utilizzare

valore del parametro di formato come identificatore di formato, racchiudere il nome del parametro tra parentesi graffe a
la parte destra del colon. In questo caso, stiamo formattando la rappresentazione di stringa dell'oggetto Card
restituito da str (self). Discuteremo di nuovo __format__ quando presenteremo __str__

metodo nella classe DeckOfCards.

10.6.3 Classe DeckOfCards

La classe DeckOfCards ha un attributo di classe NUMBER_OF_CARDS, che rappresenta il numero di

Carte in un mazzo e crea due attributi di dati:

_current_card tiene traccia di quale carta verrà distribuita dopo (0–51) e

_deck (riga 12) è un elenco di 52 oggetti Card.

Metodo __init__

Il metodo DeckOfCards __init__ inizializza un _deck di carte. L'istruzione for riempie il file
list _deck aggiungendo nuovi oggetti Card, ciascuno inizializzato con due stringhe, una dal file

list Card.FACES e uno da Card.SUITS. Il conteggio del calcolo% 13 risulta sempre


in un valore da 0 a 12 (i 13 indici di Card.FACES), e il calcolo conta // 13

restituisce sempre un valore compreso tra 0 e 3 (i quattro indici di Card.SUITS). Quando il _deck list
è inizializzato, contiene le carte con facce da "Asso" a "Re" in ordine per tutti i file

Cuori, poi i quadri, poi i fiori, poi i picche.

lecca qui per visualizzare l'immagine del codice

1 # deck.py
2 "" "La classe del mazzo rappresenta un mazzo di carte." ""
3 importazione casuale
4 da carta di import Scheda
5
DeckOfCards di 6 classi :
7 NUMBER_OF_CARDS = 52 # numero costante di carte
8
9 def __init __ (self):
10 "" "Inizializza il mazzo." ""
11 self._current_card = 0
12 self._deck = []
13
14 per il conteggio in gamma ( DeckOfCards.NUMBER_OF_CARDS ):
15 self._deck.append (Card ( Card.FACES [count% 13 ],
16 Card.SUITS [count // 13 ]))
17

Metodo shuffle

Il metodo shuffle reimposta _current_card a 0, quindi mescola le carte in _deck utilizzando il

C
Pagina 409
funzione shuffle del modulo casuale:

lecca qui per visualizzare l'immagine del codice

18 def shuffle (self):


19 "" "Mazzo shuffle." ""
20 self._current_card = 0
21 random.shuffle (self._deck)
22

Metodo deal_card

Il metodo deal_card distribuisce una carta da _deck. Ricorda che _current_card indica il

indice (0–51) della carta successiva da distribuire (cioè la carta in cima al mazzo). Linea 26
cerca di ottenere l'elemento _deck all'indice _current_card. In caso di successo, il metodo

incrementa _current_card di 1, quindi restituisce la Carta distribuita; in caso contrario, il metodo


restituisce Nessuno per indicare che non ci sono più carte da distribuire.

lecca qui per visualizzare l'immagine del codice

23 def deal_card (self):


24 "" "Restituisci una carta." ""
25 prova :
26 card = self._deck [self._current_card]
27 self._current_card + = 1
28 biglietto di ritorno
29 tranne :
30 ritorno Nessuno
31

Metodo __str__

La classe DeckOfCards definisce anche il metodo speciale __str__ per ottenere una rappresentazione di stringa
il mazzo in quattro colonne con ogni carta a sinistra allineata in un campo di 19 caratteri. Quando la linea 37

formatta una data Card, il suo metodo speciale __format__ viene chiamato con l'identificatore di formato '<19'
come argomento di formato del metodo. Il metodo __format__ utilizza quindi "<19" per creare il file

Rappresentazione in formato stringa della carta.

lecca qui per visualizzare l'immagine del codice

32 def __str __ (self):


33 "" "Restituisce una rappresentazione di stringa del _deck corrente." ""
34 s = ''
35
36 per indice, scheda in enumerazione (self._deck):
37 s + = f " {self._deck [index]: < 19 } "
38 se (indice + 1 )% 4 == 0 :
39 s + = "\ n"
40
41 ritorno s

1C 0.6.4 Visualizzazione delle immagini dei biglietti con Matplotlib

10.6.4 Visualizzazione delle immagini dei biglietti con Matplotlib Pagina 410

Finora abbiamo visualizzato le carte come testo. Ora, visualizziamo le immagini delle carte. Per questo
5
dimostrazione, abbiamo scaricato pubblico dominio le immagini di carte da Wikimedia Commons:

5
ttps: //creativecommons.org/publicdomain/zero/1.0/deed.en .

ttps: //commons.wikimedia.org/wiki/Category: SVG_English_pattern_playing_cards

Questi si trovano nella sottocartella card_images della cartella ch10 examples. Per prima cosa, creiamo un file

Mazzo di carte:

lecca qui per visualizzare l'immagine del codice

In [1]: dal mazzo importa DeckOfCards

In [2]: deck_of_cards = DeckOfCards ()

Abilita Matplotlib in IPython

Successivamente, abilita il supporto Matplotlib in IPython usando la magia% matplotlib:

lecca qui per visualizzare l'immagine del codice

In [3]:% matplotlib
Utilizzo del backend matplotlib: Qt5Agg

Crea il percorso di base per ogni immagine


Prima di visualizzare ogni immagine, dobbiamo caricarla dalla cartella card_images. Useremo il file
La classe Path del modulo pathlib per costruire il percorso completo di ogni immagine sul nostro sistema.
Lo snippet [5] crea un oggetto Path per la cartella corrente (la cartella degli esempi ch10), che è
rappresentato da '.', quindi utilizza il metodo Path joinpath per aggiungere la sottocartella contenente

le immagini delle carte:

lecca qui per visualizzare l'immagine del codice

In [4]: from pathlib import Path

In [5]: path = Path ( '.' ) .Joinpath ( 'card_images' )

Importa le funzionalità Matplotlib

Successivamente, importiamo i moduli Matplotlib di cui avremo bisogno per visualizzare le immagini. Useremo un file
funzione da matplotlib.image per caricare le immagini:

hC
h

Pagina 411
lecca qui per visualizzare l'immagine del codice

In [6]: importa matplotlib.pyplot come plt

In [7]: importa matplotlib.image come mpimg

Crea la figura e gli oggetti degli assi

Il frammento di codice seguente utilizza le sottotrame della funzione Matplotlib per creare un oggetto Figure in cui

visualizzeremo le immagini come 52 sottotrame con quattro righe (nrows) e 13 colonne (ncols). Il
restituisce una tupla contenente la figura e un array degli oggetti Axes delle sottotrame.

Li scompattiamo nelle variabili figure e axes_list:

lecca qui per visualizzare l'immagine del codice

In [8]: figura, axes_list = plt.subplots (nrows = 4 , ncols = 13 )

Quando esegui questa istruzione in IPython, la finestra Matplotlib appare immediatamente


con 52 sottotrame vuote.

Configurare gli oggetti degli assi e visualizzare le immagini

Successivamente, iteriamo su tutti gli oggetti Axes in axes_list. Ricorda che ravel fornisce a
vista unidimensionale di un array multidimensionale. Per ogni oggetto Axes, eseguiamo il

seguenti compiti:

Non stiamo tracciando dati, quindi non abbiamo bisogno di linee degli assi ed etichette per ogni immagine. Il primo
due istruzioni del ciclo nascondono la x ed y assi.

La terza istruzione distribuisce una Carta e ottiene il suo nome_immagine.

La quarta istruzione utilizza il metodo path joinpath per aggiungere image_name al file

Path, quindi chiama la risoluzione del metodo Path per determinare il percorso completo dell'immagine sul nostro file
sistema. Passiamo l'oggetto Path risultante alla funzione builtin str per ottenere la stringa

rappresentazione della posizione dell'immagine. Quindi, passiamo quella stringa al file


la funzione imread del modulo matplotlib.image , che carica l'immagine.

L'ultima istruzione chiama il metodo Axes imshow per visualizzare l'immagine corrente nel file current

sottotrama.

lecca qui per visualizzare l'immagine del codice

In [9]: per gli assi in axes_list.ravel ():


...: axes.get_xaxis (). set_visible ( False )
...: axes.get_yaxis (). set_visible ( False )
...: nome_immagine = deck_of_cards.deal_card (). nome_immagine
...: img = mpimg.imread (str (path.joinpath (nome_immagine) .resolve ()))

C
...: axes.imshow (img) Pagina 412
...:

Massimizza le dimensioni dell'immagine

A questo punto vengono visualizzate tutte le immagini. Per rendere le carte più grandi possibile, puoi
massimizzare la finestra, quindi chiamare il metodo tight_layout dell'oggetto Matplotlib Figure .
Questo rimuove la maggior parte dello spazio bianco extra nella finestra:

In [10]: figure.tight_layout ()

L'immagine seguente mostra il contenuto della finestra risultante:

Mescola e ridistribuisci il mazzo

Per vedere le immagini mescolate, chiama il metodo shuffle, quindi esegui di nuovo il codice dello snippet [9]:

lecca qui per visualizzare l'immagine del codice

In [11]: deck_of_cards.shuffle ()

In [12]: per gli assi in axes_list.ravel ():


...: axes.get_xaxis (). set_visible ( False )
...: axes.get_yaxis (). set_visible ( False )
...: nome_immagine = deck_of_cards.deal_card (). nome_immagine
...: img = mpimg.imread (str (path.joinpath (nome_immagine) .resolve ()))
...: axes.imshow (img)
...:

C
Pagina 413
10.7 EREDITÀ: CLASSI BASE E SOTTOCLASSI
Spesso, un oggetto di una classe è anche un oggetto di un'altra classe. Ad esempio, un CarLoan è un file

Prestito come sono Prestiti domestici e Prestiti ipotecari. Si può dire di classe CarLoan
eredita dalla classe Loan. In questo contesto, la classe Loan è una classe base e la classe CarLoan è una

sottoclasse. Un prestito auto è un tipo specifico di prestito, ma non è corretto affermare che ogni prestito è un

CarLoan: il prestito potrebbe essere di qualsiasi tipo. La tabella seguente elenca semplici esempi di base
classi e sottoclassi: le classi base tendono ad essere "più generali" e le sottoclassi "più"
specifico":

Classe base Sottoclassi

Alunno GraduateStudent, UndergraduateStudent

Forma Cerchio, triangolo, rettangolo, sfera, cubo

Prestito Prestito auto, Prestito casa, Prestito mutuo

Dipendente Facoltà, personale

Conto bancario CheckingAccount, SavingsAccount

Pagina 414
poiché ogni oggetto di sottoclasse è un oggetto della sua classe base e una classe base può averne molte
sottoclassi, l'insieme di oggetti rappresentato da una classe base è spesso più grande dell'insieme di oggetti
rappresentato da una delle sue sottoclassi. Ad esempio, la classe base Veicolo rappresenta tutto
veicoli, comprese auto, camion, barche, biciclette e così via. Al contrario, la sottoclasse Car

rappresenta un sottoinsieme più piccolo e più specifico di veicoli.

Gerarchia di ereditarietà dei membri della comunità

Le relazioni di ereditarietà formano strutture gerarchiche simili ad alberi . Una classe base esiste in un file
relazione gerarchica con le sue sottoclassi. Sviluppiamo una gerarchia di classi di esempio (mostrata in
il diagramma seguente), chiamato anche gerarchia di ereditarietà . Una comunità universitaria ha
migliaia di membri, inclusi dipendenti, studenti e alumni. I dipendenti lo sono
docenti o membri del personale. I membri della facoltà sono amministratori (ad esempio, presidi e
presidenti di dipartimento) o insegnanti. La gerarchia potrebbe contenere molte altre classi. Per
Ad esempio, gli studenti possono essere laureati o studenti universitari. Gli studenti universitari possono
essere matricole, studenti del secondo anno, junior o senior. Con l' ereditarietà singola , viene derivata una classe
da una classe base. Con l'ereditarietà multipla , una sottoclasse eredita da due o più basi
classi. L'ereditarietà singola è semplice. L'ereditarietà multipla va oltre lo scopo di questo
libro. Prima di utilizzarlo, cerca online il "problema del diamante in Python multiplo
eredità."
Ogni freccia nella gerarchia rappresenta un isa rapporto. Mentre seguiamo le frecce verso l'alto
in questa gerarchia di classi, possiamo affermare, ad esempio, che “un dipendente è una comunità

Membro "e" un insegnante è un membro della Facoltà ". CommunityMember è la base diretta
class of Employee, Student and Alum ed è una classe base indiretta di tutte le altre classi in
il diagramma. Partendo dal basso, puoi seguire le frecce e applicare l' ISA
relazione fino alla superclasse più alta. Ad esempio, l'amministratore è una facoltà
membro, è un dipendente, è un membro della comunità e, ovviamente, in definitiva è un oggetto.

Gerarchia di ereditarietà delle forme

Si consideri ora la gerarchia di ereditarietà delle forme nel diagramma delle classi seguente, che inizia

B
Pagina 415
con la classe base Shape, seguita dalle sottoclassi TwoDimensionalShape e

ThreeDimensionalShape. Ciascuna forma è una forma bidimensionale o un file

ThreeDimensionalShape. Il terzo livello di questa gerarchia contiene tipi specifici di file


TwoDimensionalShapes e ThreeDimensionalShapes. Di nuovo, possiamo seguire il file
frecce dalla parte inferiore del diagramma alla classe base più in alto in questa gerarchia di classi a
individuare alcuni isa relazioni. Ad esempio, un triangolo è un TwoDimensionalShape
ed è una forma, mentre una sfera è una forma tridimensionale ed è una forma. Questo

la gerarchia potrebbe contenere molte altre classi. Ad esempio, lo sono anche ellissi e trapezi

TwoDimensionalShapes, e coni e cilindri sono anche ThreeDimensionalShapes.

"È un" vs. "ha un"

L'ereditarietà produce relazioni "isa" in cui può trovarsi anche un oggetto di un tipo di sottoclasse
trattato come un oggetto del tipo baseclass. Hai anche visto "hasa" (composizione)
relazioni in cui una classe ha riferimenti a uno o più oggetti di altre classi come
membri.

10.8 COSTRUIRE UNA GERARCHIA PER L'EREDITÀ;


INTRODUZIONE AL POLIMORFISMO
Usiamo una gerarchia contenente i tipi di dipendenti nell'app per le buste paga di un'azienda per discutere di
relazione tra una classe base e la sua sottoclasse. Tutti i dipendenti dell'azienda hanno molto da fare
comune, ma i dipendenti della commissione (che saranno rappresentati come oggetti di una classe base) lo sono
pagato una percentuale delle loro vendite, mentre i dipendenti della commissione stipendiati (chi sarà
rappresentati come oggetti di una sottoclasse) ricevono una percentuale delle loro vendite più uno stipendio base.

Innanzitutto, presentiamo CommissionEmployee della classe base . Successivamente, creiamo una sottoclasse

SalariedCommissionEmployee che eredita dalla classe CommissionEmployee. Poi,


usiamo una sessione IPython per creare un oggetto SalariedCommissionEmployee e
dimostrare di avere tutte le capacità della classe base e della sottoclasse, ma calcola le sue
guadagni in modo diverso.

10.8.1 Commissione di classe di baseDipendente

Considera la classe CommissionEmployee, che fornisce le seguenti funzionalità:


Metodo __init__ (righe 8-15), che crea gli attributi di dati _first_name,

w
Pagina 416
_last_name e _ssn (numero di previdenza sociale) e utilizza i setter delle proprietà

gross_sales e commission_rate per creare i loro attributi di dati corrispondenti.

Proprietà di sola lettura first_name (righe 17-19), last_name (righe 21-23) e ssn (riga
25–27), che restituiscono gli attributi dei dati corrispondenti.

Readwrite properties gross_sales (righe 29–39) e commission_rate (righe 41–


52), in cui i setter eseguono la convalida dei dati.

Metodo guadagni (righe 54-56), che calcola e restituisce a

Commissione Guadagni del dipendente.

Metodo __repr__ (righe 58-64), che restituisce una rappresentazione di stringa di a

CommissioneDipendente.

lecca qui per visualizzare l'immagine del codice

1 # commmissionemployee.py
2 "" "CommissionEmployee classe base." ""
3 da decimale importazione decimale
4
Commissione di classe 5 Impiegato :
6 "" "Un dipendente che riceve una commissione in base alle vendite lorde." ""
7
8 def __init __ (self, first_name, last_name, ssn,
9 gross_sales, commission_rate):
10 "" "Inizializza gli attributi di CommissionEmployee." ""
11 self._first_name = first_name
12 self._last_name = last_name
13 self._ssn = ssn
14 self.gross_sales = gross_sales # convalida tramite proprietà
15 self.commission_rate = commission_rate # convalida tramite proprietà
16
17 @property
18 def first_name (self):
19 return self._first_name
20
21 @property
22 def last_name (self):
23 return self._last_name
24
25 @property
26 def ssn (self):
27 return self._ssn
28
29 @property
30 def gross_sales (self):
31 return self._gross_sales
32
33 @ gross_sales.setter
34 def gross_sales (self, sales):
35 "" "Imposta le vendite lorde o aumenta ValueError se non valido." ""
36 se le vendite <Decimale ( '0.00' ):
37 raise ValueError ( 'Le vendite lorde devono essere> = a 0' )
38

C
39 self._gross_sales = vendite Pagina 417
40
41 @property
42 def commission_rate (self):
43 return self._commission_rate
44
45 @ commission_rate.setter
46 def commission_rate (self, rate):
47 "" "Imposta il tasso di commissione o aumenta ValueError se non valido." ""
48 in caso contrario (Decimale ( '0,0' ) <velocità <Decimale ( '1,0' )):
49 raise ValueError (
50 'Il tasso di interesse deve essere maggiore di 0 e minore di 1' )
51
52 self._commission_rate = tasso
53
54 guadagni def (auto):
55 "" "Calcola le entrate." ""
56 return self.gross_sales * self.commission_rate
57
58 def __repr __ (self):
59 "" "Restituisce la rappresentazione della stringa per repr ()." ""
60 return ( "CommissionEmployee:" +
61 f ' {self.first_name} {self.last_name} \ n' +
62 f 'numero di previdenza sociale: {self.ssn} \ n' +
63 f 'vendite lorde: {self.gross_sales: .2 f} \ n' +
64 f 'tasso di commissione: {self.commission_rate: .2 f} ' )

Le proprietà first_name, last_name e ssn sono di sola lettura. Abbiamo scelto di non convalidarli,
anche se avremmo potuto. Ad esempio, potremmo convalidare il nome e il cognome, magari con
assicurandoti che siano di una lunghezza ragionevole. Potremmo convalidare il numero di previdenza sociale a
assicurati che contenga nove cifre, con o senza trattini (ad esempio, per assicurarti che sia in formato
il formato ######### o #########, dove ogni # è una cifra).

Tutte le classi ereditano direttamente o indirettamente dall'oggetto Class

Usi l'ereditarietà per creare nuove classi da quelle esistenti. In effetti, ogni classe Python
eredita da una classe esistente. Quando non specifichi esplicitamente la classe base per un nuovo file
class, Python presume che la classe erediti direttamente dall'oggetto della classe. La classe Python

la gerarchia inizia con l'oggetto classe, la classe base diretta o indiretta di ogni classe. Quindi, classe

L'intestazione di CommissionEmployee avrebbe potuto essere scritta come

class CommissionEmployee (oggetto):

Le parentesi dopo CommissionEmployee indicano l'eredità e possono contenere un singolo

class per ereditarietà singola o un elenco di classi base separate da virgole per ereditarietà multipla.
Ancora una volta, l'ereditarietà multipla va oltre lo scopo di questo libro.

Class CommissionEmployee eredita tutti i metodi dell'oggetto classe. L'oggetto di classe fa


non ha attributi di dati. Due dei molti metodi ereditati da object sono

__repr__ e __str__. Quindi ogni classe ha questi metodi che restituiscono string
rappresentazioni degli oggetti su cui vengono chiamati. Quando un metodo di classe base

Pagina 418
l'implementazione è inappropriata per una classe derivata, quel metodo può essere sovrascritto (cioè,
ridefinito) nella classe derivata con un'implementazione appropriata. Metodo __repr__

(righe 58-64) sovrascrive l'implementazione predefinita ereditata in class


6
CommissionEmployee dall'oggetto della classe.

6
ee ttps: //docs.python.org/3/reference/datamodel.html per gli oggetti
metodi sostituibili.

Commissione di classe di testDipendente

Proviamo rapidamente alcune delle funzionalità di CommissionEmployee. Innanzitutto, crea e visualizza un file

CommissioneDipendente:

lecca qui per visualizzare l'immagine del codice

In [1]: from commissionemployee import CommissionEmployee

In [2]: da decimal import Decimal

In [3]: c = CommissionEmployee ( "Sue" , "Jones" , "333333333" ,


...: decimale ( '10000.00' ), decimale ( '0,06' ))
...:

In [4]: ​c
Fuori [4]:
CommissioneDipendente: Sue Jones
numero di previdenza sociale: 333333333
vendite lorde: 10000,00
tasso di commissione: 0,06

Successivamente, calcoliamo e visualizziamo i guadagni del dipendente della Commissione:


lecca qui per visualizzare l'immagine del codice

In [5]: print (f ' {c.earnings () :, .2 f} ' )


600.00

Infine, cambiamo le vendite lorde e il tasso di commissione di CommissionEmployee, quindi


ricalcola i guadagni:

lecca qui per visualizzare l'immagine del codice

In [6]: c.gross_sales = Decimal ( '20000.00' )

In [7]: c.commission_rate = Decimal ( '0.1' )

In [8]: print (f ' {c.earnings () :, .2 f} ' )


2.000,00

h1
C
S 0.8.2 Sottoclasse SalariedCommissionEmployee

10.8.2 Sottoclasse SalariedCommissionEmployee Pagina 419

Con l'ereditarietà singola, la sottoclasse inizia essenzialmente come la classe base. Il vero
la forza dell'ereditarietà deriva dalla capacità di definire nelle sottoclassi aggiunte,
sostituzioni o perfezionamenti per le caratteristiche ereditate dalla classe base.

Molte delle capacità di un SalariedCommissionEmployee sono simili, se non identiche, a


quelli della classe CommissionEmployee. Entrambi i tipi di dipendenti hanno nome, cognome,

Numero di previdenza sociale, attributi di dati sulle vendite lorde e sui tassi di commissione, proprietà e
metodi per manipolare quei dati. Per creare la classe SalariedCommissionEmployee senza

utilizzando l'ereditarietà, avremmo potuto copiato il codice di classe di CommissionEmployee ed incollato esso
nella classe SalariedCommissionEmployee. Quindi avremmo potuto modificare la nuova classe in

includere un attributo di dati sullo stipendio di base e le proprietà e i metodi che manipolano la base
stipendio, compreso un nuovo metodo di guadagno. Questo approccio di copia e incolla è spesso un errore

incline. Peggio ancora, può diffondere molte copie fisiche dello stesso codice (inclusi gli errori)
in tutto il sistema, rendendo il codice meno gestibile. L'ereditarietà ci consente di "assorbire"
le caratteristiche di una classe senza duplicare il codice. Vediamo come.

Dichiarazione di classe SalariedCommissionEmployee

Dichiariamo ora la sottoclasse SalariedCommissionEmployee, che ne eredita la maggior parte

capacità dalla classe CommissionEmployee (riga 6). UN

SalariedCommissionEmployee è un CommissionEmployee (perché l'eredità passa


sulle capacità della classe CommissionEmployee), ma di classe

SalariedCommissionEmployee ha anche le seguenti caratteristiche:

Metodo __init__ (righe 10-15), che inizializza tutti i dati ereditati dalla classe

CommissionEmployee (ne parleremo tra poco), quindi utilizza l'estensione

setter della proprietà base_salary per creare un attributo di dati _base_salary.

Readwrite proprietà base_salary (righe 17–27), in cui il setter esegue i dati


validazione.

Una versione personalizzata dei guadagni del metodo (righe 29–31).

Una versione personalizzata del metodo __repr__ (righe 33–36).

lecca qui per visualizzare l'immagine del codice

1 # salariedcommissionemployee.py
2 "" "SalariedCommissionEmployee derivato da CommissionEmployee." ""
3 da commissioneimpiegato import Commissione Impiegato
4 da decimale importazione decimale
5
6 classe SalariedCommissionEmployee (CommissionEmployee):
7 "" "Un dipendente che viene pagato uno stipendio più
8 commissioni basate sulle vendite lorde. "" "
9

C
10 def __init __ (self, first_name, last_name, ssn, Pagina 420
11 gross_sales, commission_rate, base_salary):
12 "" "Inizializza gli attributi di SalariedCommissionEmployee." ""
13 super () .__ init __ (first_name, last_name, ssn,
14 gross_sales, commission_rate)
15 self .base_salary = base_salary # convalida tramite proprietà
16
17 @property
18 def base_salary (self):
19 return self._base_salary
20
21 @ base_salary.setter
22 def base_salary (self, salary):
23 "" "Imposta lo stipendio base o aumenta ValueError se non valido." ""
24 se salario <Decimale ( '0.00' ):
25 raise ValueError ( 'Lo stipendio base deve essere> = a 0' )
26
27 self._base_salary = stipendio
28
29 guadagni definitivi (auto):
30 "" "Calcola i guadagni." ""
31 return super (). Earnings () + self.base_salary
32
33 def __repr __ (self):
34 "" "Restituisce la rappresentazione in formato stringa per repr ()." ""
35 return ( 'Salaried' + super () .__ repr __ () +
36 f '\ nstipendio base: {self.base_salary: .2 f} ' )

Ereditando da Class CommissionEmployee

Per ereditare da una classe, devi prima importare la sua definizione (riga 3). Linea 6

classe SalariedCommissionEmployee (CommissionEmployee):

specifica che la classe SalariedCommissionEmployee eredita da

CommissioneDipendente. Anche se non vedi i dati della classe CommissionEmployee


attributi, proprietà e metodi nella classe SalariedCommissionEmployee, sono
tuttavia fa parte della nuova classe, come vedrai presto.

Metodo __init__ e funzione incorporata super

Ogni sottoclasse __init__ deve chiamare esplicitamente di sua classe base __init__ per inizializzare i dati
attributi ereditati dalla classe base. Questa chiamata dovrebbe essere la prima istruzione in
metodo __init__ della sottoclasse. Metodo __init__ di SalariedCommissionEmployee
chiama esplicitamente il metodo __init__ della classe CommissionEmployee (righe 13-14) da inizializzare
la parte della classe base di un oggetto SalariedCommissionEmployee (ovvero, i cinque
attributi di dati ereditati dalla classe CommissionEmployee). La notazione

super () .__ init__ utilizza la funzione incorporata super per individuare e chiamare la classe base
__init__, passando i cinque argomenti che inizializzano gli attributi di dati ereditati.

Guadagni del metodo di sostituzione

Pagina 421
Il metodo degli utili della classe SalariedCommissionEmployee (righe 29–31) sostituisce la classe

Commissione Metodo di guadagno del dipendente ( ezione 10.8.1 , righe 54-56) per calcolare il

guadagni di un dipendente della Commissione Salaried. La nuova versione ottiene la porzione di


guadagni basati sulla sola commissione chiamando il metodo dei guadagni di CommissionEmployee

con l'espressione super (). earnings () (riga 31). SalariedCommissionDipendenti

Il metodo dei guadagni aggiunge quindi base_salary a questo valore per calcolare i guadagni totali.
Facendo invocare il metodo dei guadagni di SalariedCommissionEmployee

Commissione Metodo di guadagno del dipendente per calcolare parte di un

SalariedCommissionEmployee guadagni, evitiamo di duplicare il codice e riduciamo


problemi di manutenzione del codice.
Metodo di sostituzione __repr__
Il metodo __repr__ di SalariedCommissionEmployee (righe 33–36) sovrascrive la classe
Metodo __repr__ di CommissionEmployee ( sezione 10.8.1 , righe 58-64) per restituire a

Rappresentazione di stringa appropriata per un SalariedCommissionEmployee. Il


la sottoclasse crea parte della rappresentazione di stringa concatenando "Salaried" e

stringa restituita da super () .__ repr __ (), che chiama CommissionEmployee's

metodo __repr__. Il metodo sottoposto a override concatena quindi le informazioni sullo stipendio base
e restituisce la stringa risultante.

Classe di test SalariedCommissionEmployee

Testiamo la classe SalariedCommissionEmployee per dimostrare che ha effettivamente ereditato

capacità dalla classe CommissionEmployee. Per prima cosa, creiamo un file

SalariedCommissionEmployee e stampa tutte le sue proprietà:

lecca qui per visualizzare l'immagine del codice

In [9]: da salariedcommissionemployee import SalariedCommissionEmployee

In [10]: s = SalariedCommissionEmployee ( 'Bob' , 'Lewis' , '444444444' ,


...: decimale ( '5000.00' ), decimale ( '0,04' ), decimale ( '300,00' ))
...:

In [11]: print (s.first_name, s.last_name, s.ssn, s.gross_sales,


...: s.commission_rate, s.base_salary)
Bob Lewis 444444444 5000,00 0,04 300,00

Si noti che l'oggetto SalariedCommissionEmployee ha tutte le proprietà delle classi

CommissionEmployee e SalariedCommissionEmployee.

Successivamente, calcoliamo e visualizziamo i guadagni di SalariedCommissionEmployee. Perché

chiamiamo guadagni del metodo su un oggetto SalariedCommissionEmployee, la sottoclasse


versione del metodo esegue:

lecca qui per visualizzare l'immagine del codice

S
C
Pagina 422
In [12]: print (f ' {s.earnings () :, .2 f} ' )
500.00

Ora, modifichiamo le proprietà gross_sales, commission_rate e base_salary,

quindi visualizzare i dati aggiornati tramite la SalariedCommissionEmployee's __repr__


metodo:

lecca qui per visualizzare l'immagine del codice

In [13]: s.gross_sales = Decimal ( '10000.00' )

In [14]: s.commission_rate = Decimal ( "0.05" )

In [15]: s.base_salary = Decimal ( '1000.00' )

In [16]: print (s)


SalariedCommissionDipendente: Bob Lewis
numero di previdenza sociale: 444444444
vendite lorde: 10000,00
tasso di commissione: 0,05
stipendio base: 1000.00

Di nuovo, poiché questo metodo viene chiamato su un oggetto SalariedCommissionEmployee, il


viene eseguita la versione della sottoclasse del metodo. Infine, calcoliamo e visualizziamo lo stipendiato

Commissione Guadagni aggiornati del dipendente:

lecca qui per visualizzare l'immagine del codice

In [17]: print (f ' {s.earnings () :, .2 f} ' )


1.500,00
Testare la relazione "è una"

Python fornisce due funzioni incorporate - issubclass e isinstance - per il test "is a"

relazioni. La funzione issubclass determina se una classe è derivata da un'altra:

lecca qui per visualizzare l'immagine del codice

In [18]: issubclass (SalariedCommissionEmployee, CommissionEmployee)


Out [18]: Vero

La funzione è istanza determina se un oggetto ha una relazione "è un" con uno specifico

genere. Poiché SalariedCommissionEmployee eredita da CommissionEmployee,


entrambi i frammenti seguenti restituiscono True, confermando la relazione "è un"

lecca qui per visualizzare l'immagine del codice

In [19]: isinstance (s, CommissionEmployee)

C
Out [19]: Vero Pagina 423

In [20]: isinstance (s, SalariedCommissionEmployee)


Out [20]: Vero

10.8.3 Commissione di elaborazione Dipendenti e


SalariedCommissionEmployees polimorficamente
Con l'ereditarietà, anche ogni oggetto di una sottoclasse può essere trattato come un oggetto di quella sottoclasse
classe base. Possiamo trarre vantaggio da questa relazione "sottoclasseobjectisabaseclassobject"
per eseguire alcune manipolazioni interessanti. Ad esempio, possiamo posizionare oggetti correlati
attraverso l'ereditarietà in un elenco, quindi iterare l'elenco e trattare ogni elemento come una base
oggetto di classe. Ciò consente di elaborare una varietà di oggetti in modo generale . Andiamo
dimostrarlo inserendo la CommissioneDipendente e

SalariedCommissionEmployee oggetti in un elenco, quindi per ogni elemento che ne visualizza


rappresentazione di stringa e guadagni:

lecca qui per visualizzare l'immagine del codice

In [21]: dipendenti = [c, s]

In [22]: per i dipendenti nei dipendenti:


...: print (impiegato)
...: print (f ' {dipendente.earnings () :, .2 f} \ n' )
...:
CommissioneDipendente: Sue Jones
numero di previdenza sociale: 333333333
vendite lorde: 20000.00
tasso di commissione: 0.10
2.000,00

SalariedCommissionDipendente: Bob Lewis


numero di previdenza sociale: 444444444
vendite lorde: 10000,00
tasso di commissione: 0,05
stipendio base: 1000.00
1.500,00

Come puoi vedere, per ciascuno vengono visualizzati la rappresentazione della stringa corretta e i guadagni
dipendente. Questo è chiamato polimorfismo, una capacità chiave della programmazione orientata agli oggetti
(OOP).

10.8.4 Una nota sulla programmazione basata su oggetti e orientata agli oggetti

L'ereditarietà con l'override del metodo è un modo potente per creare componenti software che siano
come i componenti esistenti, ma devono essere personalizzati in base alle esigenze specifiche dell'applicazione. Nel
Python opensource world, ci sono un numero enorme di librerie di classi ben sviluppate per
qual è il tuo stile di programmazione:
sapere quali librerie sono disponibili,

C
Pagina 424
sapere quali classi sono disponibili,

creare oggetti di classi esistenti e

inviare loro messaggi (cioè chiamare i loro metodi).

Questo stile di programmazione è chiamato programmazione OBP (objectbased programming) . Quando lo fai
composizione con oggetti di classi conosciute, stai ancora facendo programmazione basata su oggetti.
Aggiunta di ereditarietà con sovrascrittura per personalizzare i metodi in base alle esigenze specifiche del tuo
applicazioni ed eventualmente elaborare oggetti polimorficamente è chiamato orientato agli oggetti
programmazione (OOP) . Se fai la composizione con oggetti di classi ereditate, anche questo
programmazione orientata agli oggetti.

10.9 TIPO DI ANATRE E POLIMORFISMO


La maggior parte degli altri linguaggi di programmazione orientati agli oggetti richiedono "è un" basato sull'ereditarietà
relazioni per ottenere un comportamento polimorfico. Python è più flessibile. Usa un concetto
chiamata dattilografia, che la documentazione di Python descrive come:

Uno stile di programmazione che non guarda al tipo di un oggetto per determinare se ha il diritto
interfaccia; invece, il metodo o l'attributo viene semplicemente chiamato o utilizzato ("Se sembra un papero
7

e ciarlatano come un'anatra, dev'essere un'anatra. ”).

7
TTP: //docs.python.org/3/glossary.html#termducktyping .

Quindi, durante l'elaborazione di un oggetto al momento dell'esecuzione, il suo tipo non ha importanza. Finché il
l'oggetto ha l'attributo di dati, la proprietà o il metodo (con i parametri appropriati) che desideri
per accedere, il codice funzionerà.

Riconsideriamo il ciclo alla fine di ezione 10.8.3, che elabora un elenco di dipendenti:

per dipendente in dipendenti:


stampa (dipendente)
print (f ' {dipendente.earnings () :, .2 f} \ n' )

In Python, questo ciclo funziona correttamente fintanto che i dipendenti contengono solo oggetti che:

possono essere visualizzati con print (ovvero, hanno una rappresentazione di stringa) e

hanno un metodo di guadagno che può essere chiamato senza argomenti.

Tutte le classi ereditano dall'oggetto direttamente o indirettamente, quindi ereditano tutte i metodi predefiniti
per ottenere rappresentazioni di stringa che la stampa può visualizzare. Se una classe ha un guadagno
metodo che può essere chiamato senza argomenti, possiamo includere oggetti di quella classe nell'elenco

dipendenti, anche se la classe dell'oggetto non ha una relazione "è un" con la classe
CommissioneDipendente. Per dimostrarlo, considera la classe WellPaidDuck:

hS
Pagina 425
lecca qui per visualizzare l'immagine del codice

In [1]: class WellPaidDuck:


...: def __repr __ (self):
...: return 'I am a wellpaid duck'
...: def guadagni (self):
...: return Decimal ( '1_000_000.00' )
...:

Gli oggetti WellPaidDuck, che chiaramente non sono pensati per essere dipendenti, funzioneranno con
ciclo precedente. Per dimostrarlo, creiamo oggetti delle nostre classi CommissionEmployee,

SalariedCommissionEmployee e WellPaidDuck e inserirli in un elenco:


lecca qui per visualizzare l'immagine del codice

In [2]: da decimal import Decimal

In [3]: from commissionemployee import CommissionEmployee

In [4]: da salariedcommissionemployee import SalariedCommissionEmployee

In [5]: c = CommissionEmployee ( "Sue" , "Jones" , "333333333" ,


...: Decimale ( '10000.00' ), Decimale ( '0,06' ))
...:

In [6]: s = SalariedCommissionEmployee ( 'Bob' , ' Lewis' , '444444444' ,


...: decimale ( '5000.00' ), decimale ( '0,04' ), decimale ( '300,00' ))
...:

In [7]: d = WellPaidDuck ()

In [8]: dipendenti = [c, s, d]

Ora, elaboriamo l'elenco utilizzando il ciclo da ezione 10.8.3. Come puoi vedere nell'output,
Python è in grado di utilizzare la digitazione anatra per elaborare polimorficamente tutti e tre gli oggetti nell'elenco:

lecca qui per visualizzare l'immagine del codice

In [9]: per i dipendenti nei dipendenti:


...: print (impiegato)
...: print (f ' {dipendente.earnings () :, .2 f} \ n' )
...:
CommissioneDipendente: Sue Jones
numero di previdenza sociale: 333333333
vendite lorde: 10000,00
tasso di commissione: 0,06
600.00

SalariedCommissionDipendente: Bob Lewis


numero di previdenza sociale: 444444444
vendite lorde: 5000.00
tasso di commissione: 0,04
stipendio base: 300,00

S
C
500.00
Pagina 426

Sono un'anatra ben pagata


1.000.000,00

10.10 SOVRACCARICO DELL'OPERATORE


Hai visto che puoi interagire con gli oggetti accedendo ai loro attributi e proprietà e
chiamando i loro metodi. La notazione di chiamata al metodo può essere scomoda per alcuni tipi di
operazioni, come l'aritmetica. In questi casi, sarebbe più conveniente usare Python's
ricco set di operatori incorporati.

Questa sezione mostra come utilizzare l'overloading degli operatori per definire come gli operatori di Python
dovrebbe gestire oggetti del tuo tipo. Hai già utilizzato spesso il sovraccarico dell'operatore
in un'ampia gamma di tipi. Ad esempio, hai utilizzato:

l'operatore + per aggiungere valori numerici, concatenare elenchi, concatenare stringhe e

aggiungendo un valore a ogni elemento in un array NumPy.

l'operatore [] per accedere agli elementi in liste, tuple, stringhe e array e per accedere
il valore per una chiave specifica in un dizionario.

l'operatore * per moltiplicare valori numerici, ripetere una sequenza e moltiplicare ogni
elemento in un array NumPy da un valore specifico.

Puoi sovraccaricare la maggior parte degli operatori. Per ogni operatore sovraccaricabile, l'oggetto class definisce un file

metodo speciale, come __add__ per l'operatore di addizione (+) o __mul__ per
operatore di moltiplicazione (*). L'override di questi metodi consente di definire come un determinato
L'operatore funziona per gli oggetti della tua classe personalizzata. Per un elenco completo di metodi speciali, vedere

ttps: //docs.python.org/3/reference/datamodel.html#specialmethodnames

Restrizioni di sovraccarico dell'operatore

Esistono alcune limitazioni al sovraccarico dell'operatore:

La precedenza di un operatore non può essere modificata mediante sovraccarico. Tuttavia, parentesi
può essere utilizzato per forzare l'ordine di valutazione in un'espressione.

Il raggruppamento da sinistra a destra o da destra a sinistra di un operatore non può essere modificato da
sovraccarico.

L '"arità" di un operatore, cioè che si tratti di un operatore unario o binario, non può essere
cambiato.

Non è possibile creare nuovi operatori: solo gli operatori esistenti possono essere sovraccaricati.

Pagina 427
Il significato di come un operatore lavora su oggetti di tipi incorporati non può essere cambiato.
Non è possibile, ad esempio, cambiare + in modo che sottrae due numeri interi.

L'overloading degli operatori funziona solo con oggetti di classi personalizzate o con una combinazione di un file
oggetto di una classe personalizzata e un oggetto di un tipo incorporato.

Numeri complessi

Per dimostrare il sovraccarico degli operatori, definiremo una classe denominata Complex che rappresenta
8
numeri complessi. I numeri complessi, come –3 + 4i e 6.2 - 11.73i, hanno la forma

8
Python ha il supporto integrato per valori complessi, quindi questa classe è semplicemente per dimostrazione
scopi.

realPart + imaginaryPart * i

dove sono . Come int, float e decimali, i numeri complessi sono tipi aritmetici.

In questa sezione creeremo una classe Complex che sovraccarica solo l'operatore di addizione + e
l'assegnazione aumentata + =, quindi possiamo aggiungere oggetti complessi usando la matematica di Python

notazioni.

10.10.1 Complesso di classi di prova di guida

Per prima cosa, usiamo la classe Complex per dimostrare le sue capacità. Discuteremo i dettagli della classe

nella sezione successiva. Importa la classe Complex da complexnumber.py:

lecca qui per visualizzare l'immagine del codice

In [1]: from complexnumber import Complex

Quindi, crea e visualizza un paio di oggetti complessi. Snippet [3] e [5] chiamano implicitamente
il metodo __repr__ della classe Complex per ottenere una rappresentazione di stringa di ogni oggetto:

lecca qui per visualizzare l'immagine del codice

In [2]: x = complesso (reale = 2 , immaginario = 4 )

In [3]: x
Uscita [3]: (2 + 4i)

In [4]: ​y = Complex (real = 5 , imaginary = 1 )

In [5]: y
Uscita [5]: (5 1i)
Abbiamo scelto il formato della stringa __repr__ mostrato negli snippet [3] e [5] per imitare il
9
__repr__ stringhe prodotte dal tipo complesso incorporato di Python.

C
9 Pagina 428
Python usa j invece di i per. Ad esempio, 3 + 4j (senza spazi attorno all'operatore)
crea un oggetto complesso con attributi reali e immag. La stringa __repr__ per questo

il valore complesso è '(3 + 4j)'.

Ora, usiamo l'operatore + per aggiungere gli oggetti complessi x e y. Questa espressione aggiunge il
parti reali dei due operandi (2 e 5) e le parti immaginarie dei due operandi (4i e

1i), quindi restituisce un nuovo oggetto Complex contenente il risultato:

In [6]: x + y
Uscita [6]: (7 + 3i)

L'operatore + non modifica nessuno dei suoi operandi:

In [7]: x
Uscita [7]: (2 + 4i)

In [8]: y
Uscita [8]: (5 1i)

Infine, usiamo l'operatore + = per aggiungere y a x e memorizzare il risultato in x. L'operatore + =

modifica il suo operando sinistro ma non quello destro:

In [9]: x + = y

In [10]: x
Uscita [10]: (7 + 3i)

In [11]: y
Uscita [11]: (5 1i)

10.10.2 Definizione del complesso di classi

Ora che abbiamo visto la classe Complex in azione, diamo un'occhiata alla sua definizione per vedere come funziona
le capacità sono state implementate.

Metodo __init__

Il metodo __init__ della classe riceve i parametri per inizializzare il reale e l'immaginario
attributi dei dati:

lecca qui per visualizzare l'immagine del codice

1 # complexnumber.py
2 "" "Classe complessa con operatori sovraccarichi." ""
3
Complesso di 4 classi :
5 "" "Classe complessa che rappresenta un numero complesso
6 con parti reali e immaginarie. "" "
7

C
8 def __init __ (self, real, imaginary):
Pagina 429
9 "" "Inizializza gli attributi della classe Complex." ""
10 self.real = reale
11 self.imaginary = immaginario
12

Sovraccarico + Operatore

Il seguente metodo speciale sovrascritto __add__ definisce come sovraccaricare l'operatore +


da utilizzare con due oggetti Complex:

lecca qui per visualizzare l'immagine del codice


13 def __add __ (self, right):
14 "" "Sostituisce l'operatore +." ""
15 return Complex (self.real + right.real,
16 self.imaginary + right.imaginary)
17

I metodi che sovraccaricano gli operatori binari devono fornire due parametri: il primo (self) è il
operando sinistro e il secondo (destro) è l' operando destro . Metodo __add__ di Class Complex
accetta due oggetti Complex come argomenti e restituisce un nuovo oggetto Complex contenente l'estensione

somma delle parti reali degli operandi e somma delle parti immaginarie degli operandi.

Noi non modificare il contenuto di uno dei due operandi originali. Questo corrisponde al nostro intuitivo
senso di come questo operatore dovrebbe comportarsi. L'aggiunta di due numeri non modifica nessuno dei
valori originali.

Sovraccarico + = Assegnazione aumentata

Le righe 18-22 sovraccaricano il metodo speciale __iadd__ per definire come l'operatore + = aggiunge due

Oggetti complessi:

lecca qui per visualizzare l'immagine del codice

18 def __iadd __ (self, right):


19 "" "Sostituisce l'operatore + =." ""
20 self.real + = right.real
21 self.imaginary + = right.imaginary
22 ritorno di sé
23

Gli assegnamenti aumentati modificano i loro operandi di sinistra, quindi il metodo __iadd__ modifica il sé
oggetto, che rappresenta l'operando sinistro, quindi restituisce self.

Metodo __repr__

Le righe 24–28 restituiscono la rappresentazione di stringa di un numero complesso.

lecca qui per visualizzare l'immagine del codice

C
Pagina 430
24 def __repr __ (self):
25 "" "Restituisce la rappresentazione della stringa per repr ()." ""
26 return (f ' ({self.real} ' +
27 ( '+' se self.imaginary> = 0 else '' ) +
28 f ' {abs (self.imaginary)} i)' )

10.11 GERARCHIA DI CLASSE DI ECCEZIONE E PERSONALIZZAZIONE


ECCEZIONI
Nel capitolo precedente abbiamo introdotto la gestione delle eccezioni. Ogni eccezione è un oggetto di a
class nella gerarchia di classi di eccezioni di Python o un0 oggetto di una classe che eredita da una di
quelle classi. Le classi di eccezione ereditano direttamente o indirettamente dalla classe di base

BaseException e sono definiti nelle eccezioni del modulo .

0
ttps: //docs.python.org/3/library/exceptions.html .

Python definisce quattro sottoclassi BaseException primarie: SystemExit ,

KeyboardInterrupt , GeneratorExit ed Exception :

SystemExit termina l'esecuzione del programma (o termina una sessione interattiva) e


quando uncaught non produce un traceback come altri tipi di eccezioni.

Le eccezioni KeyboardInterrupt si verificano quando l'utente digita il comando di interrupt


- Ctrl + C (o control + C ) sulla maggior parte dei sistemi.

Le eccezioni GeneratorExit si verificano quando un generatore si chiude, normalmente quando un generatore


finisce di produrre valori o quando il suo metodo di chiusura viene chiamato esplicitamente.
L'eccezione è la classe base per le eccezioni più comuni che incontrerai. Hai visto
eccezioni delle sottoclassi di eccezione ZeroDivisionError, NameError,

ValueError, StatisticsError, TypeError, IndexError, KeyError, Runtime


Errore e AttributeError. Spesso gli StandardErrors possono essere catturati e gestiti, quindi
il programma può continuare a funzionare.

Catturare le eccezioni della classe base

Uno dei vantaggi della gerarchia delle classi di eccezioni è che un gestore eccetto può catturare

eccezioni di un tipo particolare o può utilizzare un tipo di classe base per catturare quelle classe base
eccezioni e tutte le eccezioni di sottoclasse correlate. Ad esempio, un gestore di eccezione that

specifica che la classe di base Exception può catturare oggetti di qualsiasi sottoclasse di Exception. Posizionamento
un gestore eccetto che cattura il tipo Eccezione prima di altri gestori eccetto è una logica
errore, perché tutte le eccezioni verrebbero rilevate prima che lo siano altri gestori di eccezioni
raggiunto. Pertanto, i gestori di eccezioni successivi non sono raggiungibili.

Classi di eccezione personalizzate

Quando sollevi un'eccezione dal tuo codice, dovresti generalmente usare uno dei file esistenti

h1
Pagina 431
classi di eccezione dalla libreria standard Python. Tuttavia, utilizzando l'ereditarietà
tecniche presentate in precedenza in questo capitolo, è possibile creare la propria eccezione personalizzata
classi che derivano direttamente o indirettamente dalla classe Exception. In generale, questo è scoraggiato,
soprattutto tra i programmatori alle prime armi. Prima di creare classi di eccezioni personalizzate, cercare un file
classe di eccezione esistente appropriata nella gerarchia delle eccezioni Python. Definisci nuova eccezione
classi solo se è necessario catturare e gestire le eccezioni in modo diverso da altre esistenti
tipi di eccezione. Dovrebbe essere raro.

10.12 TUPLES CON NOME


Hai utilizzato le tuple per aggregare diversi attributi di dati in un unico oggetto. Il pitone
Il modulo delle collezioni della Standard Library fornisce anche tuple con nome che ti consentono di
fare riferimento ai membri di una tupla per nome anziché per numero di indice.

Creiamo una semplice tupla con nome che potrebbe essere utilizzata per rappresentare una carta in un mazzo di carte.
Innanzitutto, importa la funzione denominata tuple:

lecca qui per visualizzare l'immagine del codice

In [1]: dalle collezioni importa namedtuple

La funzione namedtuple crea una sottoclasse del tipo di tupla incorporata. La prima funzione
argomento è il nome del nuovo tipo e il secondo è un elenco di stringhe che rappresentano il
identificatori che utilizzerai per fare riferimento ai membri del nuovo tipo:

lecca qui per visualizzare l'immagine del codice

In [2]: Card = namedtuple ( 'Card' , [ 'face' , 'suit' ])

Ora abbiamo un nuovo tipo di tupla denominato Card che possiamo usare ovunque sia possibile utilizzare una tupla.

Creiamo un oggetto Card, accediamo ai suoi membri per nome e visualizziamo la sua rappresentazione di stringa:

lecca qui per visualizzare l'immagine del codice

In [3]: carta = Carta (faccia = 'Asso' , seme = 'Picche' )

In [4]: ​card.face
Uscita [4]: ​"Ace"

In [5]: card.suit
Fuori [5]: "Spades"

In [6]: il card
Fuori [6]: Carta (faccia = 'Asso', seme = 'Picche')
Altre funzionalità di tupla denominate

C
Pagina 432
Ogni tipo di tupla denominato dispone di metodi aggiuntivi. Il metodo della classe _make del tipo (ovvero un file
metodo chiamato sulla classe ) riceve un iterabile di valori e restituisce un oggetto del nome
tipo di tupla:

lecca qui per visualizzare l'immagine del codice

In [7]: values ​= [ "Queen" , "Hearts" ]

In [8]: card = Card._make (valori)

In [9]: il card
Fuori [9]: Carta (faccia = 'Regina', seme = 'Cuori')

Ciò potrebbe essere utile, ad esempio, se si dispone di un tipo di tupla denominato che rappresenta i record in un file
File CSV. Mentre leggi e tokenizza i record CSV, puoi convertirli in tupla con nome
oggetti.

Per un determinato oggetto di un tipo di tupla denominato, è possibile ottenere un dizionario OrderedDict
rappresentazione dei nomi e dei valori dei membri dell'oggetto. Un OrderedDict ricorda il file

ordine in cui le sue coppie chiave-valore sono state inserite nel dizionario:

lecca qui per visualizzare l'immagine del codice

In [10]: card._asdict ()
Out [10]: OrderedDict ([('face', 'Queen'), ('suit', 'Hearts')])

Per funzionalità aggiuntive della tupla denominata vedere:

ttps: //docs.python.org/3/library/collections.html#collections.namedtuple

10.13 BREVE INTRODUZIONE AI NUOVI DATI DI PYTHON 3.7


CLASSI
Sebbene le tuple con nome ti consentano di fare riferimento ai loro membri per nome, sono ancora solo tuple,
non classi. Per alcuni dei vantaggi delle tuple con nome, oltre alle funzionalità tradizionali
1
Le classi Python forniscono, puoi usare le nuove classi di dati di Python 3.7 da Python
Modulo dataclasses della Standard Library .

1
ttps: //www.python.org/dev/peps/pep0557/ .

Le classi di dati sono tra le nuove funzionalità più importanti di Python 3.7. Ti aiutano a costruire
classi più veloci utilizzando più concisa notazione e di autogenerating codice “boilerplate” di quella
comune nella maggior parte delle classi. Potrebbero diventare il modo preferito per definire molti Python
classi. In questa sezione, presenteremo i fondamenti di dataclass. Alla fine della sezione, lo faremo
fornire collegamenti a ulteriori informazioni.

DhC
1h
ata Classes Autogenerate Code

Codice di generazione automatica delle classi di dati Pagina 433

La maggior parte delle classi che definirai forniscono un metodo __init__ per creare e inizializzare un oggetto
attributi e un metodo __repr__ per specificare la rappresentazione di stringa personalizzata di un oggetto. Se una

class ha molti attributi di dati, la creazione di questi metodi può essere noiosa.

Le classi di dati generano automaticamente gli attributi di dati e i metodi __init__ e __repr__ per
tu. Ciò può essere particolarmente utile per le classi che aggregano principalmente elementi di dati correlati.
Ad esempio, in un'applicazione che elabora i record CSV, potresti volere una classe che
rappresenta i campi di ogni record come attributi di dati in un oggetto. Anche le classi di dati possono essere
generato dinamicamente da un elenco di nomi di campo.
Le classi di dati generano automaticamente anche il metodo __eq__ , che sovraccarica l'operatore ==. Qualsiasi classe
che ha un metodo __eq__ supporta anche implicitamente! =. Tutte le classi ereditano gli oggetti della classe
implementazione del metodo predefinito __ne__ (non uguale a), che restituisce l'opposto di __eq__

(o NotImplemented se la classe non definisce __eq__). Le classi di dati non vengono eseguite automaticamente
generare metodi per gli operatori di confronto <, <=,> e> =, ma possono farlo.

10.13.1 Creazione di una classe di dati della carta

Reimplementiamo la scheda di classe da sezione 10.6.2 come classe di dati. La nuova classe è definita in

carddataclass.py. Come vedrai, la definizione di una classe di dati richiede una nuova sintassi. Nel
sottosezioni successive, useremo la nostra nuova classe di dati Card nella classe DeckOfCards per mostrare
che è intercambiabile con la classe Card originale, quindi discuti alcuni dei vantaggi di

classi di dati su tuple con nome e classi tradizionali di Python.

Importazione dalle classi di dati e moduli di digitazione

Il modulo dataclasses della Python Standard Library definisce i decoratori e le funzioni per
implementare classi di dati. Useremo il decoratore @dataclass (importato alla riga 4) per
specifica che una nuova classe è una classe di dati e fa sì che vari codici vengano scritti per te. Richiamare
che la nostra classe Card originale definiva le variabili di classe FACES e SUITS, che sono elenchi di
stringhe utilizzate per inizializzare le carte. Usiamo ClassVar e List dallo standard Python

Modulo di digitazione della libreria (importato alla riga 5) per indicare che FACES e SUITS sono di classe
variabili che fanno riferimento a elenchi . Diremo di più su questi momentaneamente:

lecca qui per visualizzare l'immagine del codice

1 # carddataclass.py
2 "" "Classe di dati della carta con attributi di classe, attributi di dati,
3 metodi generati automaticamente e metodi definiti in modo esplicito. "" "
4 da dataclass importa dataclass
5 da digitazione importazione ClassVar, List
6

Utilizzando @dataclass Decorator

Per specificare che una classe è una classe di dati , fai precedere la sua definizione con @dataclass
2
1C
S
2 Pagina 434
decoratore:

2
ttps: //docs.python.org/3/library/dataclasses.html#modulelevel
ecoratorsclassesandfunctions .

7 @dataclass
Tessera 8 classi :

Facoltativamente, il decoratore @dataclass può specificare parentesi contenenti argomenti che


aiutare la classe di dati a determinare quali metodi generati automaticamente includere. Ad esempio, il file
decorator @dataclass (order = True) causerebbe la generazione automatica della classe di dati
metodi dell'operatore di confronto sovraccaricato per <, <=,> e> =. Questo potrebbe essere utile, per

esempio, se devi ordinare i tuoi oggetti dataclass.

Annotazioni variabili: attributi di classe

A differenza delle classi normali, le classi di dati dichiarano sia gli attributi di classe che gli attributi di dati all'interno del file
class, ma al di fuori dei metodi della classe. In una classe normale, vengono dichiarati solo gli attributi della classe
in questo modo e gli attributi dei dati vengono generalmente creati in __init__. Le classi di dati richiedono

informazioni aggiuntive, o suggerimenti , per distinguere gli attributi di classe dagli attributi di dati, che
influisce anche sui dettagli di implementazione dei metodi generati automaticamente.

Le righe 9-11 definiscono e inizializzano gli attributi della classe FACES e SUITS:

lecca qui per visualizzare l'immagine del codice

9 VOLTI: ClassVar [List [str]] = [ 'Ace' , '2' , '3' , '4' , '5' , '6' , '7' ,
10 "8" , "9" , "10" , "Jack" , "Queen" , "King" ]
11 ABITI: ClassVar [List [str]] = [ 'Hearts' , 'Diamonds' , 'Clubs' , 'Spades'
12

Nelle righe 9 e 11, la notazione

: ClassVar [List [str]]

3, 4
è un'annotazione di variabile (a volte chiamato suggerimento di tipo ) specificando che FACES è una classe
attributo (ClassVar) che fa riferimento a un elenco di stringhe (List [str]). SUITS è anche una classe

attributo che fa riferimento a un elenco di stringhe.

3
ttps: //www.python.org/dev/peps/pep0526/ .

4
Le annotazioni variabili sono una caratteristica del linguaggio recente e sono facoltative per le classi regolari. tu
non li vedrà nella maggior parte del codice Python legacy.

Le variabili di classe vengono inizializzate nelle loro definizioni e sono specifiche della classe , non individuali
oggetti della classe. I metodi __init__, __repr__ e __eq__, tuttavia, possono essere utilizzati con

1C
hd
Pagina 435
oggetti della classe. Quando una classe di dati genera questi metodi, ispeziona tutta la variabile
annotazioni e include solo gli attributi dei dati nelle implementazioni del metodo.

Annotazioni variabili: attributi dei dati

Normalmente, creiamo gli attributi dei dati di un oggetto nel metodo __init__ della classe (o metodi
chiamato da __init__) tramite assegnazioni del modulo self. nome_attributo = valore . Perché a

data class genera automaticamente il suo metodo __init__, abbiamo bisogno di un altro modo per specificare i dati
attributi nella definizione di una classe di dati. Non possiamo semplicemente inserire i loro nomi all'interno della classe,
che genera un'eccezione NameError, come in:

lecca qui per visualizzare l'immagine del codice

In [1]: da dataclass importa dataclass

In [2]: @dataclass
...: classe Demo:
...: x # sta tentando di creare un attributo di dati x
...:

NameError Traceback (la chiamata più recente per ultima)


<ipythoninput279ffe37b1ba2> in <module> ()
> 1 @dataclass
Demo di 2 classi :
3 x # durante il tentativo di creare un attributo dati x
4

<ipythoninput279ffe37b1ba2> in Demo ()
1 @dataclass
Demo di 2 classi :
> 3 x # durante il tentativo di creare un attributo di dati x
4

NameError : il nome "x" non è definito

Come gli attributi di classe, ogni attributo di dati deve essere dichiarato con un'annotazione di variabile. Linee
13-14 definiscono gli attributi dei dati face e suit. L'annotazione della variabile ": str" indica
che ciascuno dovrebbe fare riferimento a oggetti stringa:

13 faccia: str
14 abito: str

Definizione di una proprietà e altri metodi

Le classi di dati sono classi, quindi possono contenere proprietà e metodi e partecipare alla classe
gerarchie. Per questa classe di dati Card, abbiamo definito la stessa proprietà readonly image_name
e metodi speciali personalizzati __str__ e __format__ come nella nostra classe Card originale precedente

nel capitolo:
lecca qui per visualizzare l'immagine del codice

C
Pagina 436
15 @property
16 def image_name (self):
17 "" "Restituisce il nome del file immagine della scheda." ""
18 return str (self) .replace ( '' , '_' ) + '.png'
19
20 def __str __ (self):
21 "" "Restituisce la rappresentazione della stringa per str ()." ""
22 return f ' {self.face} di {self.suit} '
23
24 def __format __ (self, format):
25 "" "Restituisce una rappresentazione di stringa formattata." ""
26 return f ' {str (self): {format}} '

Note di annotazione variabile

Puoi specificare annotazioni di variabili usando nomi di tipo incorporati (come str, int e float),
tipi di classe o tipi definiti dal modulo di digitazione (come ClassVar e List mostrato

prima). Anche con le annotazioni di tipo, Python è ancora un linguaggio tipizzato dinamicamente . Quindi, digita
le annotazioni non vengono applicate al momento dell'esecuzione. Quindi, anche se la faccia di una Carta dovrebbe essere

una stringa, puoi assegnare qualsiasi tipo di oggetto alla faccia.

10.13.2 Utilizzo della classe di dati della carta

Dimostriamo la nuova classe di dati Card. Innanzitutto, crea una carta:

lecca qui per visualizzare l'immagine del codice

In [1]: da carddataclass import Card

In [2]: c1 = Card (Card.FACES [ 0 ], Card.SUITS [ 3 ])

Successivamente, utilizziamo il metodo __repr__ generato automaticamente da Card per visualizzare la Card:

lecca qui per visualizzare l'immagine del codice

In [3]: c1
Fuori [3]: Carta (faccia = 'Asso' , seme = 'Picche' )

Il nostro metodo __str__ personalizzato, che stampa le chiamate quando gli si passa un oggetto Card, restituisce un file
stringa della forma ' faccia del seme ':

In [4]: ​print (c1)


Asso di spade

Accediamo agli attributi della nostra classe di dati e alla proprietà readonly:

lecca qui per visualizzare l'immagine del codice

In [5]: c1.face

Uscita [5]: "Ace"


Pagina 437

In [6]: c1.suit
Fuori [6]: "Spades"

In [7]: c1.image_name
Uscita [7]: "Ace_of_Spades.png"

Successivamente, dimostriamo che gli oggetti Card possono essere confrontati tramite l' autogenerato ==

operatore ed ereditato! = operatore. Per prima cosa, crea due oggetti Carta aggiuntivi, uno identico
al primo e uno diverso:
lecca qui per visualizzare l'immagine del codice

In [8]: c2 = Card (Card.FACES [ 0 ], Card.SUITS [ 3 ])

In [9]: c2
Fuori [9]: Carta (faccia = 'Asso', seme = 'Picche')

In [10]: c3 = Card (Card.FACES [ 0 ], Card.SUITS [ 0 ])

In [11]: c3
Fuori [11]: Carta (faccia = 'Asso', seme = 'Cuori')

Ora confronta gli oggetti usando == e! =:

In [12]: c1 == c2
Out [12]: Vero

In [13]: c1 == c3
Out [13]: Falso

In [14]: c1! = C3
Out [14]: Vero

La nostra classe di dati Card è intercambiabile con la classe Card sviluppata in precedenza in questo capitolo.
Per dimostrarlo, abbiamo creato il file deck2.py contenente una copia della classe DeckOfCards

dal precedente nel capitolo e importato la classe di dati della carta nel file. Il seguente
snippet importare la classe DeckOfCards, creare un oggetto della classe e stamparlo. Richiama questo

print chiama implicitamente il metodo DeckOfCards __str__, che formatta ogni Card in un file
campo di 19 caratteri, risultante in una chiamata al metodo __format__ di ciascuna scheda. Leggi ogni riga

destra a sinistra per confermare che tutte le carte siano visualizzate in ordine da ogni seme (cuori,

Quadri, fiori e picche):

lecca qui per visualizzare l'immagine del codice

In [15]: from deck2 import DeckOfCards # usa la classe di dati Card

In [16]: deck_of_cards = DeckOfCards ()

In [17]: print (deck f Sindrome da distress respiratorio acuto)

C
_o
_c

Asso di cuori 2 di cuori 3 di cuori 4 di cuori


Pagina 438
5 di cuori 6 di cuori 7 di cuori 8 di cuori
9 di cuori 10 di cuori Fante di cuori Regina di cuori
Re di cuori Asso di quadri 2 di quadri 3 di quadri
4 di quadri 5 di quadri 6 di quadri 7 di quadri
8 di quadri 9 di quadri 10 di quadri Fante di quadri
Regina di quadri Re di quadri Asso di fiori 2 di fiori
3 di Club 4 di Club 5 di Club 6 di Club
7 di Club 8 di Club 9 di Club 10 di Club
Fante di fiori Regina di fiori Re di fiori Asso di picche
2 di picche 3 di picche 4 di picche 5 di picche
6 di picche 7 di picche 8 di picche 9 di picche
10 di picche Jack di picche Regina di picche Re di picche

10.13.3 Vantaggi delle classi di dati rispetto alle tuple con nome
5
Le classi di dati offrono diversi vantaggi rispetto alle tuple con nome:

5
ttps: //www.python.org/dev/peps/pep0526/ .

Sebbene ogni tupla denominata rappresenti tecnicamente un tipo diverso, una tupla denominata è un file
tuple e tutte le tuple possono essere confrontate tra loro. Quindi, oggetti di tupla con nome diverso
i tipi potrebbero essere paragonati allo stesso modo se hanno lo stesso numero di membri e lo stesso
valori per quei membri. Il confronto di oggetti di diverse classi di dati restituisce sempre risultati

Falso, così come il confronto di un oggetto di una classe di dati con un oggetto tupla.

Se si dispone di codice che decomprime una tupla, l'aggiunta di più membri a quella tupla interrompe il file
codice di decompressione. Gli oggetti della classe di dati non possono essere decompressi. Quindi puoi aggiungere più dati
attributi a una classe di dati senza interrompere il codice esistente.
Una classe di dati può essere una classe base o una sottoclasse in una gerarchia di ereditarietà.

10.13.4 Vantaggi delle classi di dati rispetto alle classi tradizionali

Le classi di dati offrono anche vari vantaggi rispetto alle tradizionali classi Python che hai visto in precedenza
in questo capitolo:

Una classe di dati genera automaticamente __init__, __repr__ e __eq__, facendoti risparmiare tempo.

Una classe di dati può generare automaticamente i metodi speciali che eseguono l'overload di <, <=,> e> =
operatori di confronto.

Quando si modificano gli attributi dei dati definiti in una classe di dati, utilizzarli in uno script o
sessione interattiva, il codice generato automaticamente si aggiorna automaticamente. Quindi hai meno codice
per mantenere ed eseguire il debug.

Le annotazioni delle variabili richieste per attributi di classe e attributi di dati consentono di farlo
sfruttare gli strumenti di analisi del codice statico. Quindi, potresti essere in grado di eliminare ulteriori file
errori prima che possano verificarsi in fase di esecuzione.

1h

Pagina 439
Alcuni strumenti di analisi del codice statico e IDE possono ispezionare annotazioni e problemi di variabili
avvisi se il codice utilizza il tipo sbagliato. Questo può aiutarti a individuare gli errori logici nel tuo file
codice prima di eseguirlo.

Maggiori informazioni

Le classi di dati hanno funzionalità aggiuntive, come la creazione di istanze "congelate" che non ne hanno
consentono di assegnare valori agli attributi di una classe di dati dopo che l'oggetto è stato creato. Per un
elenco completo dei vantaggi e delle capacità della classe di dati, vedere

ttps: //www.python.org/dev/peps/pep0557/

ttps: //docs.python.org/3/library/dataclasses.html

10.14 UNIT TEST CON DOCSTRINGS E DOCTEST


Un aspetto chiave dello sviluppo del software è testare il codice per assicurarsi che funzioni correttamente.
Anche con test approfonditi, tuttavia, il codice potrebbe contenere ancora bug. Secondo il
il famoso scienziato informatico olandese Edsger Dijkstra, “I test mostrano la presenza, non il
6
assenza di insetti. "

6
J. N. Buxton e B. Randell, eds, Software Engineering Techniques , aprile 1970, p. 16.
Rapporto su una conferenza sponsorizzata dal Comitato scientifico della NATO, Roma, Italia, 27 31
Ottobre 1969

Modulo doctest e funzione testmod

La libreria standard Python fornisce il modulo doctest per aiutarti a testare il tuo codice e
opportunamente riprovare dopo aver apportato le modifiche. Quando esegui il doctest

funzione testmod del modulo , ispeziona le docstring di funzioni, metodi e classi


alla ricerca di istruzioni Python di esempio precedute da >>>, ciascuna seguita nella riga successiva dal
7
output atteso dell'istruzione data (se presente). La funzione testmod li esegue quindi
dichiara e conferma che producono l'output atteso. Se non lo fanno, testmod

segnala gli errori che indicano quali test hanno fallito in modo da poter individuare e risolvere i problemi nel file
codice. Ogni test che definisci in una docstring in genere verifica una specifica unità di codice , come un file
una funzione, un metodo o una classe. Tali test sono chiamati unit test .

7
La notazione >>> imita i prompt di input dell'interprete standard Python.

Classe di conto modificata


Il file accountdoctest.py contiene la classe Account del primo esempio di questo capitolo.
Abbiamo modificato la docstring del metodo __init__ per includere quattro test che possono essere utilizzati

1h

Pagina 440
assicurarsi che il metodo funzioni correttamente:

Il test nella riga 11 crea un oggetto Account di esempio denominato account1. Questa dichiarazione

non produce alcun output.

Il test nella riga 12 mostra quale dovrebbe essere il valore dell'attributo name di account1 se la riga 11
eseguito con successo. L'output di esempio è mostrato nella riga 13.

Il test nella riga 14 mostra quale dovrebbe essere il valore dell'attributo balance di account1 se
riga 11 eseguita con successo. L'output di esempio è mostrato nella riga 15.

Il test nella riga 18 crea un oggetto Account con un saldo iniziale non valido. Il campione

l'output mostra che in questo caso dovrebbe verificarsi un'eccezione ValueError. Per eccezioni, il
La documentazione del modulo doctest consiglia di mostrare solo la prima e l'ultima riga del file
8
rintracciare.

8
ttps: //docs.python.org/3/library/doctest.html?

ighlight = doctest # moduledoctest .

Puoi intervallare i tuoi test con testo descrittivo, come la riga 17.

lecca qui per visualizzare l'immagine del codice

1 # accountdoctest.py
2 "" "Definizione della classe di conto." ""
3 da decimale importazione decimale
4
Conto di 5 classi :
6 "" "Classe di account per dimostrare doctest." ""
7
8 def __init __ (self, name, balance):
9 "" "Inizializza un oggetto Account.
10
11 >>> account1 = Account ('John Green', Decimal ('50 .00 '))
12 >>> account1.name
13 "John Green"
14 >>> account1.balance
15 decimali ('50 .00 ')
16
17 L'argomento balance deve essere maggiore o uguale a 0.
18 >>> account2 = Account ('John Green', Decimal ('50 .00 '))
19 Traceback (la chiamata più recente per ultima):
20 ...
21 ValueError: il saldo iniziale deve essere> = a 0.00.
22 "" "
23
24 # se il saldo è inferiore a 0,00, sollevare un'eccezione
25 se saldo <Decimale ( '0.00' ):
26 raise ValueError ( 'Il saldo iniziale deve essere> = a 0.00.' )
27
28 self.name = nome
29 self.balance = equilibrio
30

C
1h

31 deposito definitivo (auto, importo):


Pagina 441
32 "" "Deposita denaro sul conto." ""
33
34 # se l'importo è inferiore a 0,00, solleva un'eccezione
35 se importo <Decimale ( '0.00' ):
36 raise ValueError ( 'importo deve essere positivo.' )
37
38 self.balance + = importo
39
40 if __name__ == '__main__' :
41 import doctest
42 doctest.testmod (verbose = True )
Modulo __main__
Quando carichi un modulo, Python assegna una stringa contenente il nome del modulo a un globale
attributo del modulo chiamato __name__. Quando esegui un file sorgente Python (come

accountdoctest.py) come script , Python utilizza la stringa "__main__" come


nome. Puoi usare __name__ in un'istruzione if come le righe 40–42 per specificare il codice che dovrebbe
eseguito solo se il file sorgente viene eseguito come uno script . In questo esempio, la riga 41 importa il file

doctest module e la riga 42 chiama la funzione testmod del modulo per eseguire la docstring
unit test.

Esecuzione di test

Eseguire il file accountdoctest.py come script per eseguire i test. Per impostazione predefinita, se chiami

testmod senza argomenti, non mostra i risultati dei test per i test riusciti . In tal caso, se
non ottieni alcun output, tutti i test sono stati eseguiti con successo. In questo esempio, la riga 42 chiama testmod
con l'argomento parola chiave verbose = True. Questo dice a testmod di produrre un output dettagliato

mostrando i risultati di ogni test:

lecca qui per visualizzare l'immagine del codice

Provando:
account1 = Account ('John Green', Decimal ('50 .00 '))
Non aspettarsi niente
ok
Provando:
account1.name
In attesa:
"John Green"
ok
Provando:
account1.balance
In attesa:
Decimale ('50 .00 ')
ok
Provando:
account2 = Account ('John Green', Decimal ('50 .00 '))
In attesa:
Traceback (la chiamata più recente per ultima):
...
ValueError: il saldo iniziale deve essere> = a 0.00.
ok

3 articoli non hanno avuto test:


Pagina 442
__principale__
__account principale
__main __. Account.deposit
1 elementi hanno superato tutti i test:
4 test in __main __. Account .__ init__
4 test in 4 articoli.
4 passati e 0 falliti.
Test superato.

In modalità dettagliata, testmod mostra per ogni test cosa sta "cercando" di fare e cosa è

"In attesa" come risultato, seguito da "ok" se il test ha esito positivo. Dopo aver completato il file
test in modalità dettagliata, testmod mostra un riepilogo dei risultati.

Per dimostrare un test fallito , "commentare" le righe 25-26 in accountdoctest.py di

facendo precedere ciascuno un #, quindi eseguire accountdoctest.py come script. Per risparmiare spazio, mostriamo
solo le parti dell'output del doctest che indicano il test fallito:

lecca qui per visualizzare l'immagine del codice

...
************************************************** ********************
File "accountdoctest.py", riga 18, in __main __. Account .__ init__
Esempio fallito:
account2 = Account ('John Green', Decimal ('50 .00 '))
Previsto:
Traceback (la chiamata più recente per ultima):
...
ValueError: il saldo iniziale deve essere> = a 0.00.
Non ho niente
************************************************** ********************
1 articoli hanno avuto problemi:
1 di 4 in __main __. Account .__ init__
4 test in 4 articoli.
3 sono passati e 1 non è riuscito.
*** Test fallito *** 1 fallimenti.

In questo caso, vediamo che il test della riga 18 è fallito. La funzione testmod si aspettava un traceback
che indica che un'eccezione ValueError è stata sollevata a causa del saldo iniziale non valido. Quell'eccezione

non si è verificato, quindi il test è fallito. In quanto programmatore responsabile della definizione di questa classe, this
il fallimento del test sarebbe un'indicazione che qualcosa non va con il codice di convalida nel tuo

metodo __init__.

IPython% doctest_mode Magic

Un modo conveniente per creare doctest per il codice esistente è utilizzare una sessione interattiva IPython
per testare il codice, quindi copia e incolla quella sessione in una docstring. IPython in [] e

I prompt Out [] non sono compatibili con doctest, quindi IPython fornisce la magia

% doctest_mode per visualizzare i prompt nel formato doctest corretto. La magia si alterna
tra i due stili di prompt. La prima volta che esegui% doctest_mode, IPython

passa a >>> prompt per input e nessun prompt per output. La seconda volta che esegui

C
Pagina 443
doctest_mode, IPython torna ai prompt In [] e Out [].

10.15 SPAZI NOMINALI E SCOPI


Nel capitolo "Funzioni", abbiamo mostrato che ogni identificatore ha un ambito che determina dove
puoi usarlo nel tuo programma e abbiamo introdotto gli ambiti locale e globale. Qui noi
continuare la nostra discussione sugli ambiti con un'introduzione agli spazi dei nomi.

Gli ambiti sono determinati dagli spazi dei nomi , che associano gli identificatori agli oggetti e sono
implementato "sotto il cofano" come dizionari. Tutti gli spazi dei nomi sono indipendenti da uno
un altro. Quindi, lo stesso identificatore può apparire in più spazi dei nomi. Ci sono tre primarie
spazi dei nomi: locale, globale e incorporato.

Spazio dei nomi locale

Ogni funzione e metodo ha uno spazio dei nomi locale che associa identificatori locali (come,
parametri e variabili locali) con oggetti. Lo spazio dei nomi locale esiste dal momento
la funzione o il metodo viene chiamato finché non termina ed è accessibile solo a quella funzione o
metodo. Nella suite di una funzione o di un metodo, l' assegnazione a una variabile che non esiste crea un file
variabile locale e la aggiunge allo spazio dei nomi locale. Gli identificatori nello spazio dei nomi locale sono in
ambito dal punto in cui vengono definiti fino al termine della funzione o del metodo.

Spazio dei nomi globale

Ogni modulo ha uno spazio dei nomi globale che associa gli identificatori globali di un modulo (come
variabili globali, nomi di funzioni e nomi di classi) con oggetti. Python crea un modulo
spazio dei nomi globale quando carica il modulo. Lo spazio dei nomi globale di un modulo esiste e il suo
gli identificatori sono nell'ambito del codice all'interno di quel modulo fino a quando il programma (o interattivo
sessione) termina. Una sessione IPython ha il proprio spazio dei nomi globale per tutti gli identificatori
create in quella sessione.

Lo spazio dei nomi globale di ogni modulo ha anche un identificatore chiamato __name__ contenente il file
il nome del modulo, come 'math' per il modulo math o 'random' per il modulo random.

Come hai visto nell'esempio doctest della sezione precedente, __name__ contiene '__main__' per
un file .py che esegui come script.

Spazio dei nomi integrato

Lo spazio dei nomi incorporato contiene identificatori associati per le funzioni incorporate di Python
(come, input e range) e tipi (come, int, float e str) con oggetti che

definire tali funzioni e tipi. Python crea lo spazio dei nomi incorporato quando l'interprete
inizia l'esecuzione. Gli identificatori dello spazio dei nomi incorporato rimangono nell'ambito di tutto il codice fino a quando il
9
il programma (o la sessione interattiva) termina.
9 il suo presuppone che non si ombreggiano le funzioni oi tipi incorporati ridefinendo i loro

identificatori in uno spazio dei nomi locale o globale. Abbiamo discusso dello shadowing nel capitolo Funzioni.

F
1T
% inding Identificatori negli spazi dei nomi

Trovare identificatori negli spazi dei nomi Pagina 444

Quando usi un identificatore, Python cerca quell'identificatore nel file attualmente accessibile
spazi dei nomi, procedere dal locale al globale al builtin . Per aiutarti a capire il file
ordine di ricerca dello spazio dei nomi, considera la seguente sessione IPython:

lecca qui per visualizzare l'immagine del codice

In [1]: z = "z globale"

In [2]: def print_variables ():


...: y = 'local y in print_variables'
...: print (y)
...: print (z)
...:

In [3]: print_variables ()
locale y in print_variables
z globale

Gli identificatori definiti in una sessione IPython vengono inseriti nello spazio dei nomi globale della sessione .
Quando snippet [3] chiama print_variables, Python cerca in locale , globale e incorporato

spazi dei nomi come segue:

Lo snippet [3] non si trova in una funzione o in un metodo, quindi lo spazio dei nomi globale della sessione e il file
incorporato namespace sono attualmente accessibili. Python cerca prima il file globale della sessione
namespace, che contiene print_variables. Quindi print_variables è nell'ambito e
Python usa l'oggetto corrispondente per chiamare print_variables.

Quando print_variables inizia l'esecuzione, Python crea lo spazio dei nomi locale della funzione .
Quando la funzione print_variables definisce la variabile locale y, Python aggiunge y al file

spazio dei nomi locale della funzione . La variabile y è ora nell'ambito fino al termine della funzione
esecuzione.

Successivamente, print_variables chiama la built funzione di stampa, passando y come argomento.

Per eseguire questa chiamata, Python deve risolvere gli identificatori y e stampare. L'identificatore y è
definito nello spazio dei nomi locale , quindi è nell'ambito e Python utilizzerà il corrispondente
oggetto (la stringa 'local y in print_variables') come argomento di print. Per chiamare il
funzione, Python deve trovare l'oggetto corrispondente di print. Innanzitutto, sembra nel locale

spazio dei nomi, che non definisce la stampa. Successivamente, guarda nel globale della sessione
spazio dei nomi, che non definisce print. Infine, sembra nel incorporato spazio dei nomi,

che fa definire stampa. Quindi, print è nell'ambito e Python usa il corrispondente


oggetto da chiamare print.

Avanti, print_variables chiama l'incorporato funzione di stampa di nuovo con la z argomento,


che non è definito nello spazio dei nomi locale . Quindi, Python cerca nello spazio dei nomi globale .
L'argomento z è definito nello spazio dei nomi globale , quindi z è nell'ambito e Python lo userà
l'oggetto corrispondente (la stringa 'global z') come argomento di print. Di nuovo, Python

C
Pagina 445
trova la stampa identificatore nel incorporato namespace e utilizza l'oggetto corrispondente al
chiama stampa.

A questo punto, arriviamo alla fine della suite della funzione print_variables, quindi la funzione

termina e il suo spazio dei nomi locale non esiste più, il che significa che la variabile locale y è ora
non definito.

Per dimostrare che y non è definito, proviamo a visualizzare y:

lecca qui per visualizzare l'immagine del codice


In [4]: ​y

NameError Traceback (la chiamata più recente per ultima)


<ipythoninput49063a9f0e032> in <module> ()
> 1 anno

NameError : il nome "y" non è definito

In questo caso, non esiste uno spazio dei nomi locale , quindi Python cerca y nel file globale della sessione
spazio dei nomi. L'identificatore y non è definito lì, quindi Python cerca y nel builtin

spazio dei nomi. Di nuovo, Python non trova y. Non ci sono più spazi dei nomi da cercare, quindi
Python solleva un'eccezione NameError, indicando che y non è definito.

Gli identificatori print_variables ez esistono ancora nello spazio dei nomi globale della sessione , quindi noi

può continuare a usarli. Ad esempio, valutiamo z per vedere il suo valore:

In [5]: z
Uscita [5]: "global z"

Funzioni annidate

Uno spazio dei nomi che non abbiamo trattato nella discussione precedente è lo spazio dei nomi che lo racchiude .
Python ti consente di definire funzioni annidate all'interno di altre funzioni o metodi. Per
Ad esempio, se una funzione o un metodo esegue la stessa attività più volte, è possibile definire un file
funzione annidata per evitare di ripetere il codice nella funzione che lo racchiude. Quando accedi a un file
identificatore all'interno di una funzione annidata, Python cerca nello spazio dei nomi locale della funzione annidata
prima, quindi lo spazio dei nomi della funzione che racchiude , quindi lo spazio dei nomi globale e infine il
incorporato namespace. A volte viene indicato come LEGB (locale, inclusivo, globale,
builtin) .

Spazio dei nomi di classe

Una classe ha uno spazio dei nomi in cui sono memorizzati i suoi attributi di classe. Quando accedi a una classe
attributo, Python cerca quell'attributo prima nello spazio dei nomi della classe, poi in quello della classe base
spazio dei nomi e così via, finché non trova l'attributo o raggiunge l'oggetto della classe. Se la
l'attributo non è stato trovato, si verifica un'eccezione NameError.

O
C bject Namespace

Spazio dei nomi degli oggetti Pagina 446

Ogni oggetto ha il proprio spazio dei nomi contenente i metodi e gli attributi dei dati dell'oggetto. Il
il metodo __init__ della classe inizia con un oggetto vuoto (self) e aggiunge ogni attributo al file
spazio dei nomi dell'oggetto. Dopo aver definito un attributo nello spazio dei nomi di un oggetto, i client che utilizzano l'estensione
l'oggetto può accedere al valore dell'attributo.

10.16 INTRO ALLA DATA SCIENCE: SERIE TEMPORALE E SEMPLICE


REGRESSIONE LINEARE
Abbiamo esaminato le sequenze, come elenchi, tuple e array. In questa sezione discuteremo del tempo
serie , che sono sequenze di valori (chiamate osservazioni ) associate a punti nel tempo.
Alcuni esempi sono i prezzi di chiusura giornalieri delle azioni, le letture della temperatura oraria, il cambiamento
posizioni di un aereo in volo, raccolti annuali e profitti aziendali trimestrali. Forse il
Ultimate Time Series è il flusso di tweet con timestamp provenienti dagli utenti di Twitter
In tutto il mondo. Nel capitolo "Data mining Twitter", studieremo i dati di Twitter in modo approfondito.

In questa sezione, useremo una tecnica chiamata regressione lineare semplice da cui fare previsioni
dati di serie temporali. Useremo le alte temperature medie di gennaio dal 1895 al 2018 a New
York City per prevedere le alte temperature medie future di gennaio e stimare la media
Temperature elevate di gennaio per gli anni precedenti il ​1895.

Nel capitolo "Machine Learning", rivisiteremo questo esempio utilizzando la libreria scikitlearn. Nel
nel capitolo "Deep Learning", utilizzeremo reti neurali ricorrenti (RNN) per analizzare il tempo
serie.

Nei capitoli successivi, vedremo che le serie temporali sono popolari nelle applicazioni finanziarie e con
Internet of Things (IoT), di cui parleremo nella sezione " ig Dati: Hadoop, Spark, NoSQL e
oT ”.

In questa sezione, visualizzeremo grafici con Seaborn e panda, che utilizzano entrambi Matplotlib, quindi
avvia IPython con il supporto Matplotlib:

ipython matplotlib

Serie storica

I dati che utilizzeremo sono una serie temporale in cui le osservazioni sono ordinate per anno. Univariata
serie temporali hanno un'osservazione a tempo, come ad esempio la media degli alti gennaio
temperature a New York City per un anno particolare. Le serie temporali multivariate hanno due o
più osservazioni per volta, come temperatura, umidità e pressione barometrica
letture in un'applicazione meteo. Qui analizzeremo una serie temporale univariata.

Due attività spesso eseguite con le serie temporali sono:

Analisi delle serie temporali , che esamina i dati delle serie temporali esistenti per i modelli, aiutando i dati
gli analisti comprendono i dati. Un'attività di analisi comune è cercare la stagionalità nel file

B
io
Pagina 447
dati. Ad esempio, a New York City, l'alta temperatura media mensile varia
significativamente in base alle stagioni (inverno, primavera, estate o autunno).

Previsione delle serie temporali , che utilizza i dati del passato per prevedere il futuro.

In questa sezione eseguiremo la previsione delle serie temporali.

Regressione lineare semplice

Utilizzando una tecnica chiamata regressione lineare semplice , faremo previsioni trovando un file
relazione lineare tra i mesi (gennaio di ogni anno) e la media di New York City
Gennaio alte temperature. Data una raccolta di valori che rappresentano un indipendente
variabile (la combinazione mese / anno) e una variabile dipendente (la media massima
temperatura per quel mese / anno), una semplice regressione lineare descrive la relazione
tra queste variabili con una linea retta, nota come linea di regressione .

Relazioni lineari

Per comprendere il concetto generale di una relazione lineare, considera Fahrenheit e Celsius
temperature. Data una temperatura Fahrenheit, possiamo calcolare il Celsius corrispondente
temperatura utilizzando la seguente formula:

c = 5 / 9 * (f 32 )

In questa formula, f (la temperatura Fahrenheit) è la variabile indipendente e c (la


Temperatura Celsius) è la variabile dipendente: ogni valore di c dipende dal valore di f
utilizzato nel calcolo.

Tracciare le temperature Fahrenheit e le corrispondenti temperature Celsius produce a


retta. Per dimostrarlo, creiamo prima un lambda per la formula precedente e usiamolo per
calcolare gli equivalenti Celsius delle temperature Fahrenheit 0–100 in 10 gradi
incrementi. Memorizziamo ogni coppia Fahrenheit / Celsius come una tupla in temps:

lecca qui per visualizzare l'immagine del codice

In [1]: c = lambda f: 5 / 9 * (f 32 )

In [2]: temps = [(f, c (f)) per f a intervallo ( 0 , 101 , 10 )]

Quindi, posizioniamo i dati in un DataFrame, quindi usiamo il suo metodo di stampa per visualizzare il lineare

relazione tra le temperature Fahrenheit e Celsius. Lo stile del metodo di trama


l'argomento della parola chiave controlla l'aspetto dei dati. Il punto nella stringa "." indica
che ogni punto dovrebbe apparire come un punto e il trattino indica che le linee dovrebbero collegare il
punti. Abbiamo impostato manualmente l' etichetta dell'asse y su "Celsius" perché il metodo di stampa mostra

"Celsius" solo nella legenda dell'angolo superiore sinistro del grafico, per impostazione predefinita.

C
Pagina 448
lecca qui per visualizzare l'immagine del codice

In [3]: importa i panda come pd

In [4]: ​temps_df = pd.DataFrame (temps, columns = [ 'Fahrenheit' , 'Celsius' ])

In [5]: axes = temps_df.plot (x = 'Fahrenheit' , y = 'Celsius' , style = '.' )

In [6]: y_label = axes.set_ylabel ( 'Celsius' )

Componenti dell'equazione di regressione lineare semplice

I punti lungo una qualsiasi linea retta (in due dimensioni) come quelli mostrati nella precedente
grafico può essere calcolato con l'equazione:

y = mx + b

dove

m è la pendenza della linea ,

b è l' intercetta della linea con l' asse y (in x = 0),

x è la variabile indipendente (la data in questo esempio) e

y è la variabile dipendente (la temperatura in questo esempio).

Nella regressione lineare semplice, y è il valore previsto per una data x .

F
C la linea di unzione regredisce dal modulo delle statistiche di SciPy

la linea di unzione regredisce dal modulo delle statistiche di SciPy Pagina 449

La regressione lineare semplice determina la pendenza ( m ) e l'intercetta ( b ) di una linea retta più adatta
si adatta ai tuoi dati. Considera il diagramma seguente, che mostra alcuni dei dati della serie temporale
punti che elaboreremo in questa sezione e una corrispondente linea di regressione. Abbiamo aggiunto verticale
linee per indicare la distanza di ciascun punto dati dalla linea di regressione:
L'algoritmo di regressione lineare semplice regola iterativamente la pendenza e l'intercetta e, per
ogni regolazione, calcola il quadrato della distanza di ogni punto dalla linea. La "soluzione migliore"
si verifica quando i valori di pendenza e intercetta minimizzano la somma di tali distanze al quadrato.
0
Questo è noto come un normale calcolo dei minimi quadrati .

0
ttps: //en.wikipedia.org/wiki/Ordinary_least_squares .

La libreria SciPy (Scientific Python) è ampiamente utilizzata per l'ingegneria, la scienza e la matematica in
Pitone. La funzione linregress di questa libreria (dal modulo scipy.stats ) viene eseguita
semplice regressione lineare per te. Dopo aver chiamato linregress, inserirai la pendenza risultante
e intercetta nell'equazione y = mx + b per fare previsioni.

Panda

Nelle tre sezioni precedenti di Introduzione alla scienza dei dati, hai utilizzato i panda per lavorare con i dati.
Continuerai a usare i panda per tutto il resto del libro. In questo esempio, caricheremo il file
dati per le alte temperature medie di gennaio 1895–2018 di New York City da un file CSV in
un DataFrame. Quindi formatteremo i dati da utilizzare in questo esempio.

Visualizzazione Seaborn

F
2h

Pagina 450
Useremo Seaborn per tracciare i dati del DataFrame con una linea di regressione che mostra la media
andamento delle alte temperature nel periodo 1895–2018.

Acquisizione dei dati meteorologici da NOAA

Otteniamo i dati per il nostro studio. La National Oceanic and Atmospheric Administration
1
(NOAA) offre molti dati storici pubblici, comprese le serie temporali per livelli medi
temperature in città specifiche su vari intervalli di tempo.

1
ttp: //www.noaa.gov .

Abbiamo ottenuto le alte temperature medie di gennaio per New York City dal 1895 fino al
2018 dalla serie temporale "Climate at a Glance" della NOAA a:

ttps: //www.ncdc.noaa.gov/cag/

In quella pagina web, puoi selezionare temperatura, precipitazioni e altri dati per l'intero
Stati Uniti, regioni all'interno degli Stati Uniti, stati, città e altro ancora. Dopo aver impostato l'area e l'intervallo di tempo,
fare clic su Grafico per visualizzare un diagramma e visualizzare una tabella dei dati selezionati. In cima a quel tavolo
sono collegamenti per scaricare i dati in diversi formati, incluso CSV, di cui abbiamo discusso in
il capitolo "File ed eccezioni". L'intervallo di date massimo di NOAA disponibile al momento di questo
la scrittura era 1895–2018. Per tua comodità, abbiamo fornito i dati negli esempi ch10

cartella nel file ave_hi_nyc_jan_18952018.csv. Se scarichi i dati sul tuo


proprio, elimina le righe sopra la riga contenente "Data, Valore, Anomalia".

Questi dati contengono tre colonne per osservazione:


Data: un valore nel formato "AAAAMM" (ad esempio "201801"). MM è sempre 01 perché noi
dati scaricati solo per gennaio di ogni anno.

Valore: una temperatura Fahrenheit in virgola mobile.

Anomalia: la differenza tra il valore per la data specificata e i valori medi per tutti
date. Non usiamo il valore Anomaly in questo esempio, quindi lo ignoreremo.

Caricamento delle temperature medie alte in un DataFrame

Carichiamo e visualizziamo i dati di New York City da ave_hi_nyc_jan_18952018.csv:

lecca qui per visualizzare l'immagine del codice

In [7]: nyc = pd.read_csv ( 'ave_hi_nyc_jan_18952018.csv' )

Possiamo guardare la testa e la coda del DataFrame per avere un'idea dei dati:

lecca qui per visualizzare l'immagine del codice

hC
2h

Pagina 451
In [8]: nyc.head ()
Fuori [8]:
Anomalia valore data
0 189501 34,2 3.2
1 189601 34,7 2.7
2 189701 35,5 1.9
3 189801 39,6 2.2
4 189901 36,4 1.0

In [9]: nyc.tail ()
Fuori [9]:
Anomalia valore data
119 201401 35,5 1.9
120 201501 36,1 1.3
121 201601 40,8 3.4
122 201701 42,8 5.4
123 201801 38,7 1.3

Pulizia dei dati

Presto utilizzeremo Seaborn per rappresentare graficamente le coppie DateValue e una linea di regressione. Durante la stampa
dati da un DataFrame, Seaborn etichetta gli assi di un grafico utilizzando la colonna del DataFrame

nomi. Per una maggiore leggibilità, rinomina la colonna "Valore" come "Temperatura":

lecca qui per visualizzare l'immagine del codice

In [10]: nyc.columns = [ "Date" , "Temperature" , "Anomaly" ]

In [11]: nyc.head ( 3 )
Fuori [11]:
Anomalia della temperatura della data
0 189501 34,2 3.2
1 189601 34,7 2.7
2 189701 35,5 1.9

Seaborn etichetta i segni di graduazione sull'asse x con valori di data. Poiché questo esempio processa
solo temperature di gennaio, le etichette dell'asse x saranno più leggibili se non contengono 01
(per gennaio), lo rimuoveremo da ogni data. Innanzitutto, controlliamo il tipo di colonna:

In [12]: nyc.Date.dtype
Uscita [12]: dtype ('int64')

I valori sono numeri interi, quindi possiamo dividere per 100 per troncare le ultime due cifre. Richiama questo
ogni colonna in un DataFrame è una serie. La chiamata al metodo Series floordiv viene eseguita
divisione intera su ogni elemento della serie:

lecca qui per visualizzare l'immagine del codice


In [13]: nyc.Date = nyc.Date.floordiv ( 100 )

In [14]: nyc.head ( 3 )

Fuori [14]:
Pagina 452
Anomalia della temperatura della data
0 1895 34,2 3.2
1 1896 34,7 2.7
2 1897 35,5 1.9

Calcolo delle statistiche descrittive di base per il set di dati

Per alcune statistiche rapide sulle temperature del set di dati, chiama Descrivi sulla temperatura
colonna. Possiamo vedere che ci sono 124 osservazioni, il valore medio delle osservazioni è
37,60 e le osservazioni più bassa e più alta sono rispettivamente di 26,10 e 47,60 gradi:

lecca qui per visualizzare l'immagine del codice

In [15]: pd.set_option ( 'precision' , 2)

In [16]: nyc.Temperature.describe ()
Fuori [16]:
contare 124.00
significa 37.60
std 4.54
min 26.10
25% 34,58
50% 37,60
75% 40,60
max 47,60
Nome: temperatura, dtype: float64

Previsione delle temperature alte medie future di gennaio

La libreria SciPy (Scientific Python) è ampiamente utilizzata per l'ingegneria, la scienza e la matematica in
Pitone. Il suo modulo delle statistiche fornisce la funzione linregress , che calcola una regressione
pendenza della linea e intercetta per un dato insieme di punti dati:

lecca qui per visualizzare l'immagine del codice

In [17]: from scipy import stats

In [18]: linear_regression = stats.linregress (x = nyc.Date,


...: y = nyc.Temperature)
...:

2
La funzione linregress riceve due array unidimensionali della stessa lunghezza
che rappresentano le coordinate x e y dei punti dati . Gli argomenti della parola chiave x e y rappresentano

rispettivamente le variabili indipendenti e dipendenti. L'oggetto restituito da linregress


contiene la pendenza e l'intercetta della retta di regressione:

2
Questi argomenti possono anche essere oggetti simili ad array monodimensionali, come elenchi o panda
Serie.

lecca qui per visualizzare l'immagine del codice

2C

Pagina 453
In [19]: linear_regression.slope
Uscita [19]: 0.00014771361132966167

In [20]: linear_regression.intercept
Uscita [20]: 8.694845520062952

Possiamo usare questi valori con l'equazione di regressione lineare semplice per una linea retta, y = mx
+ b , per prevedere la temperatura media di gennaio a New York City per un dato anno. Andiamo
prevedere la temperatura media Fahrenheit per gennaio 2019. Nel calcolo seguente,

linear_regression.slope è m , 2019 è x (il valore della data per il quale si desidera prevedere
la temperatura) e linear_regression.intercept è b :

lecca qui per visualizzare l'immagine del codice

In [21]: linear_regression.slope * 2019 + linear_regression.intercept


Uscita [21]: 38,51837136113298

Possiamo anche approssimare quale potrebbe essere stata la temperatura media negli anni precedenti
1895. Ad esempio, approssimiamo la temperatura media del gennaio 1890:

lecca qui per visualizzare l'immagine del codice

In [22]: linear_regression.slope * 1890 + linear_regression.intercept


Uscita [22]: 36.612865774980335

Per questo esempio, avevamo dati per il periodo 1895–2018. Dovresti aspettarti che più vai avanti
al di fuori di questo intervallo, meno affidabili saranno le previsioni.

Tracciare le temperature medie alte e una linea di regressione

Successivamente, usiamo la funzione regplot di Seaborn per tracciare ogni punto dati con le date sulla x ​

asse e le temperature sull'asse y . La funzione regplot crea il grafico a dispersione o


scattergram sotto in cui i punti sparsi rappresentano le Temperature per il dato

Date e la linea retta visualizzata attraverso i punti è la linea di regressione:

C
Pagina 454

Innanzitutto, chiudi la precedente finestra Matplotlib se non l'hai già fatto, altrimenti
regplot utilizzerà la finestra esistente che contiene già un grafico. Funzione x di regplot
3
e gli argomenti delle parole chiave y sono array unidimensionali della stessa lunghezza che rappresentano il
Xy coppie di coordinate di trama. Ricorda che i panda creano automaticamente attributi per ciascuno
4
nome della colonna se il nome può essere un identificatore Python valido:
3
Questi argomenti possono anche essere oggetti simili ad array monodimensionali, come elenchi o panda

Serie.

4
Per i lettori con uno sfondo più statistico, l'area ombreggiata che circonda la regressione
la linea è l' intervallo di confidenza del 95% per la linea di regressione
( ttps: //en.wikipedia.org/wiki/Simple_linear_regression#Confidence_interva S
o disegnare il diagramma senza un intervallo di confidenza, aggiungere l'argomento della parola chiave ci = None a

la lista degli argomenti della funzione regplot.

lecca qui per visualizzare l'immagine del codice

In [23]: importa seaborn come sns

In [24]: sns.set_style ( 'whitegrid' )

In [25]: axes = sns.regplot (x = nyc.Date, y = nyc.Temperature)

La pendenza della linea di regressione (inferiore a sinistra e superiore a destra) indica un riscaldamento
trend degli ultimi 124 anni. In questo grafico, l' asse y rappresenta una temperatura di 21,5 gradi
range tra il minimo di 26,1 e il massimo di 47,6, quindi i dati sembrano essere

2T
lhC
Pagina 455
pread significativamente sopra e sotto la linea di regressione, rendendo difficile vedere la linea
relazione. Questo è un problema comune nelle visualizzazioni di analisi dei dati. Quando hai assi che
riflettono diversi tipi di dati (date e temperature in questo caso), come si fa ragionevolmente
determinare le rispettive scale? Nel grafico precedente, questo è puramente un problema di
del grafico altezza Seaborn e Matplotlib autoscale assi, a seconda della distanza dei dati di
valori. Possiamo scalare l' intervallo di valori dell'asse y per enfatizzare la relazione lineare. Qui noi
ridimensionato l' asse y da un intervallo di 21,5 gradi a un intervallo di 60 gradi (da 10 a 70 gradi):

lecca qui per visualizzare l'immagine del codice

In [26]: axes.set_ylim ( 10 , 70 )
Uscita [26]: (10, 70)

Recupero di set di dati di serie temporali

Di seguito sono riportati alcuni siti popolari in cui è possibile trovare serie temporali da utilizzare nei propri studi:

Set di dati serie temporale delle origini


ttps: //data.gov/

Questo è il portale di dati aperti del governo degli Stati Uniti. La ricerca di "serie temporali" produce
oltre 7200 set di dati timeseries.

S
hC
Pagina 456

ttps: //www.ncdc.noaa.gov/cag/

Il clima della National Oceanic and Atmospheric Administration (NOAA) in sintesi


Il portale fornisce serie temporali globali e relative alle condizioni meteorologiche statunitensi.

ttps: //www.esrl.noaa.gov/psd/data/timeseries/

Il portale ESRL (Earth System Research Laboratory) di NOAA fornisce mensilmente e


serie temporali stagionali legate al clima.

ttps: //www.quandl.com/search

Quandl fornisce centinaia di serie temporali gratuite di natura finanziaria, oltre a feebased
serie temporali.

ttps: //datamarket.com/data/list/? q = provider: tsdl

La Time Series Data Library (TSDL) fornisce collegamenti a centinaia di serie temporali
set di dati in molti settori.

ttp: //archive.ics.uci.edu/ml/datasets.html

Il repository di machine learning dell'Università della California Irvine (UCI) contiene


dozzine di dataset serie temporali per una varietà di argomenti.

ttp: //inforumweb.umd.edu/econdata/econdata.html

Il servizio EconData dell'Università del Maryland fornisce collegamenti a migliaia di


serie storiche economiche di varie agenzie governative degli Stati Uniti.

10.17 WRAP-UP
In questo capitolo, abbiamo discusso i dettagli della creazione di classi preziose. Hai visto come definire un file
class, crea oggetti della classe, accedi agli attributi di un oggetto e chiama i suoi metodi. tu
ha definito il metodo speciale __init__ per creare e inizializzare gli attributi dei dati di un nuovo oggetto.

Abbiamo discusso il controllo dell'accesso agli attributi e l'utilizzo delle proprietà. Abbiamo dimostrato che tutti gli oggetti

h
Pagina 457
ttributes può essere letto direttamente da un client. Abbiamo discusso di identificatori con interlinea singola
trattini bassi (_), che indicano attributi a cui non si intende accedere dal codice client.
Abbiamo mostrato come implementare attributi "privati" tramite il doubleunderscore (__)
convenzione di denominazione, che dice a Python di manipolare il nome di un attributo.

Abbiamo implementato una simulazione di mescolamento e distribuzione delle carte composta da una classe di carte e un file

DeckOfCards classe che manteneva un elenco di carte e mostrava il mazzo entrambi come stringhe
e come immagini di carte utilizzando Matplotlib. Abbiamo introdotto metodi speciali __repr__, __str__

e __format__ per creare rappresentazioni di stringa di oggetti.


Successivamente, abbiamo esaminato le capacità di Python per la creazione di classi di base e sottoclassi. Abbiamo mostrato
come creare una sottoclasse che erediti molte delle sue capacità dalla sua superclasse, quindi aggiunge
più capacità, possibilmente sovrascrivendo i metodi della classe base. Abbiamo creato una lista
contenente sia oggetti di classe base che di sottoclasse per dimostrare il polimorfismo di Python
capacità di programmazione.

Abbiamo introdotto l'overloading degli operatori per definire come funzionano gli operatori incorporati di Python
oggetti di tipi di classe personalizzati. Hai visto che i metodi dell'operatore sovraccaricato sono implementati da
sovrascrivendo vari metodi speciali che tutte le classi ereditano dall'oggetto classe. Abbiamo discusso
la gerarchia delle classi di eccezioni Python e la creazione di classi di eccezioni personalizzate.

Abbiamo mostrato come creare una tupla denominata che consente di accedere agli elementi della tupla tramite
nomi di attributi piuttosto che numeri di indice. Successivamente, abbiamo introdotto i nuovi dati di Python 3.7
classi, che possono generare automaticamente vari codici boilerplate comunemente forniti in classe
definizioni, come i metodi speciali __init__, __repr__ e __eq__.

Hai visto come scrivere unit test per il tuo codice in docstrings, quindi eseguire quei test
comodamente tramite la funzione testmod del modulo doctest. Infine, abbiamo discusso i vari
spazi dei nomi che Python utilizza per determinare gli ambiti degli identificatori.

Nella parte successiva del libro, presentiamo una serie di studi di casi di implementazione che utilizzano un mix
delle tecnologie AI e bigdata. Esploriamo l'elaborazione del linguaggio naturale, il data mining
Twitter, IBM Watson e cognitive computing, macchina supervisionata e non supervisionata
learning e deep learning con reti neurali convoluzionali e neurali ricorrenti
reti. Discutiamo di software bigdata e infrastruttura hardware, incluso NoSQL
database, Hadoop e Spark con una grande enfasi sulle prestazioni. Stai per vedere
alcune cose davvero interessanti!

un'
Pagina 458

Playlist

storia
11. Elaborazione del linguaggio naturale (PNL)
opiche
Obiettivi

In questo capitolo potrai:


guadagnando Pat

Eseguire attività di elaborazione del linguaggio naturale (NLP), fondamentali per molti dei file
ffers & Dea
prossimi capitoli di case study sulla scienza dei dati.

ighlights
Esegui molte demo di PNL.

ettings Usa le librerie TextBlob, NLTK, Textatistic e spaCy NLP ei loro modelli pre-addestrati
per eseguire vari compiti di PNL.
Supporto

Tokenizza il testo in parole e frasi.


Disconnessione

Usa parti di tag vocale.

Utilizza l'analisi del sentiment per determinare se il testo è positivo, negativo o neutro.

Rileva la lingua del testo e traduci tra le lingue utilizzando Google di TextBlob
Traduci supporto.
Ottieni radici di parole tramite stemming e lemmatization.

Usa le capacità di controllo ortografico e correzione di TextBlob.

Ottieni definizioni di parole, sinonimi e contrari.

Rimuovi le parole chiave dal testo.

Crea nuvole di parole.

Determina la leggibilità del testo con Textatistic.

Usa la libreria spaCy per il riconoscimento di entità denominate e il rilevamento di somiglianze.

Contorno

1.1 Introduzione

1.2 TextBlob

1.2.1 Creare un TextBlob

1.2.2 Tokenizzazione del testo in frasi e parole

1.2.3 Parti di contrassegno vocale Pagina 459

1.2.4 Estrazione di frasi sostantive

1.2.5 Analisi del sentiment con il Sentiment Analyzer predefinito di TextBlob

1.2.6 Analisi del sentiment con NaiveBayesAnalyzer

1.2.7 Rilevamento e traduzione della lingua

1.2.8 Flessione: pluralizzazione e singolarizzazione

1.2.9 Controllo ortografico e correzione

1.2.10 Normalizzazione: stemming e lemmatizzazione

1.2.11 Frequenze di parole

1.2.12 Ottenere definizioni, sinonimi e contrari da WordNet

1.2.13 Eliminazione di parole di arresto

1.2.14 ngram

1.3 Visualizzazione delle frequenze delle parole con grafici a barre e nuvole di parole

1.3.1 Visualizzazione delle frequenze delle parole con i Panda

1.3.2 Visualizzazione delle frequenze delle parole con le nuvole di parole

1.4 Valutazione della leggibilità con Textatistic

1.5 Riconoscimento di entità designate con spaCy

1.6 Rilevamento di similarità con spaCy

1.7 Altre librerie e strumenti della PNL

1.8 Apprendimento automatico e apprendimento approfondito del linguaggio naturale

1.9 Set di dati in linguaggio naturale

1.10 WrapUp

11.1 INTRODUZIONE
La sveglia ti sveglia e premi il pulsante "Allarme disattivato". Raggiungi il tuo smartphone
e leggi i tuoi messaggi di testo e controlla le ultime clip di notizie.Ascolti i conduttori televisivi
intervistando celebrità. Parli a familiari, amici e colleghi e ascolti i loro
risposte. Hai un amico con problemi di udito con il quale comunichi tramite segno
lingua e chi ama i programmi video con didascalie chiuse. Hai un collega cieco che
legge il braille, ascolta i libri letti da un lettore di libri computerizzato e ascolta un file
lo screen reader parla di cosa c'è sullo schermo del suo computer.Leggi le e-mail, distinguendo

1
scartare da comunicazioni importanti e inviare email. Leggi romanzi o opere di non Pagina 460
finzione. Guidi, osservando segnali stradali come "Stop", "Speed ​Limit 35" e "Road Under
Costruzione." Dai alla tua auto comandi verbali, come "chiama casa", "suona musica classica" o
fare domande come "Dov'è il distributore di benzina più vicino?" Insegni a un bambino a parlare e
leggere. Mandi un biglietto di simpatia a un amico. Leggi libri. Leggi giornali e
riviste. Prendi appunti durante una lezione o una riunione. Impari una lingua straniera per prepararti
per viaggi all'estero. Ricevi un'e-mail del cliente in spagnolo e la esegui attraverso una traduzione gratuita
programma. Rispondi in inglese sapendo che il tuo cliente può tradurre facilmente la tua email
torna in spagnolo. Non sei sicuro della lingua di un'e-mail, ma il rilevamento della lingua
il software lo capisce immediatamente e traduce l'e-mail in inglese.

Questi sono esempi di comunicazioni in linguaggio naturale in testo, voce, video, segno
lingua, braille e altre forme con lingue come inglese, spagnolo, francese, russo,
Cinese, giapponese e altre centinaia. In questo capitolo imparerai a padroneggiare molti linguaggi naturali
capacità di elaborazione (NLP) attraverso una serie di demo manuali e sessioni IPython.
Utilizzerai molte di queste funzionalità di PNL nei prossimi capitoli di case study sulla scienza dei dati.

L'elaborazione del linguaggio naturale viene eseguita su raccolte di testo, composte da Tweet, Facebook
post, conversazioni, recensioni di film, opere di Shakespeare, documenti storici, notizie,
registri delle riunioni e molto altro ancora. Una raccolta di testi è nota come corpus , il cui plurale
è corpora .

Il linguaggio naturale manca di precisione matematica. Sfumature di significato creano il linguaggio naturale
comprensione difficile. Il significato di un testo può essere influenzato dal suo contesto e da quello del lettore
"Visione del mondo". I motori di ricerca, ad esempio, possono "conoscerti" tramite il tuo precedente
ricerche. Il vantaggio è che i risultati di ricerca sono migliori. Lo svantaggio potrebbe essere una violazione della privacy.

1
11.2 TEXTBLOB
1
ttps: //textblob.readthedocs.io/en/latest/ .

TextBlob è una libreria di elaborazione del testo NLP orientata agli oggetti costruita su NLTK e
pattern NLP librerie e semplifica molte delle loro capacità. Alcuni dei compiti della PNL
TextBlob può eseguire includono:

Tokenizzazione: suddivisione del testo in parti chiamate gettoni , che sono unità significative,
come parole e numeri.

Tagging Partsofspeech (POS): identificare la parte del discorso di ciascuna parola, come nome,
verbo, aggettivo, ecc.

Estrazione di frasi di nomi: assegnazione di gruppi di parole che rappresentano nomi, come "rosso
2
fabbrica di mattoni. "

2
La frase fabbrica di mattoni rossi illustra perché il linguaggio naturale è un argomento così difficile.
Una fabbrica di mattoni rossi è una fabbrica che produce mattoni rossi? È una fabbrica rossa che produce mattoni
di qualsiasi colore? È una fabbrica di mattoni rossi che realizza prodotti di qualsiasi tipo? In oggi s
mondo della musica, potrebbe anche essere il nome di una rock band o il nome di un gioco sul tuo
smartphone.

hj
Analisi del sentimento: determinare se il testo è positivo, neutro o negativo Pagina 461
sentimento.

Traduzione interlinguistica e rilevamento della lingua forniti da Google Translate.

3
Inflessione —Pluralizzare e singolarizzare le parole. Ci sono altri aspetti dell'inflessione
che non fanno parte di TextBlob.

3
ttps: //en.wikipedia.org/wiki/Inflection .

Controllo ortografico e correzione ortografica .


Stemming parole -riduzione al loro steli rimuovendo prefissi o suffissi. Per
esempio, la radice di "varietà" è "varieti".

Lemmatizzazione: come lo stemming, ma produce parole reali basate sulle parole originali '
contesto. Ad esempio, la forma lemmatizzata di "varietà" è "varietà".

Frequenze delle parole: determinare la frequenza con cui ogni parola appare in un corpus.

Integrazione con WordNet per trovare definizioni di parole, sinonimi e contrari.

Interrompere l'eliminazione delle parole: rimuovere le parole comuni, come a, an, the, I, we, you and
più per analizzare le parole importanti in un corpus.

ngrams -produzione di insiemi di parole consecutive in un corpus serve per identificare le parole
che spesso appaiono adiacenti l'uno all'altro.

Molte di queste funzionalità vengono utilizzate come parte di attività di PNL più complesse.In questa sezione, lo faremo
eseguire queste attività NLP utilizzando TextBlob e NLTK.

Installazione del modulo TextBlob


Per installare TextBlob, apri il tuo Anaconda Prompt (Windows), Terminal (macOS / Linux) o
shell (Linux), quindi eseguire il seguente comando:

lecca qui per visualizzare l'immagine del codice

conda installa c condaforge textblob

Gli utenti Windows potrebbero dover eseguire il prompt di Anaconda come amministratore per
privilegi di installazione del software. Per fare ciò, fai clic con il pulsante destro del mouse su Prompt di Anaconda nel menu di avvio e
seleziona Altro> Esegui come amministratore.

Al termine dell'installazione, eseguire il comando seguente per scaricare i corpora NLTK


utilizzato da TextBlob:

lecca qui per visualizzare l'immagine del codice

ipython m textblob.download_corpora

hC
Questi includono: Pagina 462

Il Brown Corpus (creato presso la Brown University ) per parti di etichettatura vocale.

4
ttps: //en.wikipedia.org/wiki/Brown_Corpus .

Punkt per la tokenizzazione delle frasi in inglese.

WordNet per definizioni di parole, sinonimi e contrari.

Tagger Perceptron medio per parti di etichettatura vocale.

conll2000 per suddividere il testo in componenti, come nomi, verbi, frasi nominali e altro -
noto come frammentazione del testo. Il nome conll2000 proviene dalla conferenza che ha creato
i dati chunking — Conference on Computational Natural Language Learning.

Recensioni di film per l'analisi del sentiment.

Progetto Gutenberg

Un'ottima fonte di testo per l'analisi sono gli ebook gratuiti del Progetto Gutenberg:

ttps: //www.gutenberg.org

Il sito contiene oltre 57.000 ebook in vari formati, inclusi file di testo semplice. Questi sono
fuori dal copyright negli Stati Uniti. Per informazioni sui Termini di utilizzo del progetto Gutenberg
e copyright in altri paesi, vedere:

ttps: //www.gutenberg.org/wiki/Gutenberg: Terms_of_Use


In alcuni degli esempi di questa sezione, utilizziamo il file ebook in chiaro per ilRomeo di Shakespeare
e Juliet , che puoi trovare su:

ttps: //www.gutenberg.org/ebooks/1513

Il progetto Gutenberg non consente l'accesso programmatico ai suoi ebook. Devi copiare
5
i libri a tale scopo . Per scaricare Romeo e Giulietta come ebook in chiaro, giusto
fai clic sul link Testo normale UTF8 nella pagina web del libro, quindi seleziona Salva collegamento con nome ...
(Chrome / FireFox), Scarica file collegato come ... (Safari) o Salva destinazione con nome (Microsoft
Edge) per salvare il libro sul tuo sistema. Salvalo come RomeoAndJuliet.txt nel ch11
cartella di esempi per garantire che i nostri esempi di codice funzionino correttamente. A scopo di analisi,
abbiamo rimosso il testo del progetto Gutenberg prima di "LA TRAGEDIA DI ROMEO E GIULIETTA",

così come le informazioni sul progetto Guttenberg alla fine del file che iniziano con:

ttps: //www.gutenberg.org/wiki/Gutenberg: Information_About_Robot_Access_to_ou _Pages

Fine del progetto Gutenberg EBook di Romeo e Giulietta, di William Shakespeare

11.2.1 Creare un TextBlob

4r
h
TextBlob è la classe fondamentale per la PNL con il modulo textblob . Creiamo un file
Pagina 463

TextBlob contenente due frasi:

ttp: //textblob.readthedocs.io/en/latest/api_reference.html#textblob.blob.Tex Blob

lecca qui per visualizzare l'immagine del codice

In [1]: da textblob importa TextBlob

In [2]: text = 'Oggi è una bella giornata. Domani sembra brutto tempo.

In [3]: blob = TextBlob (text)

In [4]: ​blob
Out [4]: ​TextBlob ("Oggi è una bella giornata. Domani sembra brutto tempo."

extBlobs e, come vedrai tra poco, Sentences and Words, supportano i metodi string e
può essere confrontato con le stringhe. Forniscono anche metodi per vari compiti di PNL. Frasi,

Words e TextBlob ereditano da BaseBlob , quindi hanno molti metodi comuni e


proprietà.

11.2.2 Tokenizzazione del testo in frasi e parole

L'elaborazione del linguaggio naturale spesso richiede la tokenizzazione del testo prima di eseguire altri NLP
compiti. TextBlob fornisce proprietà convenienti per accedere alle frasi e alle parole in

TextBlobs. Usiamo la proprietà frase per ottenere un elenco di oggetti Frase :

lecca qui per visualizzare l'immagine del codice

In [5]: blob.sentences
Fuori [5]:
[Frase ("Oggi è una bella giornata."),
Frase ("Domani sembra brutto tempo.")]

La proprietà words restituisce un oggetto WordList contenente un elenco di oggetti Word ,


che rappresenta ogni parola nel TextBlob con la punteggiatura rimossa:

lecca qui per visualizzare l'immagine del codice

In [6]: blob.words
Out [6]: WordList (["Today", "is", "a", "beautiful", "day", "Tomorrow", "looks" like ",

1.2.3 Etichettatura di parti del discorso

Il tagging di Partsofspeech (POS) è il processo di valutazione delle parole in base al loro contesto
per determinare la parte del discorso di ciascuna parola. Ci sono otto parti principali del discorso in inglese:
sostantivi, pronomi, verbi, aggettivi, avverbi, preposizioni, congiunzioni e interiezioni
(parole che esprimono emozioni e che sono tipicamente seguite da punteggiatura, come "Sì!" o
"Ah!"). All'interno di ogni categoria ci sono molte sottocategorie.

1
6C
htT
Alcune parole hanno molteplici significati. Ad esempio, le parole "set" e "run" hanno centinaia Pagina 464
di significati ciascuno! Se guardi le definizioni di dictionary.com della parola "corri", lo farai
vedi che può essere un verbo, un sostantivo, un aggettivo o una parte di una frase verbale.Un uso importante di
L'etichettatura POS determina il significato di una parola tra i suoi molti significati.Questo è
importante per aiutare i computer a "comprendere" il linguaggio naturale.

La proprietà tags restituisce un elenco di tuple, ciascuna contenente una parola e una stringa che rappresenta
il suo tag partofspeech:

lecca qui per visualizzare l'immagine del codice

In [7]: blob
Out [7]: TextBlob ("Oggi è una bella giornata. Domani sembra brutto tempo."

n [8]: blob.tags
Fuori [8]:
[("Oggi", "NN"),
('è', 'VBZ'),
('a', 'DT'),
('beautiful', 'JJ'),
("giorno", "NN"),
("Domani", "NNP"),
("sembra", "VBZ"),
('come in'),
('cattivo', 'JJ'),
('weather', 'NN')]

Per impostazione predefinita, TextBlob utilizza un PatternTagger per determinare partsofspeech. Questa classe utilizza
le funzionalità di tag di partsofspeech della libreria di pattern :

ttps: //www.clips.uantwerpen.be/pattern

È possibile visualizzare i 63 tag partsofspeech della libreria all'indirizzo

ttps: //www.clips.uantwerpen.be/pages/MBSPtags

Nell'output dello snippet precedente:

Oggi, giorno e tempo sono contrassegnati come NN, un nome singolare o un nome di massa.

è e gli sguardi sono etichettati come VBZ, un verbo presente singolare in terza persona.

7
a è etichettato come DT, un determinante.

7
ttps: //en.wikipedia.org/wiki/Determiner .

bello e cattivo sono etichettati come JJ, un aggettivo.

Domani è etichettato come NNP, un nome singolare proprio.

like è etichettato come IN - una congiunzione o preposizione subordinata.

11.2.4 Estrazione di frasi sostantive

hC
io

Supponiamo che ti stia preparando ad acquistare uno sci nautico, quindi lo stai cercando online.tu Pagina 465
potrebbe cercare "miglior sci nautico". In questo caso, "sci nautico" è una frase nominale. Se il file search
il motore non analizza correttamente la frase nominale, probabilmente non otterrai la ricerca migliore
risultati. Andare online e provare a cercare "migliore acqua", "miglior sci" e "miglior sci nautico" e vedere
cosa ottieni.

La proprietà noun_phrases di un TextBlob restituisce un oggetto WordList contenente un elenco di


Oggetti parola, uno per ogni frase nominale nel testo:

lecca qui per visualizzare l'immagine del codice


In [9]: blob
Out [9]: TextBlob ("Oggi è una bella giornata. Domani sembra brutto tempo."

n [10]: blob.noun_phrases
Out [10]: WordList (["bella giornata", "domani", "brutto tempo"])

Nota che una parola che rappresenta una frase nominale può contenere più parole. Una WordList è un file
estensione del tipo di elenco predefinito di Python. Gli elenchi di parole forniscono metodi aggiuntivi per
stemming, lemmatizing, singularizing and pluralizing.

11.2.5 Sentiment Analysis con il Sentiment Analyzer predefinito di TextBlob

Uno dei compiti di PNL più comuni e preziosi è l' analisi del sentiment , che determina
se il testo è positivo, neutro o negativo. Ad esempio, le aziende potrebbero usarlo per
determinare se le persone parlano online in modo positivo o negativo dei loro prodotti.
Considera la parola positiva "buono" e la parola negativa "cattivo".Solo perché una frase
contiene "buono" o "cattivo" non significa che il sentimento della frase sia necessariamente positivo o
negativo. Ad esempio, la frase

Il cibo non è buono.

ha chiaramente un sentimento negativo. Allo stesso modo, la frase

Il film non era male.

ha chiaramente un sentimento positivo, anche se forse non così positivo come qualcosa di simile

Il film è stato eccellente!

L'analisi del sentiment è un problema complesso di machine learning. Tuttavia, librerie come TextBlob
dispongono di modelli di machine learning pre-addestrati per eseguire l'analisi del sentiment.

Ottenere il sentimento di un TextBlob


La proprietà sentiment di un TextBlob restituisce un oggetto Sentiment che indica se il
il testo è positivo o negativo e se è oggettivo o soggettivo:

lecca qui per visualizzare l'immagine del codice

n [11]: blob
Out [11]: TextBlob ("Oggi è una bella giornata. Domani sembra brutto tempo.")

C
io

Pagina 466
In [12]: blob.sentiment
Out [12]: Sentiment (polarità = 0,07500000000000007,
soggettività = 0,8333333333333333)

Nell'output precedente, la polarità indica il sentiment con un valore da 1.0


(negativo) a 1,0 (positivo) con 0,0 neutro. La soggettività è un valore compreso tra 0,0
(oggettivo) a 1.0 (soggettivo). In base ai valori per il nostro TextBlob, il sentiment generale è
vicino al neutro e il testo è per lo più soggettivo.

Ottenere la polarità e la soggettività dall'oggetto Sentiment

I valori visualizzati sopra probabilmente forniscono una maggiore precisione di cui hai bisogno nella maggior parte dei casi.
Ciò può ridurre la leggibilità dell'output numerico. La precisione magica % di IPython consente
di specificare la precisione predefinita per gli oggetti float standalone e gli oggetti float in built
in tipi come elenchi, dizionari e tuple. Usiamo la magia per arrotondare la polarità e

valori di soggettività a tre cifre a destra del punto decimale:

lecca qui per visualizzare l'immagine del codice

In [13]:% precisione 3
Uscita [13]: "% .3f"

In [14]: blob.sentiment.polarity
Uscita [14]: 0,075

In [15]: blob.sentiment.subjectivity
Uscita [15]: 0,833
Ottenere il sentimento di una frase

Puoi anche ottenere il sentimento a livello di singola frase. Usiamo la frase

proprietà per ottenere un elenco di frasi oggetti, quindi iterarli e visualizzarli

Proprietà sentiment della frase:

ttp: //textblob.readthedocs.io/en/latest/api_reference.html#textblob.blob.Sen ence

lecca qui per visualizzare l'immagine del codice

In [16]: per la frase in blob.sentences:


...: print (frase.sentimento)
...:
Sentimento (polarità = 0,85, soggettività = 1,0)
Sentiment (polarità = 0.6999999999999998, soggettività = 0.6666666666666666)

Questo potrebbe spiegare perché l'intero sentimento di TextBlob è vicino a 0,0 (neutro): uno
la frase è positiva (0,85) e l'altra negativa (0,6999999999999998).

11.2.6 Analisi del sentiment con NaiveBayesAnalyzer

Per impostazione predefinita, un TextBlob e le frasi e le parole che ottieni determinano il sentiment

io
C
8th

utilizzando un PatternAnalyzer, che utilizza le stesse tecniche di analisi del sentiment del Pagina 467
9
Libreria di pattern. La libreria TextBlob include anche un NaiveBayesAnalyzer (modulo

textblob.sentiments ), che è stato formato su un database di recensioni di film. Ingenuo


0
Bayes è un algoritmo di classificazione del testo di apprendimento automatico comunemente utilizzato. Il seguente
utilizza l'argomento della parola chiave analyzer per specificare un analizzatore di sentimenti di TextBlob.Richiamare
da prima in questa sessione IPython in corso quel testo contiene 'Today is a beautiful

giorno. Domani sembra brutto tempo. ':

ttps: //textblob.readthedocs.io/en/latest/api_reference.html#module
extblob.en.sentiments .

0
ttps: //en.wikipedia.org/wiki/Naive_Bayes_classifier .

lecca qui per visualizzare l'immagine del codice

In [17]: from textblob.sentiments import NaiveBayesAnalyzer

In [18]: blob = TextBlob (text, analyzer = NaiveBayesAnalyzer ())

In [19]: blob
Out [19]: TextBlob ("Oggi è una bella giornata. Domani sembra brutto tempo.)

et usa la proprietà sentiment di TextBlob per visualizzare il sentiment del testo usando il

NaiveBayesAnalyzer:

lecca qui per visualizzare l'immagine del codice

In [20]: blob.sentiment
Out [20]: Sentiment (classification = 'neg', p_pos = 0.47662917962091056, p_neg = 0.5 33708203

In questo caso, il sentiment complessivo è classificato come negativo (classificazione = 'neg').Il


P_pos dell'oggetto Sentiment indica che TextBlob è positivo al 47,66% e il relativo p_neg
indica che TextBlob è negativo al 52,34%. Dal momento che il sentimento generale è solo leggermente
più negativo, probabilmente considereremmo il sentimento di TextBlob come nel complesso neutro.

Ora, otteniamo il sentimento di ogni frase:

lecca qui per visualizzare l'immagine del codice

In [21]: per la frase in blob.sentences:


...: print (frase.sentimento)
...:
Sentiment (classificazione = 'pos', p_pos = 0,8117563121751951, p_neg = 0,18824368782 80477)
entiment (classificazione = 'neg', p_pos = 0,174363226578349, p_neg = 0,825636773421 521)
otice che piuttosto che polarità e soggettività, i Sentiment oggetti da cui otteniamo
NaiveBayesAnalyzer contiene una classificazione : "pos" (positivo) o "neg" (negativo) -
e p_pos (percentuale positiva) e p_neg (percentuale negativa) valori compresi tra 0,0 e 1,0.

io
L
N
th1SC
Ancora una volta, vediamo che la prima frase è positiva e la seconda è negativa. Pagina 468

11.2.7 Rilevamento e traduzione della lingua

La traduzione interlinguistica è un problema impegnativo nell'elaborazione del linguaggio naturale e


intelligenza artificiale. Con i progressi nell'apprendimento automatico, nell'intelligenza artificiale e nel naturale
elaborazione della lingua, servizi come Google Translate (oltre 100 lingue) e Microsoft Bing
Il traduttore (oltre 60 lingue) può tradurre istantaneamente tra le lingue.

La traduzione interlingua è ottima anche per le persone che viaggiano in paesi stranieri.Possono usare
app di traduzione per tradurre menu, segnali stradali e altro. Ci sono anche sforzi per vivere
traduzione vocale in modo da poter conversare in tempo reale con persone che non conoscono
1, 2
il tuo linguaggio naturale. Alcuni smartphone possono ora funzionare insieme all'orecchio
3 4 5
cuffie per fornire una traduzione dal vivo di molte lingue . ,, Nel "IBM Watson
e Cognitive Computing ”, sviluppiamo uno script che fa quasi l'interazione in tempo reale
traduzione linguistica tra le lingue supportate da Watson.

1
ttps: //www.skype.com/en/features/skypetranslator/ .

2
ttps: //www.microsoft.com/enus/translator/business/live/ .

3
ttps: //www.telegraph.co.uk/technology/2017/10/04/googlesnew
eadphonescantranslateforeignlanguagesreal / .

4
TTP:? hl = //store.google.com/us/product/google_pixel_buds enUS .

5
ttp: //www.chicagotribune.com/bluesky/originals/ctbsigoogle
ixelbudsreview20171115story.html .

La libreria TextBlob utilizza Google Translate per rilevare la lingua di un testo e tradurlo
6
TextBlobs, Sentences e Words in altre lingue. Usiamo detect_language
metodo per rilevare la lingua del testo che stiamo manipolando ('en' è l'inglese):

6
Queste funzionalità richiedono una connessione Internet.

lecca qui per visualizzare l'immagine del codice

In [22]: blob
Out [22]: TextBlob ("Oggi è una bella giornata. Domani sembra brutto tempo.)

n [23]: blob.detect_language ()
Out [23]: "en"

Successivamente, utilizziamo il metodo di traduzione per tradurre il testo in spagnolo ("es") e quindi rilevare
la lingua sul risultato. L'argomento della parola chiave to specifica la lingua di destinazione.

lecca qui per visualizzare l'immagine del codice

In [24]: spagnolo = blob.translate (a = 'es' )

In [25]: spagnolo
Out [25]: TextBlob ("Hoy es un hermoso dia. Mañana parece mal tiempo.")

1C
phio
Pagina 469
In [26]: spanish.detect_language ()
Out [26]: "es"

Successivamente, traduciamo il nostro TextBlob in cinese semplificato (specificato come 'zh' o 'zhCN')
quindi rileva la lingua sul risultato:

lecca qui per visualizzare l'immagine del codice

In [27]: cinese = blob.translate (a = 'zh' )


In [28]: cinese
Uscita [28]: TextBlob ("")

In [29]: chinese.detect_language ()
Uscita [29]: "zhCN"

L'output del metodo detect_language mostra sempre il cinese semplificato come "zhCN", anche
sebbene la funzione di traduzione possa ricevere il cinese semplificato come "zh" o "zhCN".

In ciascuno dei casi precedenti, Google Translate rileva automaticamente la lingua di origine.
È possibile specificare esplicitamente una lingua di origine passando l'argomento della parola chiave from_lang a

il metodo di traduzione, come in

lecca qui per visualizzare l'immagine del codice

cinese = blob.translate (from_lang = 'en' , to = 'zh' )

7
Google Translate usi iso6391 codici linguistici elencati

7
SO è l'Organizzazione internazionale per la standardizzazione ( ttps: //www.iso.org/ ).

ttps: //en.wikipedia.org/wiki/List_of_ISO_6391_codes

Per le lingue supportate, useresti questi codici come valori di from_lang e to


argomenti delle parole chiave. L'elenco delle lingue supportate da Google Translate si trova su:

ttps: //cloud.google.com/translate/docs/languages

La chiamata di traduzione senza argomenti traduce dalla lingua di origine rilevata a


Inglese:

lecca qui per visualizzare l'immagine del codice

In [30]: spanish.translate ()
Out [30]: TextBlob ("Oggi è una bella giornata. Domani sembra brutto tempo.)

n [31]: chinese.translate ()
Out [31]: TextBlob ("Oggi è una bella giornata. Domani sembra brutto tempo.)

ota la leggera differenza nei risultati in inglese.

11hio
C
N
io
1.2.8 Flessione: pluralizzazione e singolarizzazione

11.2.8 Flessione: pluralizzazione e singolarizzazione Pagina 470

Le flessioni sono forme diverse delle stesse parole, come singolare e plurale (come "persona"
e "persone") e diversi tempi verbali (come "corri" e "corre"). Quando stai calcolando la parola
frequenze, potresti prima voler convertire tutte le parole flesse nella stessa forma per altre
frequenze di parole accurate. Parole ed Elenchi di parole supportano ciascuno la conversione delle parole nel proprio
forme singolari o plurali. Pluralizziamo e singolarizziamo un paio di oggetti Word:

lecca qui per visualizzare l'immagine del codice

In [1]: da textblob importa Word

In [2]: index = Word ( "index" )

In [3]: index.pluralize ()
Out [3]: "indici"

In [4]: ​cacti = Word ( 'cacti' )

In [5]: cacti.singularize ()
Uscita [5]: "cactus"

Pluralizzare e singolarizzare sono compiti sofisticati che, come puoi vedere sopra, non lo sono
semplice come aggiungere o rimuovere una "s" o una "e" alla fine di una parola.

Puoi fare lo stesso con una WordList:

lecca qui per visualizzare l'immagine del codice

In [6]: da textblob importa TextBlob


In [7]: animali = TextBlob ( 'cane gatto pesce uccello' ) .words

In [8]: animals.pluralize ()
Out [8]: WordList (['dogs', 'cats', 'fish', 'birds'])

Si noti che la parola "pesce" è la stessa sia nella sua forma singolare che in quella plurale.

11.2.9 Controllo ortografico e correzione

Per le attività di elaborazione del linguaggio naturale, è importante che il testo sia privo di errori di ortografia.
Pacchetti software per scrivere e modificare testo, come Microsoft Word, Google Docs e altri
controlla automaticamente l'ortografia durante la digitazione e in genere viene visualizzata una linea rossa sotto
parole con errori di ortografia. Altri strumenti consentono di richiamare manualmente un correttore ortografico.

Puoi controllare l'ortografia di una parola con il suo metodo di controllo ortografico , che restituisce un elenco di tuple
contenente possibili ortografie corrette e un valore di confidenza.Supponiamo di voler digitare
la parola "loro", ma abbiamo sbagliato a scrivere "loro". I risultati del controllo ortografico mostrano due possibili
correzioni con la parola 'loro' che hanno il valore di confidenza più alto:

lecca qui per visualizzare l'immagine del codice

In [1]: da textblob importa Word

In [2]: word = Word ( 'theyr' )

C
Pagina 471
In [3]:% precision 2
Uscita [3]: "% .2f"

In [4]: ​word.spellcheck ()
Fuori [4]: ​[('loro', 0,57), ('loro', 0,43)]

Tieni presente che la parola con il valore di confidenza più elevato potrebbe non essere la parola corretta per
dato contesto.

TextBlobs, Sentences e Words hanno tutti un metodo corretto che puoi chiamare per correggere
ortografia. La chiamata corretta su una parola restituisce la parola correttamente digitata che ha il valore più alto
valore di confidenza (come restituito dal controllo ortografico):

lecca qui per visualizzare l'immagine del codice

In [5]: word.correct () # sceglie la parola con il valore di confidenza più alto


Fuori [5]: "loro"

La chiamata corretta su un TextBlob o una frase controlla l'ortografia di ogni parola. Per ciascuno
parola sbagliata, corretta la sostituisce con quella scritta correttamente che ha la più alta

valore di fiducia:

lecca qui per visualizzare l'immagine del codice

In [6]: da textblob importa Word

In [7]: phrase = TextBlob ( 'Ths sentense has missplled wrds.' )

In [8]: phrase.correct ()
Out [8]: TextBlob ("La frase contiene parole con errori di ortografia.")

11.2.10 Normalizzazione: stemming e lemmatizzazione

Lo stemming rimuove un prefisso o un suffisso da una parola lasciando solo una radice, che può o può
non essere una parola reale. La lemmatizzazione è simile, ma fattori nella parte del discorso della parola e
significato e risultati in una parola reale.

Lo stemming e la lemmatizzazione sono operazioni di normalizzazione , in cui prepari le parole


per l'analisi. Ad esempio, prima di calcolare le statistiche sulle parole in un corpo di testo, potresti
converte tutte le parole in minuscolo in modo che le parole in maiuscolo e minuscolo non vengano trattate
diversamente. A volte, potresti voler usare la radice di una parola per rappresentare i molti della parola
forme. Ad esempio, in una determinata applicazione, potresti voler trattare tutte le seguenti parole
come “programma”: programma, programmi, programmatore, programmazione e programmato (e
forse anche l'ortografia inglese britannico, come i programmi).

Parole ed elenchi di parole supportano ciascuno stemming e lemmatization tramite i metodi stem e
lemmatizzare . Usiamo entrambi su una parola:

lecca qui per visualizzare l'immagine del codice

In [1]: da textblob importa Word

C
Pagina 472
In [2]: word = Word ( "varietà" )

In [3]: word.stem ()
Uscita [3]: "varieti"

In [4]: ​word.lemmatize ()
Fuori [4]: ​"varietà"

11.2.11 Frequenze di parole

Diverse tecniche per rilevare la somiglianza tra i documenti si basano sulle frequenze delle parole. Come
vedrai qui, TextBlob conta automaticamente le frequenze delle parole.Per prima cosa, carichiamo l'ebook
per Romeo e Giulietta di Shakespeare in un TextBlob. Per fare ciò, useremo la classe Path
dal modulo pathlib della Python Standard Library :

lecca qui per visualizzare l'immagine del codice

In [1]: from pathlib import Path

In [2]: da textblob importa TextBlob

In [3]: blob = TextBlob (Path ( 'RomeoAndJuliet.txt' ) .read_text ())

8
Usa il file RomeoAndJuliet.txt che hai scaricato in precedenza. Qui assumiamo che tu

ha avviato la tua sessione IPython da quella cartella.Quando leggi un file con il read_text di Path
metodo , chiude il file immediatamente dopo aver finito di leggere il file.

8
Ogni ebook di Project Gutenberg include testo aggiuntivo, come le informazioni sulla licenza,
non fa parte dell'ebook stesso. Per questo esempio, abbiamo utilizzato un editor di testo per rimuovere quel testo
dalla nostra copia dell'ebook.

È possibile accedere alle frequenze delle parole tramite ildizionario word_counts di TextBlob .
Facciamo il conteggio di diverse parole nel gioco:

lecca qui per visualizzare l'immagine del codice

In [4]: ​blob.word_counts [ ' juliet ' ]


Uscita [4]: ​190

In [5]: blob.word_counts [ 'romeo' ]


Uscita [5]: 315

In [6]: blob.word_counts [ 'tu' ]


Uscita [6]: 278

Se hai già tokenizzato un TextBlob in un WordList, puoi contare parole specifiche in formato
l'elenco tramite il metodo di conteggio :

lecca qui per visualizzare l'immagine del codice

In [7]: blob.words.count ( 'joy' )


Uscita [7]: 14

In [8]: blob.noun_phrases.count ( 'lady capulet' )

1C

Uscita [8]: 46 Pagina 473

11.2.12 Ottenere definizioni, sinonimi e contrari da WordNet


9
WordNet è un database di parole creato dalla Princeton University. La libreria TextBlob utilizza
l'interfaccia WordNet della libreria NLTK, che consente di cercare definizioni di parole e ottenere
sinonimi e contrari. Per ulteriori informazioni, controlla l'interfaccia di NLTK WordNet
documentazione a:

9
ttps: //wordnet.princeton.edu/ .
ttps: //www.nltk.org/api/nltk.corpus.reader.html#modulenltk.corpus.reader.wordnet

Ottenere definizioni
Per prima cosa, creiamo una parola:

lecca qui per visualizzare l'immagine del codice

In [1]: da textblob importa Word

In [2]: felice = Parola ( "felice" )

La proprietà delle definizioni della classe Word restituisce un elenco di tutte le definizioni della parola nel file
Database WordNet:

lecca qui per visualizzare l'immagine del codice

In [3]: happy.definitions
Fuori [3]:
["godendo o mostrando o segnato da gioia o piacere",
'segnato dalla buona fortuna',
'desiderosamente disposto ad agire o ad essere utile',
'ben espresso e al punto']

Il database non contiene necessariamente tutte le definizioni del dizionario di una determinata parola.C'è
anche un metodo di definizione che ti consente di passare una parte del discorso come argomento in modo da poterlo fare
ottenere definizioni che corrispondono solo a quella parte del discorso.

Ottenere sinonimi

Puoi ottenere i synset di Word, ovvero i suoi set di sinonimi, tramite la proprietà synsets .
Il risultato è un elenco di oggetti Synset:

In [4]: ​happy.synsets
Fuori [4]:
[Synset ('happy.a.01'),
Synset ('felicitous.s.02'),
Synset ('glad.s.02'),
Synset ('happy.s.04')]

Ogni Synset rappresenta un gruppo di sinonimi. Nella notazione happy.a.01:

h
1C

happy è la forma lemmatizzata di Word originale (in questo caso è la stessa).


Pagina 474

a è la parte del discorso, che può essere a per aggettivo, n per sostantivo, v per verbo, r per avverbio o
s per l'aggettivo satellite. Molti synset aggettivi in ​WordNet hanno synset satellite che
rappresentano aggettivi simili.

01 è un numero di indice basato su 0. Molte parole hanno molteplici significati e questo è l'indice
numero del significato corrispondente nel database di WordNet.

C'è anche un metodo get_synsets che ti consente di passare una parte del discorso come file
argomento in modo da poter ottenere Synset che corrispondono solo a quella parte del discorso.

Puoi scorrere l'elenco dei synset per trovare i sinonimi della parola originale.Ogni Synset
ha un metodo lemmi che restituisce un elenco di oggetti Lemma che rappresentano i sinonimi. UN

Il metodo del nome di Lemma restituisce la parola sinonimo come stringa.Nel codice seguente, per
ogni Synset nell'elenco dei Synset, il ciclo for annidato scorre attraverso quel Synset

Lemma (se presente). Quindi aggiungiamo il sinonimo all'insieme denominato sinonimi. Abbiamo usato un set
raccolta perché elimina automaticamente tutti i duplicati che aggiungiamo ad essa:

lecca qui per visualizzare l'immagine del codice

In [5]: sinonimi = set ()

In [6]: per synset in happy.synsets:


...: per il lemma in synset.lemmas ():
...: sinonimis.add (lemma.name ())
...:
In [7]: sinonimi
Out [7]: {'felicitous', 'glad', 'happy', 'wellchosen'}

Ottenere contrari

Se la parola rappresentata da un Lemma ha contrari nel database di WordNet, invocando il

Il metodo dei contrari di Lemma restituisce un elenco di Lemma che rappresentano i contrari (o un file
list se non ci sono contrari nel database). Nello snippet [4] hai visto che c'erano quattro

Synset per "felice". Per prima cosa, otteniamo i Lemma per il Synset all'indice 0 dei synset
elenco:

lecca qui per visualizzare l'immagine del codice

In [8]: lemmas = happy.synsets [ 0 ] .lemmas ()

In [9]: lemmi
Uscita [9]: [Lemma ('happy.a.01.happy')]

In questo caso, i lemmi hanno restituito un elenco di un elemento Lemma. Ora possiamo verificare se il file
database ha gli antonimi corrispondenti per quel Lemma:

lecca qui per visualizzare l'immagine del codice

In [10]: lemmi [ 0 ] .antonimi ()

C
Fine [10]: [Lemma ('unhappy.a.01.unhappy')] Pagina 475

Il risultato è un elenco di Lemma che rappresentano gli antonimi. Qui, vediamo che l'unico contrario
per "felice" nel database è "infelice".

11.2.13 Eliminazione di parole di arresto


Le parole di arresto sono parole comuni nel testo che vengono spesso rimosse dal testo prima di analizzarlo
perché in genere non forniscono informazioni utili. La tabella seguente mostra gli NLTK
elenco di parole non significative in inglese, che viene restituito dalle parole del modulo parole non significative NLTK
0
funzione (che useremo momentaneamente):

0
ttps: //www.nltk.org/book/ch02.html .

Elenco delle parole chiave in inglese di NLTK

['a', 'about', 'above', 'after', 'again', 'against', 'ain',


'all', 'am', 'an', 'and', 'any', 'are', 'aren', "n't ",
"as", "at", "be", "because", "been", "before", "being",
'below', 'between', 'both', 'but', 'by', 'can', 'couldn',
"Could", 'd', 'did', 'didn', "did", 'do', 'do',
'non', "non", "facendo", "don", "non", 'giù', 'durante',
'each', 'pochi', 'for', 'from', 'further', 'had', 'hadn',
"Hadn't", 'has', 'hasn', "hasn't", 'have', 'haven', "have",
'avendo', 'lui', 'lei', 'qui', 'lei', 'se stessa', 'lui',
"se stesso", "suo", "come", "i", "se", "in", "in", "è", "non è",
"Non è", 'esso', "è", 'suo', 'se stesso', 'solo', 'll', 'm',
'ma', 'me', 'mightn', "could not", 'more', 'most', 'mustn',
"Non devo", "mio", "me stesso", "non ho bisogno", "non devo", "no", "né",
'not', 'now', 'o', 'of', 'off', 'on', 'once', 'only', 'or',
'altro', 'nostro', 'nostro', 'noi stessi', 'fuori', 'oltre', 'proprio',
're', 's', 'same', 'shan', "shan't", 'she', "she's", 'should',
"Avrei dovuto", "non avrei dovuto", "non avrei dovuto", "così", "un po '", "tale",
't', 'than', 'that', "that'll", 'the', 'their', 'theirs',
'loro', 'se stessi', 'poi', 'là', 'questi', 'loro',
'questo', 'quelli', 'attraverso', 'a', 'anche', 'sotto', 'fino a',
'su', 've', 'molto', 'era', 'non era', “non era”, 'noi', 'eravamo',
"non erano", "non erano", 'cosa', 'quando', 'dove', 'quale', 'mentre',
'who', 'who', 'why', 'will', 'with', 'won', "won't",
"non vorrei", "non", "tu", "tu", "tu", "tu", "tu",
"Tu", "tuo", "tuo", "te stesso", "voi stessi"]
La libreria NLTK ha elenchi di parole chiave anche per molti altri linguaggi naturali.Prima
utilizzando gli elenchi di parole non significative di NLTK, è necessario scaricarli, cosa che fai con nltk

h2
funzione di download del modulo : Pagina 476

lecca qui per visualizzare l'immagine del codice

In [1]: import nltk

In [2]: nltk.download ( 'stopwords' )


[nltk_data] Download delle stopwords del pacchetto in
[nltk_data] C: \ Users \ PaulDeitel \ AppData \ Roaming \ nltk_data ...
[nltk_data] Decomprimere corpora \ stopwords.zip.
Out [2]: vero

Per questo esempio, caricheremo l'elenco di parole non significative "inglese". Prima importa le stopword da
il modulo nltk.corpus, quindi utilizzare le parole del metodo stopwords per caricare l'inglese
elenco di parole chiave:

lecca qui per visualizzare l'immagine del codice

In [3]: da nltk.corpus importare parole non significative

In [4]: ​stops = stopwords.words ( "inglese" )

Successivamente, creiamo un TextBlob da cui rimuoveremo le parole di arresto:

lecca qui per visualizzare l'immagine del codice

In [5]: da textblob importa TextBlob


In [6]: blob = TextBlob ( "Today is a beautiful day." )

Infine, per rimuovere le parole di arresto, usiamo le parole di TextBlob in una comprensione di lista
che aggiunge ogni parola all'elenco risultante solo se la parola non è in stop:

lecca qui per visualizzare l'immagine del codice

In [7]: [parola per parola in blob.words se parola non in stop]


Out [7]: ["Today", "beautiful", "day"]

11.2.14 n-grammi
1
Un ngram è una sequenza di n elementi di testo, come lettere in parole o parole in una frase.Nel
elaborazione del linguaggio naturale, n grammi possono essere utilizzati per identificare lettere o parole che frequentemente
appaiono adiacenti l'uno all'altro. Per l'input dell'utente basato sul testo, questo può aiutare a prevedere il prossimo
lettera o parola che un utente digiterà, ad esempio quando completa gli elementi in IPython con tab
completamento o quando si immette un messaggio per un amico nella messaggistica dello smartphone preferita
app. Per speechtotext, n grammi potrebbero essere utilizzati per migliorare la qualità della trascrizione.
Gli ngram sono una forma di ricorrenza in cui le parole o le lettere appaiono l'una accanto all'altra in a
corpo del testo.

1
TTP: //en.wikipedia.org/wiki/Ngram .

Il metodo ngram di TextBlob produce un elenco di WordList n grammi di lunghezza tre per

C
2h

predefinito, noto come trigrammi . È possibile passare l'argomento della parola chiave n per produrre n grammi di Pagina 477
qualsiasi lunghezza desiderata. L'output mostra che il primo trigramma contiene le prime tre parole in
la frase ("Oggi", "è" e "a"). Quindi, ngrams crea un trigramma che inizia con
seconda parola ("è", "a" e "bello") e così via fino a creare un trigramma contenente
le ultime tre parole nel TextBlob:

lecca qui per visualizzare l'immagine del codice

In [1]: da textblob importa TextBlob


In [2]: text = 'Oggi è una bella giornata. Domani sembra brutto tempo.

In [3]: blob = TextBlob (text)

In [4]: ​blob.ngrams ()
Fuori [4]:
[WordList (['Today', 'is', 'a']),
WordList (['is', 'a', 'beautiful']),
WordList (['a', 'beautiful', 'day']),
WordList (['beautiful', 'day', 'Tomorrow']),
Elenco di parole (["giorno", "domani", "aspetto"]),
Elenco di parole (["Domani", "aspetto", "mi piace"]),
WordList (['sembra', 'mi piace', 'cattivo']),
Elenco di parole (["mi piace", "cattivo", "tempo"])]

Quanto segue produce n grammi composti da cinque parole:

lecca qui per visualizzare l'immagine del codice

In [5]: blob.ngrams (n = 5 )
Fuori [5]:
[WordList (['Today', 'is', 'a', 'beautiful', 'day']),
WordList (['is', 'a', 'beautiful', 'day', 'Tomorrow']),
WordList (['a', 'beautiful', 'day', 'Tomorrow', 'looks']),
WordList (['beautiful', 'day', 'Tomorrow', 'looks', 'like']),
Elenco di parole (["giorno", "domani", "aspetto", "mi piace", "cattivo"]),
Elenco di parole (["Domani", "aspetto", "mi piace", "cattivo", "tempo"])]

11.3 VISUALIZZAZIONE DELLE FREQUENZE DELLE PAROLE CON GRAFICI A BARRE


E NUVOLE DI PAROLE
In precedenza, abbiamo ottenuto frequenze per alcune parole in Romeo e Giulietta . A volte frequenza
le visualizzazioni migliorano le analisi del tuo corpus. Spesso c'è più di un modo per visualizzare
dati e talvolta uno è superiore agli altri. Ad esempio, potresti essere interessato alla parola
frequenze relative l'una all'altra, oppure potresti essere interessato solo agli usi relativi delle parole in
un corpus. In questa sezione vedremo due modi per visualizzare le frequenze delle parole:

Un grafico a barre che visualizza quantitativamente le prime 20 parole di Romeo e Giulietta come barre
che rappresenta ogni parola e la sua frequenza.

Una nuvola di parole che visualizza qualitativamente le parole che ricorrono più frequentemente in dimensioni maggiori
caratteri e parole che ricorrono meno frequentemente in caratteri più piccoli.

11.3.1 Visualizzazione delle frequenze delle parole con i Panda

C
Visualizziamo le prime 20 parole di Romeo e Giulietta che non sono parole ferme. Per fare questo, useremo Pagina 478
caratteristiche da TextBlob, NLTK e panda. Le capacità di visualizzazione di Panda si basano su
Matplotlib, quindi avvia IPython con il seguente comando per questa sessione:

ipython matplotlib

Caricamento dei dati

Per prima cosa, carichiamo Romeo e Giulietta . Avvia prima IPython dalla cartella degli esempi ch11
eseguendo il seguente codice in modo da poter accedere al file ebook RomeoAndJuliet.txt che
hai scaricato in precedenza nel capitolo:

lecca qui per visualizzare l'immagine del codice

In [1]: from pathlib import Path

In [2]: da textblob importa TextBlob

In [3]: blob = TextBlob (Path ( 'RomeoAndJuliet.txt' ) .read_text ())

Quindi, carica le stopword NLTK:

lecca qui per visualizzare l'immagine del codice

In [4]: da nltk.corpus importare parole non significative

In [5]: stop_words = stopwords.words ( "inglese" )


Ottenere le frequenze delle parole
Per visualizzare le prime 20 parole, abbiamo bisogno di ciascuna parola e della sua frequenza.Chiamiamo il file
blob.word_counts il metodo degli elementi del dizionario per ottenere un elenco di tuple di frequenza di parole:

lecca qui per visualizzare l'immagine del codice

In [6]: items = blob.word_counts.items ()

Eliminare le parole d'arresto


Successivamente, utilizziamo una comprensione dell'elenco per eliminare tutte le tuple contenenti parole non significative:

lecca qui per visualizzare l'immagine del codice

In [7]: items = [item for item in items if item [ 0 ] not in stop_words]

L'espressione item [0] ottiene la parola da ogni tupla così possiamo controllare se è dentro

stop_words.

Ordinamento delle parole per frequenza


Per determinare le prime 20 parole, ordiniamo le tuple in elementi in ordine decrescente per

C
frequenza. Possiamo usare la funzione incorporata ordinata con un argomento chiave per ordinare le tuple Pagina 479
l'elemento frequency in ogni tupla. Per specificare l'elemento tupla in base a cui ordinare, utilizzare il
funzione itemgetter dal modulo operatore della Python Standard Library :

lecca qui per visualizzare l'immagine del codice

In [8]: da operatore import itemgetter

In [9]: oggetti_ordinati = ordinati (elementi, chiave = raccoglitore di oggetti ( 1 ), inverso = vero )

Poiché gli elementi degli elementi di ordinamento ordinato, accede all'elemento all'indice 1 in ogni tupla tramite
itemgetter espressione (1). L'argomento della parola chiave reverse = True indica che il
le tuple dovrebbero essere ordinate in ordine decrescente .

Ottenere le prime 20 parole

Successivamente, utilizziamo una sezione per ottenere le prime 20 parole da Sort_items.Quando TextBlob
tokenizza un corpus, divide tutte le contrazioni ai loro apostrofi e conta il numero totale
di apostrofi come una delle "parole". Romeo e Giulietta hanno molte contrazioni. Se visualizzi
oggetti_ordinati [0], vedrai che sono la "parola" che ricorre più di frequente con 867
2
di loro. Vogliamo visualizzare solo parole, quindi ignoriamo l'elemento 0 e otteniamo una porzione contenente
elementi da 1 a 20 di Sort_items:

2
In alcuni locali questo non accade e l'elemento 0 è effettivamente "romeo".

lecca qui per visualizzare l'immagine del codice

In [10]: top20 =oggetti_ordinati [ 1 : 21 ]

Converti top20 in un DataFrame

Quindi, convertiamo l'elenco di tuple top20 in un DataFrame di panda in modo da poterlo visualizzare
convenientemente:

lecca qui per visualizzare l'immagine del codice

In [11]: importa i panda come pd

In [12]: df = pd.DataFrame (top20, colonne = [ 'word' , 'count' ])

In [13]: df
Fuori [13]:
conteggio parole
0 romeo 315
1 tu 278
2 giulietta 190
3 il tuo 170
4 capuleti 163
5 infermiera 149
6 amore 148
7 te 138
8 signora 117
9 deve 110
10 frate 105
11 vieni 94

2C

12 mercutio 88 Pagina 480


13 Lorenzo 82
14 buono 80
15 benvolio 79
16 tybalt 79
17 immettere 75
18 vai 75
19 notte 73

Visualizzazione del DataFrame

Per visualizzare i dati, useremo il metodo bar della proprietà plot del DataFrame . Il
argomenti indicano che i dati di colonna devono essere visualizzati lungo le x ed y assi, e
che non vogliamo visualizzare una legenda sul grafico:

lecca qui per visualizzare l'immagine del codice

In [14]: axes = df.plot.bar (x = 'word' , y = 'count' , legend = False )

Il metodo a barre crea e visualizza un grafico a barre Matplotlib.

Quando guardi il grafico a barre iniziale che appare, noterai che alcune delle parole lo sono
troncato. Per risolvere questo problema, usa la funzione gcf (ottieni la figura corrente) di Matplotlib per ottenere Matplotlib
figura che i panda hanno mostrato, quindi chiama il metodo tight_layout della figura. Questo comprime
il grafico a barre per garantire che tutti i suoi componenti si adattino:

lecca qui per visualizzare l'immagine del codice

In [15]: importa matplotlib.pyplot come plt


In [16]: plt.gcf (). Tight_layout ()

Il grafico finale è mostrato di seguito:

C
Pagina 481
11.3.2 Visualizzazione delle frequenze delle parole con le nuvole di parole

Successivamente, costruiremo una nuvola di parole che visualizzi le prime 200 parole in Romeo e Giulietta . Puoi
3
utilizzare la classe WordCloud del modulo wordcloud open source per generare nuvole di parole
con poche righe di codice. Per impostazione predefinita, wordcloud crea nuvole di parole rettangolari, ma come
vedrai che la libreria può creare nuvole di parole con forme arbitrarie.

3
ttps: //github.com/amueller/word_cloud .

Installazione del modulo wordcloud

Per installare wordcloud, apri il tuo Anaconda Prompt (Windows), Terminal (macOS / Linux) o
shell (Linux) e inserisci il comando:

conda installa c condaforge wordcloud

Gli utenti Windows potrebbero dover eseguire il prompt di Anaconda come amministratore per
privilegi di installazione del software. Per fare ciò, fai clic con il pulsante destro del mouse su Prompt di Anaconda nel menu di avvio e
seleziona Altro> Esegui come amministratore.

Caricamento del testo

Per prima cosa, carichiamo Romeo e Giulietta . Avvia prima IPython dalla cartella degli esempi ch11
eseguendo il seguente codice in modo da poter accedere al file ebook RomeoAndJuliet.txt tu
scaricato in precedenza:

lecca qui per visualizzare l'immagine del codice

In [1]: from pathlib import Path

C
2h

Pagina 482
In [2]: text = Path ( 'RomeoAndJuliet.txt' ) .read_text ()

Caricamento dell'immagine della maschera che specifica la forma della nuvola di parole
Per creare un word cloud di una determinata forma, puoi inizializzare un oggetto WordCloud con un'immagine
conosciuto come una maschera . WordCloud riempie di testo le aree non bianche dell'immagine maschera. Bene
usa una forma di cuore in questo esempio, fornito come mask_heart.png negli esempi ch11
cartella. Maschere più complesse richiedono più tempo per creare il word cloud.

Carichiamo l'immagine della maschera utilizzando la funzione imread dal modulo imageio that
viene fornito con Anaconda:

lecca qui per visualizzare l'immagine del codice

In [3]: import imageio

In [4]: ​mask_image = imageio.imread ( 'mask_heart.png' )

Questa funzione restituisce l'immagine come array NumPy, richiesto da WordCloud.

Configurazione dell'oggetto WordCloud


Quindi, creiamo e configuriamo l'oggetto WordCloud:

lecca qui per visualizzare l'immagine del codice

In [5]: da wordcloud importa WordCloud


In [6]: wordcloud = WordCloud (colormap = 'prism' , mask = mask_image,
...: background_color = 'bianco' )
...:

La larghezza e l'altezza predefinite di WordCloud in pixel sono 400x200, a meno che non specifichi larghezza e

argomenti della parola chiave di altezza o un'immagine maschera. Per un'immagine maschera, la dimensione di WordCloud è
dimensione dell'immagine. WordCloud utilizza Matplotlib sotto il cofano. WordCloud assegna colori casuali

da una mappa a colori. È possibile fornire l'argomento della parola chiave colormap e utilizzare uno di
Mappe di colori con nome di Matplotlib. Per un elenco dei nomi delle mappe dei colori e dei loro colori, vedere:

ttps: //matplotlib.org/examples/color/colormaps_reference.html

L'argomento della parola chiave mask specifica la mask_image che abbiamo caricato in precedenza.Per impostazione predefinita, il

la parola è disegnata su uno sfondo nero, ma l'abbiamo personalizzato con background_color


argomento della parola chiave specificando uno sfondo "bianco". Per un elenco completo di WordCloud

argomenti delle parole chiave, vedere

ttp: //amueller.github.io/word_cloud/generated/wordcloud.WordCloud.html

Generazione della nuvola di parole

Il metodo di generazione di WordCloud riceve il testo da utilizzare nel word cloud come argomento
e crea la nuvola di parole, che restituisce come oggetto WordCloud:

hC
lecca qui per visualizzare l'immagine del codice Pagina 483

In [7]: wordcloud = wordcloud.generate (testo)

Prima di creare il word cloud, genera prima rimuove le parole di stop dall'argomento di testo
utilizzando l'elenco di stopword integrato del modulo wordcloud. Quindi genera calcola la parola

frequenze per le restanti parole. Il metodo utilizza un massimo di 200 parole nella parola
cloud per impostazione predefinita, ma puoi personalizzarlo con l'argomento parola chiave max_words.

Salvataggio di Word Cloud come file immagine

Infine, utilizziamo il metodo to_file di WordCloud per salvare l'immagine della nuvola di parole nel file
file specificato:

lecca qui per visualizzare l'immagine del codice

In [8]: wordcloud = wordcloud.to_file ( 'RomeoAndJulietHeart.png' )

Ora puoi andare alla cartella degli esempi ch11 e fare doppio clic su RomeoAndJuliet.png
file di immagine sul tuo sistema per visualizzarlo: la tua versione potrebbe avere le parole in posizioni diverse
e diversi colori:

Generazione di una nuvola di parole da un dizionario

Se hai già un dizionario di coppie chiave-valore che rappresentano i conteggi delle parole, puoi passarlo
al metodo fit_words di WordCloud . Questo metodo presuppone che tu abbia già rimosso il file

fermare le parole.

Visualizzazione dell'immagine con Matplotlib


Se desideri visualizzare l'immagine sullo schermo, puoi utilizzare la magia IPython

% matplotlib

per abilitare il supporto Matplotlib interattivo in IPython, quindi eseguire le seguenti istruzioni:

C
lecca qui per visualizzare l'immagine del codice Pagina 484

importa matplotlib.pyplot come plt


plt.imshow (wordcloud)

11.4 VALUTAZIONE DELLA LEGGIBILITÀ CON TEXTATISTIC


Un uso interessante dell'elaborazione del linguaggio naturale è la valutazione della leggibilità del testo , che è
influenzato dal vocabolario utilizzato, dalla struttura della frase, dalla lunghezza della frase, dall'argomento e altro.Mentre
scrivendo questo libro, abbiamo utilizzato lo strumento a pagamento Grammarly per ottimizzare la scrittura e garantire il
leggibilità del testo per un vasto pubblico.

4 5
In questa sezione, useremo la libreria Textatistic per valutare la leggibilità . Ci sono molti
formule utilizzate nell'elaborazione del linguaggio naturale per calcolare la leggibilità. Textatistic utilizza cinque
formule di leggibilità popolari: Flesch Reading Ease, FleschKincaid, Gunning Fog, Simple
Misura di Gobbledygook (SMOG) e DaleChall.

4
ttps: //github.com/erinhengel/Textatistic .

5
Alcune altre librerie di valutazione della leggibilità Python includono readabilityscore, textstat,
leggibilità e pilinguistica.

Installa Textatistic
Per installare Textatistic, apri il tuo Anaconda Prompt (Windows), Terminal (macOS / Linux) o
shell (Linux), quindi eseguire il seguente comando:

pip install textatistic

Gli utenti Windows potrebbero dover eseguire il prompt di Anaconda come amministratore per
privilegi di installazione del software. Per fare ciò, fai clic con il pulsante destro del mouse su Prompt di Anaconda nel menu di avvio e
seleziona Altro> Esegui come amministratore.

Calcolo delle statistiche e dei punteggi di leggibilità

Innanzitutto, carichiamo Romeo e Giulietta nella variabile di testo:

lecca qui per visualizzare l'immagine del codice

In [1]: from pathlib import Path

In [2]: text = Path ( 'RomeoAndJuliet.txt' ) .read_text ()

Il calcolo delle statistiche e dei punteggi di leggibilità richiede un oggetto Textatistic inizializzato
con il testo che vuoi valutare:

lecca qui per visualizzare l'immagine del codice

In [3]: from textatistic import Textatistic

In [4]: ​leggibilità = Textatistic (text)

C
2h

Il metodo testatistico dict restituisce un dizionario contenente varie statistiche e l' estensione Pagina 485
6
punteggi di leggibilità :

6
Ogni ebook di Project Gutenberg include testo aggiuntivo, come le informazioni sulla licenza,
non fa parte dell'ebook stesso. Per questo esempio, abbiamo utilizzato un editor di testo per rimuovere quel testo
dalla nostra copia dell'ebook.

lecca qui per visualizzare l'immagine del codice


In [5]:% precision 3
Uscita [5]: "% .3f"

In [6]: readability.dict ()
Fuori [6]:
{"char_count": 115141,
"word_count": 26120,
"conteggio_impianti": 3218,
"sybl_count": 30166,
"notdalechall_count": 5823,
"polysyblword_count": 549,
"flesch_score": 100.892,
"fleschkincaid_score": 1.203,
"gunningfog_score": 4.087,
"punteggio_mog": 5.489,
"dalechall_score": 7.559}

Ciascuno dei valori nel dizionario è accessibile anche tramite una proprietà Textatistic di
stesso nome dei tasti mostrati nell'output precedente. Le statistiche prodotte includono:

char_count: il numero di caratteri nel testo.

word_count: il numero di parole nel testo.

sent_count: il numero di frasi nel testo.

sybl_count: il numero di sillabe nel testo.

notdalechall_count: un conteggio delle parole che non sono nell'elenco DaleChall, che
7
è un elenco di parole comprese dall'80% degli alunni di 5a elementare. Più alto è questo numero
rispetto al numero totale di parole, meno leggibile è considerato il testo.

7
ttp: //www.readabilityformulas.com/articles/dalechall
eadabilitywordlist.php .

polysyblword_count: il numero di parole con tre o più sillabe.

flesch_score: il punteggio Flesch Reading Ease, che può essere mappato a un livello.
I punteggi superiori a 90 sono considerati leggibili dagli alunni di 5a elementare.I punteggi sotto i 30 richiedono un college
grado. Gli intervalli intermedi corrispondono agli altri livelli scolastici.

fleschkincaid_score: il punteggio FleschKincaid, che corrisponde a uno specifico


livello.

gunningfog_score: il valore dell'indice Gunning Fog, che corrisponde a uno specifico

hC
2r

livello. Pagina 486

smog_score — The Simple Measure of Gobbledygook (SMOG), che corrisponde al


anni di istruzione necessari per comprendere il testo. Questa misura è considerata particolarmente
8
efficace per i materiali sanitari.

8
ttps: //en.wikipedia.org/wiki/SMOG .

dalechall_score: il punteggio DaleChall, che può essere mappato a livelli di grado da 4


e inferiore al laureato (grado 16) e superiore. Questo punteggio è considerato il massimo
9, 0
affidabile per un'ampia gamma di tipi di testo.

9
ttps: //en.wikipedia.org/wiki/Readability#The_Dale%E2%80%93Chall_formula .

0
ttp: //www.readabilityformulas.com/articles/howdoidecide
hichreadabilityformulatouse.php .

Per maggiori dettagli su ciascuno dei punteggi di leggibilità prodotti qui e molti altri, vedere

ttps: //en.wikipedia.org/wiki/Readability

La documentazione Textatistic mostra anche le formule di leggibilità utilizzate:

ttp: //www.erinhengel.com/software/textatistic/

11.5 RICONOSCIMENTO DI ENTITÀ NOMINATE CON SPAZIO


La PNL può determinare di cosa tratta un testo. Un aspetto chiave di questo è chiamato riconoscimento dell'entità ,
che tenta di individuare e classificare elementi come date, orari, quantità, luoghi, persone,
cose, organizzazioni e altro ancora. In questa sezione, useremo il riconoscimento dell'entità denominata
1 2
capacità nella libreria spaCy NLP , per analizzare il testo.

1
ttps: //spacy.io/ .

2
Potresti anche voler controllare Textacy ( ttps: //github.com/chartbeat
abs / textacy ) una libreria NLP costruita su spaCy che supporta attività NLP aggiuntive.

Installa spaCy
Per installare spaCy, apri il tuo Anaconda Prompt (Windows), Terminal (macOS / Linux) o shell
(Linux), quindi eseguire il seguente comando:

lecca qui per visualizzare l'immagine del codice

conda install c condaforge spacy

Gli utenti Windows potrebbero dover eseguire il prompt di Anaconda come amministratore per
privilegi di installazione del software. Per fare ciò, fai clic con il pulsante destro del mouse su Prompt di Anaconda nel menu di avvio e
seleziona Altro> Esegui come amministratore.

Una volta completata l'installazione, devi anche eseguire il seguente comando, quindi spaCy può farlo

C
32lh
w
scarica i componenti aggiuntivi necessari per l'elaborazione del testo inglese (en): Pagina 487

lecca qui per visualizzare l'immagine del codice

python m spacy download it

Caricamento del modello linguistico


Il primo passo nell'utilizzo di spaCy è caricare il modello di linguaggio che rappresenta il linguaggio naturale
del testo che stai analizzando. Per fare ciò, chiamerai la funzione di caricamento del modulo spacy . Andiamo
carica il modello inglese che abbiamo scaricato sopra:

lecca qui per visualizzare l'immagine del codice

In [1]: import spacy

In [2]: nlp = spacy.load ( 'en' )

La documentazione di spaCy consiglia il nome della variabile nlp.

Creare uno spaCy Doc


3
Successivamente, si utilizza l'oggetto nlp per creare un oggetto spaCy Doc che rappresenta il documento a
processi. Qui abbiamo usato una frase dall'introduzione al World Wide Web in molti di
i nostri libri:

3
ttps: //spacy.io/api/doc .

lecca qui per visualizzare l'immagine del codice

In [3]: document = nlp ( 'Nel 1994, Tim BernersLee ha fondato il' +


...: "World Wide Web Consortium (W3C), dedicato a" +
...: "sviluppo di tecnologie web" )
...:

Recupero delle entità denominate


La proprietà ents dell'oggetto Doc restituisce una tupla di oggetti Span che rappresentano il nome
4
entità trovate nel Doc. Ogni span ha molte proprietà. Analizziamo gli Spans
e visualizzare il testo e le proprietà label_:

4
ttps: //spacy.io/api/span .

lecca qui per visualizzare l'immagine del codice


In [4]: per l' entità in document.ents:
...: print (f ' {entity.text} : {entity.label_} ' )
...:
1994: DATA
Tim Berners Lee: PERSON
il World Wide Web Consortium: ORG

hC
3

Ogni proprietà text di Span restituisce l'entità come una stringa e la proprietà label_ Pagina 488
restituisce una stringa che indica il tipo di entità. Qui spaCy ha trovato tre entità che rappresentano un file

DATE (1994), una PERSON (Tim BernersLee) e un'ORG (organizzazione; il World Wide
Consorzio Web). Per ulteriori informazioni su spaCy e per dare un'occhiata alla sua guida rapida,
vedere

ttps: //spacy.io/usage/models#sectionquickstart

11.6 RILEVAMENTO DELLA SIMILARITÀ CON SPACY


Il rilevamento della somiglianza è il processo di analisi dei documenti per determinare quanto siano simili
siamo. Una possibile tecnica di rilevamento della somiglianza è il conteggio della frequenza delle parole.Per esempio,
alcune persone credono che le opere di William Shakespeare potrebbero essere state effettivamente scritte
5
di Sir Francis Bacon, Christopher Marlowe o altri . Confrontando le frequenze delle parole di
le loro opere con quelle di Shakespeare possono rivelare somiglianze nello stile di scrittura.

5
ttps: //en.wikipedia.org/wiki/Shakespeare_authorship_question .

Per lo studio possono essere utilizzate varie tecniche di apprendimento automatico che discuteremo nei capitoli successivi
somiglianza del documento. Tuttavia, come spesso accade in Python, esistono librerie come
spaCy e Gensim che possono farlo per te. Qui, useremo il rilevamento della somiglianza di spaCy
caratteristiche per confrontare gli oggetti che rappresentano Doc di Shakespeare Romeo e Giulietta con
Edward the Second di Christopher Marlowe . Puoi scaricare Edward the Second da
6
Progetto Gutenberg come abbiamo fatto per Romeo e Giulietta all'inizio del capitolo.

6
Ogni ebook di Project Gutenberg include testo aggiuntivo, come le informazioni sulla licenza,
non fa parte dell'ebook stesso. Per questo esempio, abbiamo utilizzato un editor di testo per rimuovere quel testo
dalle nostre copie degli ebook.

Caricamento del modello linguistico e creazione di un documento spaCy


Come nella sezione precedente, carichiamo prima il modello inglese:

lecca qui per visualizzare l'immagine del codice

In [1]: import spacy

In [2]: nlp = spacy.load ( 'en' )

Creazione di spaCy Docs

Successivamente, creiamo due oggetti Doc, uno per Romeo e Giulietta e uno per Edoardo Secondo :

lecca qui per visualizzare l'immagine del codice

In [3]: from pathlib import Path

In [4]: ​document1 = nlp (Path ( 'RomeoAndJuliet.txt' ) .read_text ())

In [5]: document2 = nlp (Path ( 'EdwardTheSecond.txt' ) .read_text ())

paragonando la somiglianza dei libri


C
C
3h
h

Confrontando la somiglianza dei libri Pagina 489

Infine, utilizziamo il metodo di somiglianza della classe Doc per ottenere un valore da 0.0 (non simile) a
1.0 (identico) che indica quanto sono simili i documenti:

lecca qui per visualizzare l'immagine del codice

In [6]: document1.similarity (document2)


Uscita [6]: 0.9349950179100041
spaCy ritiene che questi due documenti abbiano somiglianze significative.A scopo di confronto,
abbiamo creato un Doc che rappresenta una notizia attuale e l'abbiamo confrontato con Romeo e Giulietta .
Come previsto, spaCy ha restituito un valore basso indicando poca somiglianza tra di loro.Provare
copiare un articolo di notizie corrente in un file di testo, quindi eseguire il confronto di somiglianza
te stesso.

11.7 ALTRE LIBRERIE E STRUMENTI DELLA PNL


Ti abbiamo mostrato varie librerie NLP, ma è sempre una buona idea indagare la gamma di
opzioni disponibili in modo da poter sfruttare i migliori strumenti per le tue attività. Di seguito sono riportati alcuni
librerie e API NLP per lo più gratuite e open source aggiuntive:

Gensim: rilevamento di similarità e modellazione di argomenti.

API Google Cloud Natural Language: API basata su cloud per attività NLP come named
riconoscimento di entità, analisi del sentiment, parti di analisi e visualizzazione del discorso,
determinazione delle categorie di contenuti e altro ancora.

API Microsoft Linguistic Analysis.

Analisi del sentiment di Bing: il motore di ricerca Bing di Microsoft ora utilizza il sentiment nella sua ricerca
risultati. Al momento della stesura di questo documento, l'analisi del sentiment nei risultati di ricerca è disponibile solo in
gli Stati Uniti.

PyTorch NLP: libreria di deep learning per la PNL.

Stanford CoreNLP: una libreria Java NLP, che fornisce anche un wrapper Python. Include
risoluzione corefererence, che trova tutti i riferimenti alla stessa cosa.

Apache OpenNLP: un'altra libreria NLP basata su Javab per attività comuni, tra cui
risoluzione della coreferenza. Sono disponibili wrapper Python.

PyNLPl (pineapple) —Libreria Python NLP, include NLP di base e più sofisticata
capacità.

SnowNLP: libreria Python che semplifica l'elaborazione del testo in cinese.

KoNLPy: NLP in lingua coreana.

stopwords: libreria Python con stop words per molte lingue. Abbiamo usato lo stop di NLTK
elenchi di parole in questo capitolo.

C
TextRazor: un'API NLP basata su cloud a pagamento che fornisce un livello gratuito. Pagina 490

11.8 APPRENDIMENTO MACCHINA E APPRENDIMENTO PROFONDO NATURALE


APPLICAZIONI IN LINGUA
Esistono molte applicazioni in linguaggio naturale che richiedono l'apprendimento automatico e approfondito
tecniche di apprendimento. Discuteremo alcuni dei seguenti nel nostro machine learning e approfondimenti
capitoli di apprendimento:

Rispondere a domande in linguaggio naturale: ad esempio, il nostro editore Pearson Education,


ha una partnership con IBM Watson che utilizza Watson come tutor virtuale. Gli studenti chiedono
Watson domande in linguaggio naturale e ottieni risposte.

Riassumere documenti: analizzare documenti e produrre brevi riassunti (anche


chiamati abstract) che possono, ad esempio, essere inclusi nei risultati di ricerca e possono aiutarti
decidere cosa leggere.

Sintesi vocale (speechtotext) e riconoscimento vocale (texttospeech): li usiamo


nel nostro capitolo "IBM Watson", insieme alla traduzione di testo e testo interlingua, a
sviluppare un traduttore vocale interlingua quasi in tempo reale.

Filtro collaborativo: utilizzato per implementare sistemi di raccomandazione ("se ti è piaciuto


film, potrebbe piacerti anche ").

Classificazione del testo: ad esempio, classificare gli articoli di notizie per categorie, come il mondo
notizie, notizie nazionali, notizie locali, sport, affari, intrattenimento, ecc.
Modellazione degli argomenti: ricerca degli argomenti discussi nei documenti.

Rilevamento del sarcasmo: spesso utilizzato con l'analisi del sentiment.

Semplificazione del testo: rendere il testo più conciso e più facile da leggere.

Discorso al linguaggio dei segni e viceversa, per consentire una conversazione con non udenti
persona.

Tecnologia di lettura delle labbra: per le persone che non possono parlare, converti il ​movimento delle labbra in testo o
discorso per abilitare la conversazione.

Sottotitoli: aggiunta di sottotitoli di testo al video.

11.9 SET DI DATI IN LINGUA NATURALE


C'è un numero enorme di fonti di dati di testo disponibili per lavorare con naturale
elaborazione della lingua:

Wikipedia: parte o tutta Wikipedia


( ttps: //meta.wikimedia.org/wiki/Datasets ).

IMDB (Internet Movie Database): sono disponibili vari set di dati di film e TV.

Set di dati di testo UCIs: molti set di dati, incluso il set di dati Spambase.

h
Progetto Gutenberg: oltre 50.000 ebook gratuiti non protetti da copyright negli Stati Uniti Pagina 491

Pericolo! set di dati: più di 200.000 domande da Jeopardy!Programma televisivo. Una pietra miliare nell'IA
si è verificato nel 2011, quando IBM Watson ha battuto due dei migliori Jeopardy!
Giocatori.

Set di dati per l'elaborazione del linguaggio naturale:


ttps: //machinelearningmastery.com/datasetsnaturallanguage
rocessing / .

Dati NLTK: ttps: //www.nltk.org/data.html .

Set di dati di frasi etichettate con sentiment (da fonti tra cui IMDB.com, amazon.com,
yelp.com.)

Registry of Open Data su AWS: una directory ricercabile di set di dati ospitati su Amazon
Servizi web ( ttps: //registry.opendata.aws ).

Set di dati delle recensioni dei clienti Amazon: oltre 130 milioni di recensioni di prodotti
( ttps: //registry.opendata.aws/amazonreviews/ ).

Pitt.edu corpora ( ttp: //mpqa.cs.pitt.edu/corpora/ ).

11.10 WRAP-UP
In questo capitolo, hai eseguito un'ampia gamma di attività di elaborazione del linguaggio naturale (PNL)
utilizzando diverse librerie NLP. Hai visto che la PNL viene eseguita su raccolte di testo note come
corpora. Abbiamo discusso le sfumature di significato che rendono la comprensione del linguaggio naturale
difficile.

Ci siamo concentrati sulla libreria TextBlob NLP, che è costruita sulle librerie NLTK e pattern,
ma più facile da usare. Hai creato TextBlobs e li hai tokenizzati in frasi e parole.
Hai determinato la parte del discorso per ogni parola in un TextBlob e hai estratto il nome
frasi.

Abbiamo dimostrato come valutare il sentiment positivo o negativo di TextBlobs e

Frasi con l'analizzatore di sentiment predefinito della libreria TextBlob e con


NaiveBayesAnalyzer. Hai utilizzato l'integrazione della libreria TextBlob con Google Translate
per rilevare la lingua del testo ed eseguire la traduzione interlingua.

Abbiamo mostrato vari altri compiti della PNL, tra cui singolarizzazione e pluralizzazione, incantesimo
controllo e correzione, normalizzazione con stemming e lemmatizzazione e acquisizione di notizie
frequenze. Hai ottenuto definizioni di parole, sinonimi e contrari da WordNet. tu
hai anche usato l'elenco di parole di arresto di NLTK per eliminare le parole di arresto dal testo e hai creato ngram
contenente gruppi di parole consecutive.

Abbiamo mostrato come visualizzare quantitativamente le frequenze delle parole come un grafico a barre usando i panda
capacità di plottaggio incorporate. Quindi, abbiamo utilizzato la libreria wordcloud per visualizzare la parola
frequenze qualitativamente come nuvole di parole. Hai eseguito valutazioni di leggibilità utilizzando il
Libreria testatistica. Infine, hai utilizzato spaCy per individuare entità denominate e per eseguire somiglianze
rilevamento tra documenti. Nel prossimo capitolo continuerai a usare il linguaggio naturale
mentre introduciamo i tweet di data mining utilizzando le API di Twitter.
ph
Pagina 492

Playlist

12. Twitter di data mining


storia

Obiettivi
opiche

In questo capitolo potrai:


guadagnando Pat

Comprendere l'impatto di Twitter su aziende, marchi, reputazione, analisi del sentiment,


ffers & Dea
previsioni e altro ancora.

ighlights
Usa Tweepy, uno dei client API Twitter Python più popolari per il data mining
Twitter.
ettings

Utilizza l'API di ricerca di Twitter per scaricare i tweet passati che soddisfano i tuoi criteri.
Supporto

Utilizza l'API di streaming di Twitter per provare il flusso di tweet in tempo reale mentre vengono trasmessi.
Disconnessione

Verifica che gli oggetti tweet restituiti da Twitter contengano informazioni preziose oltre al file
twittare il testo.

Usa le tecniche di elaborazione del linguaggio naturale dell'ultimo capitolo per pulire e
preelaborare i tweet per prepararli per l'analisi.

Esegui l'analisi del sentiment sui tweet.

Individua le tendenze con l'API Trends di Twitter.

Mappare i tweet utilizzando folium e OpenStreetMap.

Comprendi vari modi per archiviare i tweet utilizzando le tecniche discusse in questo documento
libro.

Contorno

2.1 Introduzione

2.2 Panoramica delle API di Twitter

1
Pagina 493
2.3 Creazione di un account Twitter

2.4 Ottenere le credenziali di Twitter: creare un'app

2.5 Cosa c'è in un Tweet?

2.6 Tweepy
2.7 Autenticazione con Twitter tramite Tweepy

2.8 Ottenere informazioni su un account Twitter

2.9 Introduzione a Tweepy Cursors: ottenere follower e amici di un account

2.9.1 Determinazione dei follower di un account

2.9.2 Determinazione di chi segue un account

2.9.3 Recupero dei tweet recenti di un utente

2.10 Ricerca di tweet recenti

2.11 Individuazione delle tendenze: API Twitter Trends

2.11.1 Luoghi con argomenti di tendenza

2.11.2 Ottenere un elenco di argomenti di tendenza

2.11.3 Creare una nuvola di parole da argomenti di tendenza

2.12 Pulizia / pre-elaborazione dei tweet per l'analisi

2.13 Twitter Streaming API

2.13.1 Creazione di una sottoclasse di StreamListener

2.13.2 Avvio dell'elaborazione del flusso

2.14 Analisi del sentiment dei Tweet

2.15 Geocodifica e mappatura

2.15.1 Ottenere e mappare i tweet

2.15.2 Funzioni di utilità in tweetutilities.py

1
Pagina 494
2.15.3 Class LocationListener

2.16 Modi per memorizzare i tweet

2.17 Twitter e Time Series

2.18 WrapUp

12.1 INTRODUZIONE
Cerchiamo sempre di predire il futuro. Pioverà durante il nostro prossimo picnic? Will il
mercato azionario o singoli titoli salgono o scendono, e quando e di quanto? Come
le persone voteranno alle prossime elezioni? Qual è la possibilità che una nuova impresa di esplorazione petrolifera
colpirà il petrolio e in caso affermativo quanto probabilmente produrrà? Vincerà di più una squadra di baseball
giochi se cambia la sua filosofia di battuta in "swing for the recences?" Quanto cliente
il traffico che una compagnia aerea prevede nei prossimi mesi? E quindi come dovrebbe il file
società acquista futures su materie prime petrolifere per garantire che avrà l'offerta di cui ha bisogno e
si spera a un costo minimo? Quale traccia è probabile che prenderà un uragano e quanto sarà potente
probabilmente diventerà (categoria 1, 2, 3, 4 o 5)? Questo tipo di informazioni è fondamentale per l'emergenza
sforzi di preparazione. È probabile che una transazione finanziaria sia fraudolenta? Sarà un mutuo
predefinito? È probabile che una malattia si diffonda rapidamente e, in caso affermativo, in quale area geografica?

La previsione è un processo impegnativo e spesso costoso, ma i potenziali vantaggi sono ottimi.


Con le tecnologie in questo e nei prossimi capitoli, vedremo come l'IA, spesso in
concerto con i big data, sta rapidamente migliorando le capacità di previsione.

In questo capitolo ci concentriamo sul data mining di Twitter, cercando il sentiment in


tweets. Il data mining è il processo di ricerca attraverso grandi raccolte di dati, spesso
big data, per trovare approfondimenti che possono essere preziosi per individui e organizzazioni. Il
l'opinione che i tuoi dati ricavati dai tweet potrebbero aiutare a prevedere i risultati di un'elezione, il
i ricavi generati da un nuovo film e il successo del marketing di un'azienda
campagna. Potrebbe anche aiutare le aziende a individuare i punti deboli nel prodotto della concorrenza
offerte.

Ti connetti a Twitter tramite servizi web. Utilizzerai l'API di ricerca di Twitter per accedere al file
enorme base di tweet passati. Utilizzerai l'API di streaming di Twitter per provare il flusso di
nuovi tweet non appena vengono pubblicati. Con l'API Twitter Trends, vedrai quali sono gli argomenti
trend. Troverai molto di ciò che abbiamo presentato nella sezione " Elaborazione del linguaggio naturale
Il capitolo NLP) ”sarà utile nella creazione di applicazioni Twitter.

Come hai visto in questo libro, grazie alle potenti librerie, ti esibirai spesso

1
(N
Pagina 495
compiti importanti con poche righe di codice. Questo è il motivo per cui Python e il suo robusto open
comunità di origine sono attraenti.

Twitter ha sostituito le principali testate giornalistiche come prima fonte di notizie degne di nota
eventi. La maggior parte dei post su Twitter sono pubblici e vengono pubblicati in tempo reale mentre gli eventi si svolgono a livello globale.
Le persone parlano francamente di qualsiasi argomento e twittano sulla loro vita personale e lavorativa.
Commentano le scene sociali, di intrattenimento e politiche e qualsiasi altra cosa venga
pensare. Con i loro telefoni cellulari, scattano e pubblicano foto e video di eventi mentre loro
accadere. Sentirai comunemente i termini Twitterverse e Twittersphere per indicare il file
centinaia di milioni di utenti che hanno a che fare con l'invio, la ricezione e
analizzare i tweet.

Cos'è Twitter?

Twitter è stata fondata nel 2006 come azienda di microblogging e oggi è una delle più importanti
siti popolari su Internet. Il suo concetto è semplice. Le persone scrivono brevi messaggi chiamati
tweets , inizialmente limitato a 140 caratteri, ma recentemente aumentato per la maggior parte delle lingue a 280
personaggi. In genere chiunque può scegliere di seguire chiunque altro. Questo è diverso dal
comunità chiuse e strette su altre piattaforme di social media come Facebook, LinkedIn
e molti altri, dove le “relazioni successive” devono essere reciproche.

Statistiche Twitter

Twitter ha centinaia di milioni di utenti e vengono inviati centinaia di milioni di tweet


1
ogni giorno con molte migliaia inviate al secondo. Ricerca in linea di "Internet
statistiche "e" statistiche Twitter "ti aiuteranno a mettere questi numeri in prospettiva. Alcuni
I "tweeter" hanno più di 100 milioni di follower. I tweeter dedicati generalmente pubblicano
diversi al giorno per mantenere i loro follower coinvolti. I tweeter con il maggior numero di follower sono
tipicamente intrattenitori e politici. Gli sviluppatori possono attingere al flusso live dei tweet come
stanno accadendo. Questo è stato paragonato a "bere da una manichetta antincendio", perché il
i tweet ti arrivano così velocemente.

1
ttp: //www.internetlivestats.com/twitterstatistics/ .

Twitter e Big Data

Twitter è diventata una fonte di big data preferita per ricercatori e uomini d'affari
In tutto il mondo. Twitter consente agli utenti regolari l'accesso gratuito a una piccola porzione di quelli più recenti
tweets. Attraverso accordi speciali con Twitter, alcune aziende di terze parti (e
Twitter stesso) offre l'accesso a pagamento a porzioni molto più grandi del database dei tweet di tutti i tempi.

Precauzioni

hS
Pagina 496
Non puoi sempre fidarti di tutto ciò che leggi su Internet ei tweet non fanno eccezione.
Ad esempio, le persone potrebbero utilizzare informazioni false per tentare di manipolare i mercati finanziari o
influenzare le elezioni politiche. Gli hedge fund negoziano spesso titoli in parte in base al tweet
flussi che seguono, ma sono cauti. Questa è una delle sfide della costruzione
businesscritical o mission-critical sistemi basati sui contenuti dei social media.

In futuro, utilizziamo ampiamente i servizi web. Le connessioni Internet possono essere perse, i servizi
possono cambiare e alcuni servizi non sono disponibili in tutti i paesi. Questo è il mondo reale di
programmazione basata su cloud. Non possiamo programmare con la stessa affidabilità delle app desktop
quando si utilizzano servizi web.

12.2 PANORAMICA DI TWITTER APIS


Le API di Twitter sono servizi Web basati su cloud, quindi è necessaria una connessione Internet
eseguire il codice in questo capitolo. I servizi Web sono metodi che chiami nel cloud, come
farai con le API di Twitter in questo capitolo, le API di IBM Watson nel prossimo capitolo
e altre API che utilizzerai man mano che l'elaborazione diventa più basata sul cloud. Ogni metodo API ha
un endpoint del servizio Web , che è rappresentato da un URL utilizzato per richiamare tale metodo
su internet.

Le API di Twitter includono molte categorie di funzionalità, alcune gratuite e altre a pagamento. Maggior parte
hanno limiti di velocità che limitano il numero di volte in cui è possibile utilizzarli in 15 minuti
intervalli. In questo capitolo, utilizzerai la libreria Tweepy per invocare metodi da
seguenti API di Twitter:

API di autenticazione: trasmetti a Twitter le tue credenziali (discusse tra poco)


puoi usare le altre API.

API Account e utenti: consente di accedere alle informazioni su un account.

API Tweets: cerca tra i tweet passati, accedi ai flussi di tweet per attingere ai tweet
sta accadendo ora e di più.

API Trends: trova posizioni di argomenti di tendenza e ottieni elenchi di argomenti di tendenza per
Posizione.

Consulta l'elenco completo delle categorie, delle sottocategorie e dei singoli metodi dell'API di Twitter su:

ttps: //developer.twitter.com/en/docs/apireferenceindex.html

Limiti di velocità: una parola di cautela

hY
Pagina 497
witter si aspetta che gli sviluppatori utilizzino i suoi servizi in modo responsabile. Ogni metodo API di Twitter ha un'estensione
limite di velocità , che è il numero massimo di richieste (cioè chiamate) che puoi effettuare
durante una finestra di 15 minuti. Twitter potrebbe impedirti di utilizzare le sue API se continui a farlo
chiamare un determinato metodo API dopo che il limite di velocità di quel metodo è stato raggiunto.

2
Prima di utilizzare qualsiasi metodo API, leggi la sua documentazione e comprendi i suoi limiti di velocità.
Configureremo Tweepy in modo che attenda quando incontra i limiti di velocità. Questo ti aiuta a prevenire
dal superamento dei limiti di ratifica. Alcuni metodi elencano sia i limiti di frequenza degli utenti che le app
limiti di velocità. Tutti gli esempi di questo capitolo utilizzano i limiti di velocità delle app . I limiti di frequenza utente riguardano le app
che consentono ai singoli utenti di accedere a Twitter, come le app di terze parti con cui interagiscono
Twitter per tuo conto, ad esempio app per smartphone di altri fornitori.

2
Tieni presente che Twitter potrebbe modificare questi limiti in futuro.

Per dettagli sulla limitazione della velocità, vedere

ttps: //developer.twitter.com/en/docs/basics/ratelimiting

Per limiti di velocità specifici sui singoli metodi API, vedere

ttps: //developer.twitter.com/en/docs/basics/ratelimits

e la documentazione di ogni metodo API.

Altre limitazioni

Twitter è una miniera d'oro per il data mining e ti permettono di fare molto con il loro gratuito
Servizi. Rimarrai stupito dalle preziose applicazioni che puoi creare e da come saranno
aiutarti a migliorare i tuoi impegni personali e professionali. Tuttavia, se non segui
Le regole e i regolamenti di Twitter, il tuo account sviluppatore potrebbe essere chiuso.
È necessario leggere attentamente quanto segue e i documenti a cui si collegano:

Termini di servizio: ttps: //twitter.com/tos

Contratto per gli sviluppatori: ttps: //developer.twitter.com/en/developer

erms / agreementandpolicy.html

Politica per gli sviluppatori:


ttps: //developer.twitter.com/en/developer
erms / policy.html

Altre limitazioni: ttps: //developer.twitter.com/en/developer


erms / moreonrestrictedusecases

hT
t
Pagina 498
Vedrai più avanti in questo capitolo che puoi cercare i tweet solo per gli ultimi sette giorni e
ricevi solo un numero limitato di tweet utilizzando le API Twitter gratuite. Alcuni libri e articoli
diciamo che puoi aggirare questi limiti raschiando i tweet direttamente da twitter.com.
Tuttavia, i Termini di servizio dicono esplicitamente che "raschiare i Servizi senza il
il previo consenso di Twitter è espressamente vietato. "

12.3 CREAZIONE DI UN ACCOUNT TWITTER


Twitter richiede di richiedere un account sviluppatore per poter utilizzare le sue API. Vai a

ttps: //developer.twitter.com/en/applyforaccess

e invia la tua domanda. Dovrai registrarti per uno come parte di questo processo se lo fai
non ne ho già uno. Ti verranno poste domande sullo scopo del tuo account. tu
deve leggere attentamente e accettare i termini di Twitter per completare l'applicazione, quindi
conferma il tuo indirizzo email.

Twitter esamina ogni applicazione. L'approvazione non è garantita. Al momento della stesura di questo articolo,
gli account per uso personale sono stati approvati immediatamente. Per gli account aziendali, il processo
stava impiegando da pochi giorni a diverse settimane, secondo i forum degli sviluppatori di Twitter.
12.4 OTTENERE LE CREDENZIALI DI TWITTER — CREAZIONE DI UN
APP
Una volta che hai un account sviluppatore Twitter, devi ottenere le credenziali per interagire
con le API di Twitter. Per farlo, creerai un'app . Ogni app ha credenziali separate.
Per creare un'app, accedi

ttps: //developer.twitter.com

ed eseguire i seguenti passaggi:

1. Nella parte superiore della pagina, fai clic sul menu a discesa del tuo account e seleziona
App.

2. Fare clic su Crea un'app.

3. Nel campo Nome app, specifica il nome della tua app. Se invii tweet tramite l'API, questo
il nome dell'app sarà il mittente del tweet. Inoltre verrà mostrato agli utenti se crei
applicazioni che richiedono che un utente acceda tramite Twitter. Non lo faremo neanche in questo
capitolo, quindi un nome come " YourName Test App" va bene per questo capitolo.

hY
Pagina 499
. Nel campo Descrizione applicazione, inserisci una descrizione per la tua app. quando
creando app basate su Twitter che verranno utilizzate da altre persone, questo descriverebbe
cosa fa la tua app. Per questo capitolo, puoi usare "Imparare a usare il
Twitter API. "

5. Nel campo URL del sito web, inserisci il tuo sito web. Quando si creano app basate su Twitter,
questo dovrebbe essere il sito web in cui ospiti la tua app. Puoi usare il tuo Twitter
URL: ttps: //twitter.com/ YourUserName , dove YourUserName è il tuo
Nome della schermata dell'account Twitter. Per esempio,ttps: //twitter.com/nasa
corrisponde allo screen name della NASA @nasa.

6. Il campo Dicci come verrà utilizzata questa app è una descrizione di almeno 100
caratteri che aiutano i dipendenti di Twitter a capire cosa fa la tua app. Entrammo
"Sono nuovo nello sviluppo di app Twitter e sto semplicemente imparando come
utilizzare le API di Twitter per scopi didattici. "

7. Lascia i campi rimanenti vuoti e fai clic su Crea, quindi esamina attentamente il (lungo)
termini per sviluppatori e fai di nuovo clic su Crea.

Ottenere le tue credenziali

Dopo aver completato il passaggio 7 sopra, Twitter visualizza una pagina web per la gestione della tua app. A
nella parte superiore della pagina ci sono i dettagli dell'app, le chiavi e i token e le schede delle autorizzazioni. Clicca il
Scheda Chiavi e token per visualizzare le credenziali della tua app. Inizialmente, la pagina mostra il file
Chiavi API di consumo -il chiave API e la chiave segreta API . Fare clic su Crea per ottenere un file
token di accesso e token di accesso segreto . Tutti e quattro questi verranno utilizzati per l'autenticazione
con Twitter in modo da poter richiamare le sue API.

Archiviazione delle credenziali

Come buona pratica, non includere le chiavi API e i token di accesso (o qualsiasi altro
credenziali, come nomi utente e password) direttamente nel codice sorgente, in questo modo
esporli a chiunque legga il codice. È necessario memorizzare le chiavi in ​un file separato e
3
non condividere mai quel file con nessuno.

3
Una buona pratica sarebbe quella di utilizzare una libreria di crittografia come bcrypt
( ttps: //github.com/pyca/bcrypt/ ) per crittografare le tue chiavi, token di accesso o qualsiasi
altre credenziali che utilizzi nel codice, quindi leggerle e decrittarle solo come te
passarli a Twitter.

Il codice che eseguirai nelle sezioni successive presuppone che tu inserisca la tua chiave utente,
consumer secret, token di accesso e valori segreti del token di accesso nel file keys.py mostrato

4h
Pagina 500
sotto. Puoi trovare questo file nella cartella degli esempi ch12:

lecca qui per visualizzare l'immagine del codice

consumer_key = "YourConsumerKey"
consumer_secret = "YourConsumerSecret"
access_token = 'YourAccessToken'
access_token_secret = 'YourAccessTokenSecret'

Modifica questo file, sostituendo YourConsumerKey, YourConsumerSecret,

YourAccessToken e YourAccessTokenSecret con la tua chiave utente, consumatore


secret, token di accesso e valori segreti del token di accesso. Quindi, salva il file.

OAuth 2.0

La chiave del consumatore, il segreto del consumatore, il token di accesso e il segreto del token di accesso fanno parte di
4 ,5
il processo di autenticazione OAuth 2.0 - a volte chiamato la danza OAuth - questo
Twitter utilizza per abilitare l'accesso alle sue API. La libreria Tweepy ti consente di fornire il file
chiave del consumatore, segreto del consumatore, token di accesso e segreto del token di accesso e gestisce il
Dettagli di autenticazione OAuth 2.0 per te.

ttps: //developer.twitter.com/en/docs/basics/authentication/overview .

5
ttps: //oauth.net/ .

12.5 COSA C'È IN UN TWEET?


I metodi dell'API Twitter restituiscono oggetti JSON. JSON (JavaScript Object Notation) è
un formato di scambio dati basato su testo utilizzato per rappresentare gli oggetti come raccolte di nome–
coppie di valori. Viene comunemente utilizzato quando si invocano servizi Web. JSON è sia umano
formato leggibile e leggibile da computer che semplifica l'invio e la ricezione dei dati
la rete.

Gli oggetti JSON sono simili ai dizionari Python. Ogni oggetto JSON contiene un elenco di file
nomi e valori delle proprietà , nel seguente formato tra parentesi graffe:

{ propertyName1 : value1 , propertyName2 : value2 }

Come in Python, gli elenchi JSON sono valori separati da virgole tra parentesi quadre:

[ valore1 , valore2 , valore3 ]

hC
Pagina 501
o per tua comodità, Tweepy gestisce il JSON per te dietro le quinte, convertendo
Oggetti da JSON a Python utilizzando classi definite nella libreria Tweepy.

Proprietà chiave di un oggetto Tweet

Un tweet (chiamato anche aggiornamento di stato ) può contenere un massimo di 280 caratteri, ma il file
gli oggetti tweet restituiti dalle API di Twitter contengono molti attributi di metadati che
descrivere aspetti del tweet, come:

quando è stato creato,

chi l'ha creato,

elenchi di hashtag, URL, @menzioni e media (come immagini e video, che


sono specificati tramite i loro URL) inclusi nel tweet,

e altro ancora.

La tabella seguente elenca alcuni attributi chiave di un oggetto tweet:

ttribute Descrizione

La data e l'ora di creazione in UTC (Coordinated Universal Time)


creato_at
formato.

Twitter estrae hashtag, URL, user_mentions (ovvero,

@ menzioni nome utente ), media (come immagini e video),


entità
simboli e sondaggi dai tweet e li inserisce nel file
dizionario di entità come elenchi a cui è possibile accedere con queste chiavi.

Per i tweet con più di 140 caratteri, contiene dettagli come i tweet
extended_tweet
full_text ed entità

favorite_count Numero di volte in cui altri utenti hanno aggiunto ai preferiti il ​tweet.

F
UN
Pagina 502
Le coordinate (latitudine e longitudine) da cui proveniva il tweet
coordinate inviato. Questo è spesso nullo (Nessuno in Python) perché molti utenti
disabilitare l'invio dei dati sulla posizione.

Gli utenti possono associare un luogo a un tweet. Se lo fanno, questo sarà un file
luogo oggetto:

posto ttps: //developer.twitter.com/en/docs/tweets/data


ictionary / overview / geoobjects # placedictionary
in caso contrario, sarà null (Nessuno in Python).

L'ID intero del tweet. Twitter consiglia di utilizzare id_str


id
portabilità.

id_str La rappresentazione di stringa dell'ID intero del tweet.

Lingua del tweet, ad esempio "en" per l'inglese o "fr" per


lang
Francese.

retweet_count Numero di volte in cui altri utenti hanno ritwittato il tweet.

Il testo del tweet. Se il tweet utilizza il nuovo limite di 280 caratteri


e contiene più di 140 caratteri, questa proprietà sarà
testo truncated e la proprietà truncated verrà impostata su true . Questo
potrebbe anche verificarsi se un tweet di 140 caratteri fosse ritwittato e diventasse
come risultato più di 140 caratteri.

L'oggetto User che rappresenta l'utente che ha pubblicato il tweet. Per il


Proprietà JSON dell'oggetto utente, vedere:
utente
ttps: //developer.twitter.com/en/docs/tweets/data
ictionary / panoramica / UserObject .

S ampio Tweet JSON

Esempio di Tweet JSON Pagina 503

Diamo un'occhiata al JSON di esempio per il seguente tweet dall'account @nasa:

lecca qui per visualizzare l'immagine del codice

@ NoFear1075 Ottima domanda, Anthony! Durante i suoi sette anni di missione,


la nostra sonda spaziale Parker #SolarProbe ... https://t.co/xKd6ym8waT '

Abbiamo aggiunto i numeri di riga e riformattato alcuni JSON a causa del wrapping. Nota che
alcuni campi in Tweet JSON non sono supportati in tutti i metodi API di Twitter; come
le differenze sono spiegate nella documentazione in linea per ogni metodo.

lecca qui per visualizzare l'immagine del codice

1 {'created_at': 'Wed Sep 05 18:19:34 +0000 2018',


2 "id": 1037404890354606082,
3 "id_str": "1037404890354606082",
4 'text': '@ NoFear1075 Ottima domanda, Anthony! Durante i suoi sette anni
missione, la nostra navicella spaziale Parker #SolarProbe
https://t.co/xKd6ym8waT ',
5 "troncato": vero,
6 'entità': {'hashtags': [{'text': 'SolarProbe', 'indices': [84, 95]}],
7 "simboli": [],
8 "menzioni_utente": [{"screen_name": "NoFear1075",
9 'nome': 'Anthony Perrone',
10 "id": 284339791,
11 "id_str": "284339791",
12 "indici": [0, 11]}],
13 'urls': [{'url': 'https://t.co/xKd6ym8waT',
14 "Expand_url": "https://twitter.com/i/web/status/
1037404890354606082 ',
15 "display_url": "twitter.com/i/web/status/1
',
16 "indici": [117, 140]}]},
17 "fonte": "<a href="http://twitter.com” rel="nofollow"> Twitter Web
Cliente </a> ",
18 "in_reply_to_status_id": 1037390542424956928,
19 "in_reply_to_status_id_str": "1037390542424956928",
20 "in_reply_to_user_id": 284339791,
21 'in_reply_to_user_id_str': '284339791',
22 'in_reply_to_screen_name': 'NoFear1075',
23 "utente": {"id": 11348282,
24 "id_str": "11348282",
25 'nome': 'NASA',
26 "screen_name": "NASA",
27 'posizione': '',
28 'description': 'Esplora l'universo e scopri il nostro pianeta natale con
@NASA. Di solito pubblichiamo in EST (UTC5) ",
29 'url': 'https://t.co/TcEE6NS8nD',
30 'entità': {'url': {'urls': [{'url': 'https://t.co/TcEE6NS8nD',

31 "Expand_url": "http://www.nasa.gov", Pagina 504


32 "display_url": "nasa.gov",
33 "indici": [0, 23]}]},
34 'descrizione': {'urls': []}},
35 'protetto': falso,
36 "followers_count": 29486081,
37 "friends_count": 287,
38 'list_count': 91928,
39 'created_at': 'Wed Dec 19 20:20:32 +0000 2007',
40 "favourites_count": 3963,
41 'time_zone': Nessuno,
42 'geo_enabled': False,
43 'verificato': vero,
44 "statuses_count": 53147,
45 'lang': 'en',
46 "contributors_enabled": False,
47 'is_translator': False,
48 'is_translation_enabled': False,
49 'profile_background_color': '000000',
50 "profile_background_image_url": "http://abs.twimg.com/images/themes/
theme1 / bg.png ',
51 "profile_background_image_url_https": "https://abs.twimg.com/images/
temi / theme1 / bg.png ',
52 "profile_image_url": "http://pbs.twimg.com/profile_images/188302352/
nasalogo_twitter_normal.jpg ',
53 'profile_image_url_https': 'https://pbs.twimg.com/profile_images/
188302352 / nasalogo_twitter_normal.jpg ',
54 "profile_banner_url": "https://pbs.twimg.com/profile_banners/11348282/
1535145490 ',
55 'profile_link_color': '205BA7',
56 'profile_sidebar_border_color': '000000',
57 'profile_sidebar_fill_color': 'F3F2F2',
58 'profile_text_color': '000000',
59 "profile_use_background_image": True,
60 'has_extended_profile': True,
61 'default_profile': False,
62 'default_profile_image': False,
63 'seguente': Vero,
64 'follow_request_sent': False,
65 "notifiche": false,
66 "traduttore_type": "regular"},
67 'geo': Nessuno,
68 'coordinate': nessuna,
69 'luogo': Nessuno,
70 "collaboratori": Nessuno,
71 'is_quote_status': False,
72 "retweet_count": 7,
73 "favour_count": 19,
74 "preferiti": falso,
75 "ritwittato": Falso,
76 'possibilmente_sensibile': Falso,
77 'lang': 'en'}

T witter JSON Object Resources

Risorse per oggetti JSON di Twitter Pagina 505

Per un elenco completo e più leggibile degli attributi dell'oggetto tweet, vedere:

ttps: //developer.twitter.com/en/docs/tweets/datadictionary/overview/tweet bject.ht


o ulteriori dettagli aggiunti quando Twitter è passato da un limite di 140 a 280
caratteri per tweet, vedi

ttps: //developer.twitter.com/en/docs/tweets/datadictionary/overview/intrototweet
son.html # extendedtweet

Per una panoramica generale di tutti gli oggetti JSON restituiti dalle API di Twitter e i collegamenti al file
dettagli dell'oggetto specifico, vedere

ttps: //developer.twitter.com/en/docs/tweets/datadictionary/overview/intrototweet
figlio

12.6 TWEEPY
6
Useremo la libreria Tweepy ( ttp: //www.tweepy.org/ ), uno dei più popolari
Librerie Python per interagire con le API di Twitter. Tweepy lo rende di facile accesso
Le capacità di Twitter e ti nasconde i dettagli dell'elaborazione degli oggetti JSON
7
restituito dalle API di Twitter. Puoi visualizzare la documentazione di Tweepy su

6
Le altre librerie Python consigliate da Twitter includono Birdy, pythontwitter, Python
Strumenti Twitter, TweetPony, TwitterAPI, twittergobject, TwitterSearch e twython. Vedere
ttps: //developer.twitter.com/en/docs/developerutilities/twitter
ibraries.html per i dettagli.

7
La documentazione di Tweepy è un work in progress. Al momento della stesura di questo articolo, Tweepy
non ha la documentazione per le loro classi corrispondenti agli oggetti JSON il
Tornano le API di Twitter. Le classi di Tweepy utilizzano gli stessi nomi di attributo e la stessa struttura di
Oggetti JSON. È possibile determinare i nomi degli attributi corretti a cui accedere guardando
Documentazione JSON di Twitter. Spiegheremo qualsiasi attributo che usiamo nel nostro codice e forniremo
note a piè di pagina con collegamenti alle descrizioni JSON di Twitter.

ttp: //docs.tweepy.org/en/latest/

Per ulteriori informazioni e il codice sorgente di Tweepy, visitare

ttps: //github.com/tweepy/tweepy

io
hjF ninstallazione di Tweepy
lO
h

Installazione di Tweepy Pagina 506

Per installare Tweepy, apri il tuo Anaconda Prompt (Windows), Terminal (macOS / Linux) o
shell (Linux), quindi eseguire il seguente comando:

pip install tweepy == 3.7

Gli utenti Windows potrebbero dover eseguire il prompt di Anaconda come amministratore per
privilegi di installazione del software. Per fare ciò, fai clic con il pulsante destro del mouse su Prompt di Anaconda nel menu di avvio
e seleziona Altro> Esegui come amministratore.

Installazione di geopy

Mentre lavori con Tweepy, utilizzerai anche le funzioni del nostro file tweetutilities.py
(fornito con il codice di esempio di questo capitolo). Una delle funzioni di utilità in quel file
dipende dalla libreria di geopy ( ttps: //github.com/geopy/geopy ), che faremo
discutere in ezione 12.15. Per installare geopy, eseguire:

lecca qui per visualizzare l'immagine del codice

conda install c condaforge geopy


12.7 AUTENTICAZIONE CON TWITTER TRAMITE TWEEPY
Nelle sezioni successive, richiamerai varie API Twitter basate su cloud tramite Tweepy.
Qui inizierai utilizzando Tweepy per autenticarti con Twitter e creare un'API Tweepy
oggetto , che è il tuo gateway per utilizzare le API di Twitter su Internet. In seguito
sezioni, lavorerai con varie API di Twitter invocando metodi sul tuo oggetto API.

Prima di poter richiamare qualsiasi API Twitter, è necessario utilizzare la chiave API, la chiave segreta API, l'accesso
8
token e token di accesso segreto per l'autenticazione con Twitter . Avvia IPython da

cartella di esempi ch12, quindi importa il modulo tweepy e il file keys.py che hai
modificato in precedenza in questo capitolo. Puoi importare qualsiasi file .py come modulo utilizzando l'estensione
nome del file senza l'estensione .py in un'istruzione di importazione:

8
Potresti voler creare app che consentano agli utenti di accedere ai propri account Twitter,
gestirli, pubblicare tweet, leggere tweet di altri utenti, cercare tweet, ecc. Per i dettagli
sull'autenticazione dell'utente, vedere il tutorial sull'autenticazione Tweepy all'indirizzo
ttp: //docs.tweepy.org/en/latest/auth_tutorial.html .

In [1]: import tweepy

C
hS
Pagina 507
In [2]: importare le chiavi

Quando importi keys.py come modulo, puoi accedere individualmente a ciascuno dei quattro
variabili definite in quel file come chiavi. nome_variabile .

Creazione e configurazione di un OAuthHandler per l'autenticazione con Twitter

L'autenticazione con Twitter tramite Tweepy prevede due passaggi. Innanzitutto, crea un oggetto di
la classe OAuthHandler del modulo tweepy , passando la chiave API e la chiave segreta API al suo file
costruttore. Un costruttore è una funzione che ha lo stesso nome della classe (in this
case, OAuthHandler) e riceve gli argomenti utilizzati per configurare il nuovo oggetto:

lecca qui per visualizzare l'immagine del codice

In [3]: auth = tweepy.OAuthHandler (keys.consumer_key,


In [3]: auth = tweepy.OAuthHandler (keys.consumer_key,
...:

Specificare il token di accesso e il segreto del token di accesso chiamando l'oggetto OAuthHandler

metodo set_access_token :

lecca qui per visualizzare l'immagine del codice

In [4]: ​auth.set_access_token (keys.access_token,


...: keys.access_token_secret)
...:

Creazione di un oggetto API

Ora crea l'oggetto API che utilizzerai per interagire con Twitter:

lecca qui per visualizzare l'immagine del codice

In [5]: api = tweepy.API (auth, wait_on_rate_limit = True ,


...: wait_on_rate_limit_notify = True )
...:

Abbiamo specificato tre argomenti in questa chiamata al costruttore API:

auth è l'oggetto OAuthHandler contenente le tue credenziali.

L'argomento della parola chiave wait_on_rate_limit = True dice a Tweepy di attendere 15

C
Pagina 508
minuti ogni volta che raggiunge il limite di velocità di un determinato metodo API. Questo ti assicura di farlo
non violare le restrizioni sui limiti di ratifica di Twitter.

L'argomento della parola chiave wait_on_rate_limit_notify = True dice a Tweepy che, se è così
deve attendere a causa dei limiti di velocità, dovrebbe avvisarti visualizzando un messaggio in
riga di comando.

Ora sei pronto per interagire con Twitter tramite Tweepy. Si noti che gli esempi di codice in
le prossime sezioni vengono presentate come una sessione IPython continua, quindi l'autorizzazione
il processo che hai seguito qui non deve essere ripetuto.

12.8 OTTENERE INFORMAZIONI SU TWITTER


ACCOUNT
Dopo esserti autenticato con Twitter, puoi utilizzare get_user dell'oggetto API Tweepy
Metodo per ottenere un oggetto tweepy.models.User contenente informazioni su un utente di
Account Twitter. Otteniamo un oggetto utente per l'account Twitter @nasa della NASA:

lecca qui per visualizzare l'immagine del codice

In [6]: nasa = api.get_user ( 'nasa' )

9
Il metodo get_user chiama il metodo users / show dell'API di Twitter. Ogni Twitter
il metodo che chiami tramite Tweepy ha un limite di velocità. Puoi chiamare gli utenti / show di Twitter
metodo fino a 900 volte ogni 15 minuti per ottenere informazioni su account utente specifici. Come
menzioniamo altri metodi API di Twitter, forniremo una nota a piè di pagina con un collegamento a ciascuno
documentazione del metodo in cui è possibile visualizzare i suoi limiti di velocità.

9
ttps: //developer.twitter.com/en/docs/accountsandusers/follow
earchgetusers / apireference / getusersshow .

Le classi tweepy.models corrispondono ciascuna al JSON restituito da Twitter. Per


Ad esempio, la classe User corrisponde a un oggetto utente Twitter :

ttps: //developer.twitter.com/en/docs/tweets/datadictionary/overview/userobject

Ogni classe tweepy.models ha un metodo che legge il JSON e lo trasforma in un oggetto


della corrispondente classe Tweepy.

Ottenere le informazioni di base sull'account

hC
S
Pagina 509
Accediamo ad alcune proprietà degli oggetti utente per visualizzare le informazioni sull'account @nasa:

La proprietà id è il numero ID dell'account creato da Twitter quando l'utente si è unito


Twitter.

La proprietà name è il nome associato all'account dell'utente.


La proprietà screen_name è l'handle Twitter dell'utente (@nasa). Sia il nome
e screen_name potrebbero essere nomi creati per proteggere la privacy di un utente.

La proprietà description è la descrizione dal profilo dell'utente.

lecca qui per visualizzare l'immagine del codice

In [7]: nasa.id
Uscita [7]: 11348282

In [8]: nasa.name
Uscita [8]: "NASA"

In [9]: nasa.screen_name
Uscita [9]: "NASA"

In [10]: nasa.description
Out [10]: 'Esplora l'universo e scopri il nostro pianeta natale con @NASA. Sually

Impostazione dell'aggiornamento di stato più recente

La proprietà status dell'oggetto User restituisce un oggetto tweepy.models.Status , che


corrisponde a un oggetto tweet di Twitter :

ttps: //developer.twitter.com/en/docs/tweets/datadictionary/overview/tweetobject

La proprietà text dell'oggetto Status contiene il testo del tweet più recente dell'account:

lecca qui per visualizzare l'immagine del codice

In [11]: nasa.status.text
Out [11]: 'L'interazione di una giovane star di alta velocità con la nuvola di as e d

La proprietà text era originariamente per tweet fino a 140 caratteri. Il ... sopra indica
che il testo del tweet è stato troncato . Quando Twitter ha aumentato il limite a 280 caratteri,

hG
C
T
Pagina 510
hanno aggiunto una proprietà extended_tweet (dimostrata in seguito) per accedere al testo
e altre informazioni dai tweet tra 141 e 280 caratteri. In questo caso, Twitter
imposta il testo su una versione troncata del testo di extended_tweet. Inoltre, ritwittando spesso
si traduce in un troncamento perché un retweet aggiunge caratteri che potrebbero superare il carattere
limite.

Ottenere il numero di follower

Puoi visualizzare il numero di follower di un account con la proprietà followers_count :

lecca qui per visualizzare l'immagine del codice

In [12]: nasa.followers_count
Uscita [12]: 29453541

0
Sebbene questo numero sia elevato, ci sono account con oltre 100 milioni di follower.

0
ttps: //friendorfollow.com/twitter/mostfollowers/ .

Ottenere il numero di amici


Allo stesso modo, puoi visualizzare il numero di amici di un account (ovvero il numero di account e
account segue) con la proprietà friends_count :

In [13]: nasa.friends_count
Uscita [13]: 287

Ottenere le informazioni sul proprio account

Puoi utilizzare le proprietà in questa sezione anche sul tuo account. Per fare ciò, chiama il
Metodo me dell'oggetto API Tweepy , come in:

me = api.me ()

Ciò restituisce un oggetto utente per l'account utilizzato per l'autenticazione con Twitter nel file
sezione precedente.

12.9 INTRODUZIONE AI CURSORI TWEEPY: OTTENERE UN


SEGUENTI E AMICI DELL'ACCOUNT
Quando si richiamano i metodi dell'API di Twitter, si ricevono spesso come risultati raccolte di oggetti,
come tweet nella timeline di Twitter, tweet nella timeline di un altro account o elenchi di
tweet che corrispondono ai criteri di ricerca specificati. Una sequenza temporale è costituita dai tweet inviati da quell'utente

hC
1

Pagina 511
e dagli amici di quell'utente, ovvero altri account che l'utente segue.

La documentazione di ogni metodo API di Twitter discute il numero massimo di elementi di


metodo può restituire in una chiamata, questa è nota come pagina dei risultati. Quando ne richiedi di più
risultati che un determinato metodo può restituire, le risposte JSON di Twitter indicano che ci sono
più pagine per ottenere. La classe Cursor di Tweepy gestisce questi dettagli per te. Un cursore
invoca un metodo specificato e controlla se Twitter ha indicato che ce n'è un altro
pagina dei risultati. In tal caso, il cursore chiama di nuovo automaticamente il metodo per ottenere quei risultati.
Ciò continua, soggetti ai limiti di velocità del metodo, fino a quando non ci sono più risultati a
processi. Se configuri l'oggetto API in modo che attenda quando vengono raggiunti i limiti di velocità (come abbiamo fatto noi),
il Cursore rispetterà i limiti di velocità e attenderà secondo necessità tra le chiamate. Il seguente
le sottosezioni trattano i fondamenti del cursore. Per ulteriori dettagli, vedere il tutorial del cursore su:

ttp: //docs.tweepy.org/en/latest/cursor_tutorial.html

12.9.1 Determinazione dei follower di un account

Usiamo un Tweepy Cursor per invocare il metodo followers dell'oggetto API , che chiama
1
il metodo follower / elenco dell'API di Twitter per ottenere i follower di un account. Twitter
li restituisce in gruppi di 20 per impostazione predefinita, ma è possibile richiederne fino a 200 alla volta. Per
scopi dimostrativi, prenderemo 10 seguaci della NASA.

1
ttps: //developer.twitter.com/en/docs/accountsandusers/follow
earchgetusers / apireference / getfollowerslist .

I follower del metodo restituiscono oggetti tweepy.models.User contenenti informazioni


su ogni follower. Cominciamo creando un elenco in cui memorizzeremo gli oggetti Utente:

In [14]: follower = []

Creazione di un cursore

Successivamente, creiamo un oggetto Cursor che chiamerà il metodo followers per la NASA
account, che viene specificato con l'argomento della parola chiave screen_name:
lecca qui per visualizzare l'immagine del codice

In [15]: cursor = tweepy.Cursor (api.followers, screen_name = 'nasa' )

Il costruttore del cursore riceve come argomento il nome del metodo da chiamare
—Api.followers indica che il cursore chiamerà i follower dell'oggetto api

hC
S
1h

Pagina 512
metodo. Se il costruttore Cursor riceve argomenti di parole chiave aggiuntivi, come
screen_name, questi verranno passati al metodo specificato nel primo del costruttore
discussione. Quindi, questo cursore ottiene specificamente follower per l'account Twitter @nasa.

Ottenere risultati

Ora possiamo usare il cursore per ottenere alcuni seguaci. Quanto segue per l'istruzione itera
attraverso i risultati dell'espressione cursor.items (10). Gli elementi del cursore
metodo avvia la chiamata a api.followers e restituisce il metodo seguaci di
risultati. In questo caso, passiamo 10 al metodo items per richiedere solo 10 risultati:

lecca qui per visualizzare l'immagine del codice

In [16]: per l' account in cursor.items ( 10 ):


...: followers.append (account.screen_name)
...:
In [17]: print ( 'Followers:' ,
...: '' .join (ordinato (followers, key = lambda s: s.lower ())))
...:
Seguaci: abhinavborra BHood1976 Eshwar12341 Harish90469614 heshamkisha H ghyaan24

Lo snippet precedente mostra i follower in ordine crescente chiamando il builtin


funzione ordinata. Il secondo argomento della funzione è la funzione utilizzata per determinare come
gli elementi dei follower vengono ordinati. In questo caso, abbiamo utilizzato un lambda che converte ogni
nome follower in lettere minuscole in modo da poter eseguire un ordinamento senza distinzione tra maiuscole e minuscole.

Paging automatico

Se il numero di risultati richiesti è superiore a quello può essere restituito da una chiamata a
follower, il metodo elementi "sfoglia" automaticamente i risultati effettuando
più chiamate a api.followers. Ricorda che i follower restituiscono fino a 20 follower in a
time per impostazione predefinita, quindi il codice precedente deve chiamare i follower solo una volta. Per alzarsi
200 follower alla volta, possiamo creare il Cursore con l'argomento della parola chiave count, come
nel:

lecca qui per visualizzare l'immagine del codice

cursore = tweepy.Cursor (api.followers, screen_name = 'nasa' , count = 200 )

Se non si specifica un argomento per il metodo items, The Cursor tenta di ottenere tutto
dei follower dell'account. Per un gran numero di follower, questo potrebbe richiedere un notevole
quantità di tempo dovuta ai limiti di frequenza di Twitter. Il metodo follower / elenco dell'API di Twitter

T
C
Pagina 513
un ritorno un massimo di 200 follower alla volta e Twitter consente un massimo di 15
chiama ogni 15 minuti. Pertanto, puoi ottenere solo 3000 follower ogni 15 minuti utilizzando
API gratuite di Twitter. Ricorda che abbiamo configurato l'oggetto API per attendere automaticamente quando si
raggiunge un limite di frequenza, quindi se provi a ottenere tutti i follower e un account ne ha più di 3000,
Tweepy si fermerà automaticamente per 15 minuti ogni 3000 follower e visualizzerà un file
Messaggio. Al momento della stesura di questo articolo, la NASA ha oltre 29,5 milioni di follower. A 12.000
follower all'ora, ci vorrebbero più di 100 giorni per ottenere tutti i follower della NASA.

Nota che per questo esempio, avremmo potuto chiamare direttamente il metodo followers, piuttosto
rispetto all'utilizzo di un cursore, poiché stiamo ottenendo solo un piccolo numero di follower. Abbiamo usato un file

Cursore qui per mostrare come chiamerai in genere i follower. In alcuni esempi successivi, lo faremo
chiama direttamente i metodi API per ottenere solo pochi risultati, invece di usare i cursori.

Ottenere gli ID dei follower invece dei follower

Sebbene tu possa ottenere oggetti utente completi per un massimo di 200 follower alla volta, tu
può ottenere molti più numeri ID Twitter chiamando followers_ids dell'oggetto API
metodo . Questo chiama il metodo followers / ids dell'API di Twitter, che restituisce fino a 5000
2
Numeri ID alla volta (di nuovo, questi limiti di velocità potrebbero cambiare). Puoi invocarlo
metodo fino a 15 volte ogni 15 minuti, in modo da ottenere 75.000 numeri di ID account per
intervallo limite di frequenza. Ciò è particolarmente utile se combinato con l'oggetto API
3
lookup_users metodo . Questo chiama il metodo di ricerca / utenti dell'API di Twitter che
può restituire fino a 100 oggetti utente alla volta e può essere richiamato fino a 300 volte ogni 15
minuti. Quindi, utilizzando questa combinazione, potresti ottenere fino a 30.000 oggetti utente per tariffa
intervallo limite.

2
ttps: //developer.twitter.com/en/docs/accountsandusers/follow
earchgetusers / apireference / getfollowersids .

3
ttps: //developer.twitter.com/en/docs/accountsandusers/follow
earchgetusers / apireference / getuserslookup .

12.9.2 Determinazione di chi segue un account


4
Il metodo friends dell'oggetto API chiama il metodo friends / list dell'API di Twitter a
ottenere un elenco di oggetti utente che rappresentano gli amici di un account. Twitter li restituisce
gruppi di 20 per impostazione predefinita, ma puoi richiederne fino a 200 alla volta, proprio come abbiamo discusso per
seguaci del metodo. Twitter ti consente di chiamare il metodo amici / elenco fino a 15 volte
ogni 15 minuti. Prendiamo 10 account di amici della NASA:

4
ttps: //developer.twitter.com/en/docs/accountsandusers/follow

chS
1

Pagina 514
earchgetusers / apireference / getfriendslist .

lecca qui per visualizzare l'immagine del codice

In [18]: amici = []

In [19]: cursor = tweepy.Cursor (api.friends, screen_name = 'nasa' )

In [20]: for friend in cursor.items ( 10 ):


...: friends.append (friend.screen_name)
...:

In [21]: print ( 'Friends:' ,


...: '' .join (ordinato (amici, chiave = lambda s: s.lower ())))
...:
Amici: AFSpace Astro2fish Astro_Kimiya AstroAnnimal AstroDuke NASA3DPrin er NASAS

2.9.3 Recupero dei tweet recenti di un utente

Il metodo API user_timeline restituisce i tweet dalla sequenza temporale di un account specifico.
Una sequenza temporale include i tweet di quell'account e quelli degli amici di quell'account. Il
5
chiama il metodo statuses / user_timeline dell'API di Twitter, che restituisce l'estensione
i 20 tweet più recenti, ma possono restituirne fino a 200 alla volta. Questo metodo può restituire solo un file
i 3200 tweet più recenti dell'account. Le applicazioni che utilizzano questo metodo possono chiamarlo fino a 1500
volte ogni 15 minuti.

5
ttps: //developer.twitter.com/en/docs/tweets/timelines/api
Riferimenti / getstatusesuser_timeline .

Il metodo user_timeline restituisce gli oggetti Status, ognuno dei quali rappresenta un tweet.
La proprietà utente di ogni stato fa riferimento a un oggetto tweepy.models.User contenente
informazioni sull'utente che ha inviato quel tweet, come screen_name dell'utente. UN
La proprietà text dello stato contiene il testo del tweet. Visualizziamo screen_name e
testo per tre tweet da @nasa:

lecca qui per visualizzare l'immagine del codice

n [22]: nasa_tweets = api.user_timeline (screen_name = 'nasa' , count = 3 )

In [23]: per tweet in nasa_tweets:


...: print (f ' {tweet.user.screen_name} : {tweet.text} \ n' )
...:
NASA: Your Gut in Space: I microrganismi nel tratto intestinale giocano un ruolo speciale
https://t.co/uLOsUhwn5p

11rShC
NASA: Abbiamo bisogno del tuo aiuto! Vuoi vedere i pannelli su @SXSW relativi all'esplorazione spaziale?
Pagina 515
https://t.co/ycqMMdGKUB

NASA: "Sei bravo come chiunque in questa città, ma non sei migliore di nessuno di loro
https://t.co/nhMD4n84Nf

Questi tweet sono stati troncati (come indicato da), il che significa che probabilmente usano il più recente
Limite di tweet di 280 caratteri. Useremo a breve la proprietà extended_tweet per accedere a full
testo per tali tweet.

Negli snippet precedenti, abbiamo scelto di chiamare direttamente il metodo user_timeline e di utilizzare
l'argomento della parola chiave count per specificare il numero di tweet da recuperare. Se lo desideri
ottieni più del numero massimo di tweet per chiamata (200), quindi dovresti usare un file

Cursore per chiamare user_timeline come dimostrato in precedenza. Ricorda che un cursore
sfoglia automaticamente i risultati chiamando il metodo più volte, se necessario.

Acquisizione di tweet recenti dalla propria cronologia

Puoi chiamare il metodo API home_timeline , come in:

api.home_timeline ()

6
per ottenere i tweet dal vostro timeline di casa -cioè, i tuoi tweets e tweets dal popolo
7
tu segui. Questo metodo chiama il metodo statuses / home_timeline di Twitter. Di
predefinito, home_timeline restituisce i 20 tweet più recenti, ma può arrivare fino a 200 in un file
tempo. Ancora una volta, per più di 200 tweet dalla cronologia di casa, dovresti usare un Tweepy
Cursore per chiamare home_timeline.

6
Specifico per l'account che hai utilizzato per autenticarti con Twitter.

7
ttps: //developer.twitter.com/en/docs/tweets/timelines/api
Riferimenti / getstatuseshome_timeline .

12.10 RICERCA DEI TWEET RECENTI


La ricerca del metodo API Tweepy restituisce tweet che corrispondono a una stringa di query. Secondo
la documentazione del metodo, Twitter mantiene il suo indice di ricerca solo per il precedente
tweet di sette giorni e non è garantito che una ricerca restituisca tutti i tweet corrispondenti. Metodo
8
search chiama il metodo search / tweets di Twitter, che restituisce 15 tweet alla volta per
predefinito, ma può restituire fino a 100.

8
ttps: //developer.twitter.com/en/docs/tweets/search/api

rT
1h

Pagina 516
Riferimenti / getsearchtweets .

Funzione di utilità print_tweets da tweetutilities.py

Per questa sezione, abbiamo creato una funzione di utilità print_tweets che riceve i risultati di un file
chiamata alla ricerca del metodo API e per ogni tweet mostra lo screen_name dell'utente e il file
testo del tweet. Se il tweet non è in inglese e il file tweet.lang non è "und"
(undefined), tradurremo anche il tweet in inglese utilizzando TextBlob, come hai fatto nel
" capitolo sull'elaborazione del linguaggio naturale (PNL) . Per utilizzare questa funzione, importala da
tweetutilities.py:

lecca qui per visualizzare l'immagine del codice

In [24]: da tweetutilities importa print_tweets

Di seguito è mostrata solo la definizione della funzione print_tweets da quel file:

lecca qui per visualizzare l'immagine del codice

def print_tweets (tweets):


"" "Per ogni oggetto Stato Tweepy nei tweet, visualizza il file
screen_name dell'utente e tweet text. Se la lingua non lo è
Inglese, traduci il testo con TextBlob. "" "
per tweet nei tweet:
print (f ' {tweet.screen_name} :' , end = '' )

se 'en' in tweet.lang:
print (f ' {tweet.text} \ n' )
elif 'und' not in tweet.lang: # traduci prima in inglese
print (f '\ n ORIGINALE: {tweet.text} ' )
print (f 'TRANSLATED: {TextBlob (tweet.text) .translate ()} \ n' )

Alla ricerca di parole specifiche

Cerchiamo tre recenti tweet sul Mars Opportunity Rover della NASA. La ricerca
L'argomento della parola chiave q del metodo specifica la stringa di query, che indica cosa cercare
for e l'argomento della parola chiave count specifica il numero di tweet da restituire:

lecca qui per visualizzare l'immagine del codice

n [25]: tweets = api.search (q = 'Mars Opportunity Rover' , count = 3 )

In [26]: print_tweets (tweets)


Jacker760: la NASA ha fissato una scadenza per l'opportunità di Mars Rover! Come la polvere su Marte
https://t.co/KQ7xaFgrzr

N
C
r
Pagina 517
hivak32637174: RT @ Gadgets360: NASA 'cautamente ottimista' nel sentire indietro da O
https://t.co/O1iTTwRvFq

ladyanakina: Opportunity Rover della NASA ancora silenziosa su #Mars. https://t.co/njcyP6zCm


s con altri metodi, se si prevede di richiedere più risultati di quelli che possono essere restituiti da uno
chiamata per cercare, dovresti usare un oggetto Cursor.

Ricerca con gli operatori di ricerca di Twitter

Puoi utilizzare vari operatori di ricerca di Twitter nelle stringhe di query per perfezionare la ricerca
risultati. La tabella seguente mostra diversi operatori di ricerca su Twitter. Operatori multipli
possono essere combinati per costruire query più complesse. Per vedere tutti gli operatori, visita

ttps: //twitter.com/searchhome

e fare clic sul collegamento operatori.

Esempio Trova tweets contenenti

pitone Logico e operatore impliciti : trova i tweet contenenti


twitter pitone e twitter.

python OR Operatore OR logico: trova i tweet contenenti python o

twitter twitter o entrambi .

? (punto interrogativo): trova i tweet su cui fanno domande


pitone?
pitone.

(segno meno): trova i tweet contenenti pianeti ma non


pianeti marte
Marte.

:) (faccina felice): trova tweet con commenti positivi

UN
h

Pagina 518
pitone :) contenente python.

:( (faccina triste): trova tweet con commenti negativi contenenti


python :(
pitone.

dal: 2018 Trova i tweet alla o dopo la data specificata, che deve essere

0901 nella forma AAAAMMGG.

vicino: "Nuovo
Trova i tweet inviati vicino a "New York City".
York City "

da: nasa Trova i tweet dall'account @nasa.


a: nasa Trova i tweet nell'account @nasa.

Usiamo gli operatori from e since per ottenere tre tweet dalla NASA da settembre
1, 2018: dovresti usare una data entro sette giorni prima di eseguire questo codice:

lecca qui per visualizzare l'immagine del codice

In [27]: tweets = api.search (q = 'from: nasa since: 20180901' , count = 3 )


In [28]: print_tweets (tweets)
NASA: @WYSIW Le nostre missioni rilevano incendi attivi, monitorano l'incendio del trasporto
https://t.co/jx2iUoMlIy
NASA: La cicatrizzazione del paesaggio è evidente sulla scia dell'abete di Mendocino Co plex
https://t.co/Nboo5GD90m
NASA: RT @NASAglenn: Per celebrare il 60 ° anniversario della # NASA, stiamo esplorando il nostro ciao

alla ricerca di un hashtag

I tweet spesso contengono hashtag che iniziano con # per indicare qualcosa di importante,
come un argomento di tendenza. Otteniamo due tweet contenenti l'hashtag #collegefootball:

S
C
Pagina 519
lecca qui per visualizzare l'immagine del codice

In [29]: tweets = api.search (q = '#collegefootball' , count = 2 )

In [30]: print_tweets (tweets)


dmcreek: Tanto per #FAU che ha dato un gioco a #OU. #Oklahoma #FloridaAtlantic #C llegeFoo

heangrychef: È il giorno del gioco gente! E il nostro gioco barbecue è forte. #bbq #atlan a #colle

2.11 RICERCA TENDENZE: API TWITTER TRENDS


Se un argomento "diventa virale", potresti avere migliaia o addirittura milioni di persone che twittano
subito. Twitter si riferisce a questi come argomenti di tendenza e mantiene elenchi di tendenze
argomenti in tutto il mondo. Tramite l'API Twitter Trends, puoi ottenere elenchi di posizioni con tendenze
argomenti ed elenchi dei 50 principali argomenti di tendenza per ciascuna località.

12.11.1 Luoghi con argomenti di tendenza

Il metodo trends_available dell'API Tweepy chiama l'API di Twitter


9
tendenze / metodo disponibile per ottenere un elenco di tutte le posizioni per le quali Twitter ha tendenze
temi. Il metodo trends_available restituisce un elenco di dizionari che li rappresentano
posizioni. Quando abbiamo eseguito questo codice, c'erano 467 posizioni con argomenti di tendenza:

9
ttps: //developer.twitter.com/en/docs/trends/locationswith
rendingtopics / apireference / gettrendsavailable .

lecca qui per visualizzare l'immagine del codice

In [31]: trends_available = api.trends_available ()


In [32]: len (trends_available)
Uscita [32]: 467

Il dizionario in ogni elemento della lista restituito da trends_available ha diversi


informazioni, incluso il nome del luogo e il guaio (discusso di seguito):
lecca qui per visualizzare l'immagine del codice

In [33]: trends_available [ 0 ]
Fuori [33]:
{"name": "Worldwide",
'placeType': {'code': 19, 'name': 'Supername'},
"url": "http://where.yahooapis.com/v1/place/1",
'parentid': 0,

1ht1Ct
'nazione': '',
Pagina 520
'woeid': 1,
'countryCode': Nessuno}

In [34]: trends_available [ 1 ]
Fuori [34]:
{"nome": "Winnipeg",
'placeType': {'code': 7, 'name': 'Town'},
"url": "http://where.yahooapis.com/v1/place/2972",
"parentid": 23424775,
'country': 'Canada',
'woeid': 2972,
"countryCode": "CA"}

Il metodo trend / luogo dell'API Twitter Trends (discusso momentaneamente) utilizza Yahoo!
Where on Earth ID (WOEID) per cercare argomenti di tendenza. Il WOEID 1 rappresenta
in tutto il mondo . Altre posizioni hanno valori WOEID univoci maggiori di 1. Useremo WOEID
valori nelle due sottosezioni successive per ottenere argomenti di tendenza e argomenti di tendenza a livello mondiale
una città specifica. La tabella seguente mostra i valori WOEID per diversi punti di riferimento, città,
stati e continenti. Nota che sebbene questi siano tutti WOEID validi, Twitter non lo fa
avere necessariamente argomenti di tendenza per tutte queste località.

Posto WOEID Posto WOEID

Statua della Libertà 23617050 Cascate dell'Iguazú 468785

Los Angeles, CA 2442047 stati Uniti 23424977

Washington, DC 2514815 Nord America 24865672

Parigi, Francia 615702 Europa 24865675

È anche possibile cercare posizioni vicine a una posizione specificata con latitudine e
valori di longitudine. Per fare ciò, chiama il metodo trends_closest dell'API Tweepy , che
0
richiama le tendenze / il metodo più vicino dell'API di Twitter.

0
2

0 Pagina 521
ttps: //developer.twitter.com/en/docs/trends/locationswith
rendingtopics / apireference / gettrendsclosest .

12.11.2 Ottenere un elenco di argomenti di tendenza


Il metodo trends_place dell'API Tweepy chiama l'API Twitter Trends
1
metodo trend / luogo per ottenere i primi 50 argomenti di tendenza per la località con l'estensione
WOEID specificato. Puoi ottenere i WOEID dall'attributo woeid in ogni dizionario
restituito dai metodi trends_available o trends_closest discussi in
sezione precedente, oppure puoi trovare Yahoo! Where on Earth ID (WOEID) di
ricerca di una città / paese, stato, paese, indirizzo, codice postale o punto di riferimento in

1
ttps: //developer.twitter.com/en/docs/trends/trendsfor
ocation / apireference / gettrendsplace .

ttp: //www.woeidlookup.com

Puoi anche cercare WOEID a livello di programmazione utilizzando i servizi web di Yahoo! tramite Python
2
biblioteche come woeid:

2
Avrai bisogno di un account Yahoo! Chiave API come descritto nella documentazione del modulo woeid.

ttps: //github.com/RaySunR/woeid

Argomenti di tendenza in tutto il mondo

Vediamo gli argomenti di tendenza mondiali di oggi (i risultati saranno diversi):

lecca qui per visualizzare l'immagine del codice

In [35]: world_trends = api.trends_place (id = 1 )

Il metodo trends_place restituisce un elenco di un elemento contenente un dizionario. La dizione


La chiave "tendenze" di ary si riferisce a un elenco di dizionari che rappresentano ciascuna tendenza:

lecca qui per visualizzare l'immagine del codice

In [36]: trends_list = world_trends [ 0 ] [ 'trends' ]

Ogni dizionario delle tendenze ha nome, url, promoted_content (che indica che il tweet è un file

tC
2lhh

Pagina 522
advertisement), i tasti query e tweet_volume (mostrati sotto). La tendenza seguente è in atto
Spagnolo— # BienvenidoSeptiembre significa "Benvenuto settembre":

lecca qui per visualizzare l'immagine del codice

In [37]: trends_list [ 0 ]
Fuori [37]:
{'name': '#BienvenidoSeptiembre',
'url': 'http://twitter.com/search?q=%23BienvenidoSeptiembre',
"promoted_content": Nessuno,
'query': '% 23BienvenidoSeptiembre',
"tweet_volume": 15186}

Per le tendenze con più di 10.000 tweet, tweet_volume è il numero di tweet;


altrimenti è Nessuno. Usiamo una comprensione dell'elenco per filtrare l'elenco in modo che contenga solo
tendenze con più di 10.000 tweet:

lecca qui per visualizzare l'immagine del codice

In [38]: trends_list = [t per t in trends_list if t [ 'tweet_volume' ]]


Quindi, ordiniamo le tendenze in ordine decrescente per tweet_volume:

lecca qui per visualizzare l'immagine del codice

In [39]: da operatore import itemgetter

In [40]: trends_list.sort (key = itemgetter ( 'tweet_volume' ), reverse = True )

Ora, mostriamo i nomi dei primi cinque argomenti di tendenza:

lecca qui per visualizzare l'immagine del codice

In [41]: for trend in trends_list [: 5 ]:


...: print (trend [ 'nome' ])
...:
#HBDJanaSenaniPawanKalyan
#BackToHogwarts
Khalil Mack
#ItalianGP
Alisson

Argomenti di tendenza di New York City

C
Pagina 523
Ora, passiamo ai cinque principali argomenti di tendenza per New York City (WOEID 2459115). Il
codice seguente esegue le stesse attività di cui sopra, ma per il diverso WOEID:

lecca qui per visualizzare l'immagine del codice

In [42]: nyc_trends = api.trends_place (id = 2459115 ) # WOEID di New York City

In [43]: nyc_list = nyc_trends [ 0 ] [ 'trends' ]

In [44]: nyc_list = [t for t in nyc_list if t [ 'tweet_volume' ]]

In [45]: nyc_list.sort (key = itemgetter ( 'tweet_volume' ), reverse = True )

In [46]: for trend in nyc_list [: 5 ]:


...: print (trend [ 'nome' ])
...:
# IDOL100M
#TuesdayThoughts
#HappyBirthdayLiam
NAFTA
#USOpen

12.11.3 Creare una nuvola di parole da argomenti di tendenza


Nel " capitolo " Elaborazione linguistica naturale ", abbiamo utilizzato la libreria WordCloud per creare
nuvole di parole. Usiamolo di nuovo qui, per visualizzare gli argomenti di tendenza di New York City che hanno
più di 10.000 tweet ciascuno. Per prima cosa, creiamo un dizionario composto da coppie chiave-valore
dei nomi degli argomenti di tendenza e tweet_volumes:

lecca qui per visualizzare l'immagine del codice

In [47]: topics = {}

In [48]: per trend in nyc_list:


...: topics [trend [ 'name' ]] = trend [ 'tweet_volume' ]
...:
Successivamente, creiamo un WordCloud dalle coppie chiave-valore del dizionario degli argomenti, quindi
visualizza la nuvola di parole nel file immagine TrendingTwitter.png (mostrato dopo il codice).
L'argomento prefer_horizontal = 0.5 suggerisce che il 50% delle parole dovrebbe essere
orizzontale, sebbene il software possa ignorarlo per adattarsi al contenuto:

lecca qui per visualizzare l'immagine del codice

In [49]: da wordcloud importa WordCloud

N
C
Pagina 524
n [50]: wordcloud = WordCloud (larghezza = 1600 , altezza = 900 ,
...: prefer_horizontal = 0.5 , min_font_size = 10 , colormap = 'prism' ,
...: background_color = 'bianco' )
...:

In [51]: wordcloud = wordcloud.fit_words (argomenti)

In [52]: wordcloud = wordcloud.to_file ( 'TrendingTwitter.png' )

La nuvola di parole risultante è mostrata di seguito: la tua sarà diversa in base agli argomenti di tendenza
il giorno in cui esegui il codice:

12.12 PULIZIA / PREPROCESSIONE DEI TWEET PER


ANALISI
La pulizia dei dati è una delle attività più comuni svolte dai data scientist. A seconda di
come intendi elaborare i tweet, dovrai utilizzare l'elaborazione del linguaggio naturale per
normalizzarli eseguendo alcune o tutte le attività di pulizia dei dati nella tabella seguente.
Molti di questi possono essere eseguiti utilizzando le librerie introdotte nel " Linguaggio naturale
capitolo rocessing (NLP) ":

Tweet attività di pulizia

Conversione di tutto il testo nello stesso caso

Rimozione di parole chiave

N
P
io

Pagina 525
emoving # simbolo dagli hashtag Rimozione di RT (retweet) e FAV (preferito)

Rimozione di @menzioni Rimozione di URL

Rimozione di duplicati Stemming


Rimozione degli spazi bianchi in eccesso Lemmatizzazione

Rimozione di hashtag Tokenizzazione

Rimozione della punteggiatura

libreria tweet-preprocessor e funzioni di utilità TextBlob

In questa sezione, utilizzeremo la libreria tweetpreprocessor

ttps: //github.com/s/preprocessor

per eseguire alcune semplici operazioni di pulizia dei tweet. Può rimuovere automaticamente qualsiasi combinazione di:

URL,

@menzioni (come @nasa),

hashtag (come #mars),

Parole riservate di Twitter (come, RT per retweet e FAV per preferiti, che è simile a un file
"Mi piace" su altri social network),

emoji (tutte o solo faccine) e

numeri

La tabella seguente mostra le costanti del modulo che rappresentano ciascuna opzione:

Opzione Costante di opzione

@Mentions (ad esempio, @nasa) OPZIONE

hR
Pagina 526

Emoji OPT.EMOJI

Hashtag (ad esempio, #mars) OPT.HASHTAG

Numero OPT.NUMBER

Parole riservate (RT e FAV) OPT.RESERVED

Smiley SMILEY OTTIMALE

URL OPT.URL
Installazione del tweet-preprocessor

Per installare tweetpreprocessor, apri il tuo Anaconda Prompt (Windows), Terminal


(macOS / Linux) o shell (Linux), quindi immetti il ​seguente comando:

pip installa tweetpreprocessor

Gli utenti Windows potrebbero dover eseguire il prompt di Anaconda come amministratore per i file
privilegi di installazione del software. Per fare ciò, fai clic con il pulsante destro del mouse su Prompt di Anaconda nel menu di avvio
e seleziona Altro> Esegui come amministratore.

Pulire un Tweet

Facciamo un po 'di pulizia tweet di base che useremo in un esempio successivo in questo capitolo. Il
Il nome del modulo della libreria tweetpreprocessor è preprocessor. La sua documentazione
consiglia di importare il modulo come segue:

lecca qui per visualizzare l'immagine del codice

In [1]: importa il preprocessore come p

C
Pagina 527
Per impostare le opzioni di pulizia che desideri utilizzare chiama la funzione set_options del modulo . Nel
in questo caso, vorremmo rimuovere gli URL e le parole riservate di Twitter:

lecca qui per visualizzare l'immagine del codice

In [2]: p.set_options ( p.OPT.URL , p.OPT.RESERVED )

Ora puliamo un tweet di esempio contenente una parola riservata (RT) e un URL:

lecca qui per visualizzare l'immagine del codice

In [3]: tweet_text = "RT A sample retweet with a URL https://nasa.gov"

In [4]: ​p.clean (tweet_text)


Out [4]: ​"Un retweet di esempio con un URL"

12.13 API TWITTER STREAMING


L'API Streaming gratuita di Twitter invia alla tua app tweet selezionati casualmente in modo dinamico come
si verificano, fino a un massimo dell'uno percento dei tweet al giorno. Secondo
InternetLiveStats.com, ci sono circa 6000 tweet al secondo, ovvero
3
oltre 500 milioni di tweet al giorno. Quindi l'API di streaming ti dà accesso a circa
cinque milioni di tweet al giorno. Twitter consentiva l'accesso gratuito al 10% dei tweet in streaming,
ma questo servizio - chiamato manichetta antincendio - è ora disponibile solo come servizio a pagamento. In questo
sezione, useremo una definizione di classe e una sessione IPython per eseguire i passaggi per
elaborazione di tweet in streaming. Nota che il codice per ricevere un flusso di tweet richiede
creando una classe personalizzata che eredita da un'altra classe. Questi argomenti sono trattati in
capitolo 10 .

3
ttp: //www.internetlivestats.com/twitterstatistics/ .

12.13.1 Creazione di una sottoclasse di StreamListener

L'API di streaming restituisce i tweet nel momento in cui si verificano che corrispondono ai criteri di ricerca. Piuttosto
piuttosto che connettersi a Twitter su ogni chiamata al metodo, uno stream utilizza una connessione persistente a
spingere (cioè inviare) tweet alla tua app. La velocità con cui arrivano questi tweet varia
tremendamente, in base ai criteri di ricerca. Più un argomento è popolare, più è probabile
è che i tweet arriveranno rapidamente.

Si crea una sottoclasse della classe StreamListener di Tweepy per elaborare il flusso di tweet.
Un oggetto di questa classe è l' ascoltatore che riceve una notifica quando ogni nuovo tweet (o altro

4
hC
2

4 Pagina 528
messaggio inviato da Twitter) arriva. Ogni messaggio che Twitter invia risultati in una chiamata a un
Metodo StreamListener. La tabella seguente riassume diversi di questi metodi.
StreamListener definisce già ogni metodo, quindi ridefinisci solo i metodi
bisogno: questo è noto come override . Per ulteriori metodi StreamListener, vedere:

4
Per i dettagli sui messaggi, vedere
ttps: //developer.twitter.com/en/docs/tweets/filterrealtime
guide / streamingmessagetypes.html .

ttps: //github.com/tweepy/tweepy/blob/master/tweepy/streaming.py

Metodo Descrizione

Chiamato quando ti connetti correttamente a Twitter


on_connect (self) ruscello. Questo è per istruzioni che dovrebbero essere eseguite solo se
la tua app è connessa allo stream.

on_status (self, Chiamato quando arriva un tweet: lo stato è un oggetto di


stato) Stato di Tweepy.

Chiamato quando arriva un avviso di limite. Ciò si verifica se il tuo


la ricerca corrisponde a più tweet di quanti Twitter possa fornire
on_limit (self,
in base ai suoi attuali limiti di velocità di streaming. In questo caso,
traccia)
l'avviso di limite contiene il numero di tweet corrispondenti
che non è stato possibile consegnare.

on_error (self,
Chiamato in risposta ai codici di errore inviati da Twitter.
status_code)

Chiamato se la connessione scade, ovvero Twitter


on_timeout (self)
il server non sta rispondendo.

Chiamato se Twitter invia un avviso di disconnessione per indicare

m
2/h

Pagina 529
che la connessione potrebbe essere chiusa. Per esempio,
Twitter mantiene una coda dei tweet a cui sta spingendo
on_warning (self,
la tua app. Se l'app non legge i tweet abbastanza velocemente,
Avviso)
L'argomento di avviso di on_warning conterrà un avviso
messaggio che indica che la connessione verrà terminata se
la coda si riempie.

Classe TweetListener

La nostra sottoclasse StreamListener TweetListener è definita in tweetlistener.py. Noi


discuti i componenti di TweetListener qui. La riga 6 indica quella classe

TweetListener è una sottoclasse di tweepy.StreamListener. Ciò garantisce che il nostro nuovo file
class ha le implementazioni del metodo predefinito della classe StreamListener.

lecca qui per visualizzare l'immagine del codice

1 # tweetlistener.py
2 "" "sottoclasse tweepy.StreamListener che elabora i tweet non appena arrivano." "
3 importazione tweepy
4 da textblob importa TextBlob
5
6 classi TweetListener (tweepy.StreamListener):
7 "" "Gestisce il flusso di Tweet in arrivo." ""
8

Classe TweetListener: metodo __init__

Le righe seguenti definiscono il metodo __init__ della classe TweetListener, che viene chiamato
quando crei un nuovo oggetto TweetListener. Il parametro api è l'API Tweepy
oggetto che TweetListener utilizzerà per interagire con Twitter. Il parametro limite è
il numero totale di tweet da elaborare, 10 per impostazione predefinita. Abbiamo aggiunto questo parametro per abilitare
per controllare il numero di tweet da ricevere. Come vedrai presto, terminiamo lo stream
quando viene raggiunto tale limite. Se imposti il ​limite su Nessuno, il flusso non verrà terminato
automaticamente. La riga 11 crea una variabile di istanza per tenere traccia del numero di tweet
elaborato finora e la riga 12 crea una costante per memorizzare il limite. Se non hai familiarità
con __init__ e super () dei capitoli precedenti, la riga 13 assicura che l'oggetto api
viene memorizzato correttamente per essere utilizzato dall'oggetto listener.

lecca qui per visualizzare l'immagine del codice

C
Pagina 530
9 def __init __ (self, api, limit = 10 ):
10 "" "Crea variabili di istanza per tenere traccia del numero di tweet." ""
11 self.tweet_count = 0
12 self.TWEET_LIMIT = limite
13 super () .__ init __ (api) # chiama l'init della superclasse
14

Classe TweetListener: metodo on_connect

Il metodo on_connect viene chiamato quando la tua app si connette correttamente allo stream di Twitter.
Sostituiamo l'implementazione predefinita per visualizzare un messaggio "Connessione riuscita".

lecca qui per visualizzare l'immagine del codice

15 def on_connect (self):


16 "" "Chiamato quando il tentativo di connessione ha esito positivo, abilitazione
17 di eseguire le attività dell'applicazione appropriate a quel punto. "" "
18 print ( "Connessione riuscita \ n" )
19
Classe TweetListener: metodo on_status

Il metodo on_status viene chiamato da Tweepy quando arriva ogni tweet. Questo è il secondo metodo
riceve un oggetto Tweepy Status che rappresenta il tweet. Le righe 23-26 ottengono l'estensione
testo del tweet. Innanzitutto, supponiamo che il tweet utilizzi il nuovo limite di 280 caratteri, quindi proviamo a farlo
accedi alla proprietà extended_tweet del tweet e ottieni il suo full_text. Un'eccezione lo farà
si verifica se il tweet non ha una proprietà extended_tweet. In questo caso, otteniamo il file

proprietà text invece. Le righe 28–30 quindi visualizzano il nome_schermo dell'utente che ha inviato
il tweet, il lang (cioè la lingua) del tweet e il tweet_text. Se la lingua è
non inglese ('en'), le righe 32-33 usano un TextBlob per tradurre il tweet e visualizzarlo in
Inglese. Incrementiamo self.tweet_count (riga 36), quindi lo confrontiamo con

self.TWEET_LIMIT nell'istruzione return. Se on_status restituisce True, il flusso


rimane aperto. Quando on_status restituisce False, Tweepy si disconnette dal flusso.

lecca qui per visualizzare l'immagine del codice

20 def on_status (self, status):


21 "" "Chiamato quando Twitter ti invia un nuovo tweet." ""
22 # ottieni il testo del tweet
23 prova :
24 tweet_text = status.extended_tweet.full_text
25 tranne :
26 tweet_text = status.text

27
Pagina 531
28 print (f 'Screen name: {status.user.screen_name} :' )
29 print (f 'Lingua: {status.lang} ' )
30 print (f 'Stato: {tweet_text} ' )
31
32 if status.lang! = 'En' :
33 print (f 'Tradotto: {TextBlob (tweet_text) .translate ()} ' )
34
35 stampa ()
36 self.tweet_count + = 1 # numero di traccia dei tweet elaborati
37
38 # se viene raggiunto TWEET_LIMIT, restituisci False per terminare lo streaming
39 return self.tweet_count! = Self. TWEET_LIMIT

2.13.2 Avvio dell'elaborazione del flusso

Usiamo una sessione IPython per testare il nostro nuovo TweetListener.

Autenticazione

Innanzitutto, devi autenticarti con Twitter e creare un oggetto API Tweepy:

lecca qui per visualizzare l'immagine del codice

In [1]: import tweepy

In [2]: importare le chiavi

In [3]: auth = tweepy.OAuthHandler (keys.consumer_key,


...: keys.consumer_secret)
...:

In [4]: ​auth.set_access_token (keys.access_token,


...: keys.access_token_secret)
...:

In [5]: api = tweepy.API (auth, wait_on_rate_limit = True ,


...: wait_on_rate_limit_notify = True )
...:
Creazione di un TweetListener

Successivamente, crea un oggetto della classe TweetListener e inizializzalo con l'oggetto api:

lecca qui per visualizzare l'immagine del codice

In [6]: from tweetlistener import TweetListener

1
C

In [7]: tweet_listener = TweetListener (api)


Pagina 532

Non abbiamo specificato l'argomento limite, quindi questo TweetListener termina dopo 10
tweets.

Creazione di uno stream

Un oggetto Tweepy Stream gestisce la connessione allo stream di Twitter e passa il file
messaggi al tuo TweetListener. L'argomento della parola chiave auth del costruttore Stream
riceve la proprietà auth dell'oggetto api, che contiene il file precedentemente configurato

Oggetto OAuthHandler. L'argomento della parola chiave listener riceve il tuo oggetto listener:

lecca qui per visualizzare l'immagine del codice

In [8]: tweet_stream = tweepy.Stream (auth = api.auth,


...: listener = tweet_listener)
...:

Avvio del Tweet Stream

Il metodo di filtro dell'oggetto Stream avvia il processo di streaming. Tracciamo i tweet


sui rover della NASA su Marte. Qui, usiamo il parametro track per passare un elenco di ricerche
termini:

lecca qui per visualizzare l'immagine del codice

In [9]: tweet_stream.filter (track = [ 'Mars Rover' ], is_async = True )

L'API di streaming restituirà gli oggetti JSON tweet completi per i tweet che corrispondono a uno qualsiasi dei file
termini, non solo nel testo del tweet, ma anche in @menzioni, hashtag, URL espansi e
altre informazioni che Twitter conserva nel JSON di un oggetto tweet. Quindi potresti non vedere
i termini di ricerca che stai monitorando se guardi solo il testo del tweet.

Flussi asincroni e sincroni

L'argomento is_async = True indica che il filtro dovrebbe avviare un processo asincrono
tweet stream . Ciò consente al codice di continuare l'esecuzione mentre l'ascoltatore attende
ricevere tweet ed è utile se decidi di terminare lo streaming in anticipo. Quando esegui
un flusso di tweet asincrono in IPython, vedrai il prossimo prompt In [] e can
terminare il flusso di tweet impostando la proprietà running dell'oggetto Stream su False,
come in:

C
Pagina 533
tweet_stream.running = False

Senza l'argomento is_async = True, il filtro avvia un tweet sincrono


ruscello . In questo caso, IPython visualizzerà il successivo prompt In [] dopo lo stream
termina. I flussi asincroni sono particolarmente utili nelle applicazioni GUI, quindi il tuo file
gli utenti possono continuare a interagire con altre parti dell'applicazione mentre arrivano i tweet. Il
di seguito viene mostrata una porzione dell'output composta da due tweet:

lecca qui per visualizzare l'immagine del codice

Connessione riuscita

Nome schermo: bevjoy:


Lingua: en
Stato: RT @SPACEdotcom: With Mars Dust Storm Clearing, Opportunity R ver Coul

creen name: tourmaline1973:


Lingua: en
Stato: RT @BennuBirdy: Il nostro amato rover su Marte non è ancora pronto, ma è urgente

..

Altri parametri del metodo di filtro

Il filtro del metodo ha anche parametri per perfezionare le tue ricerche di tweet in base all'ID utente di Twitter
numeri (per seguire i tweet di utenti specifici) e per posizione. Per i dettagli, vedere:

ttps: //developer.twitter.com/en/docs/tweets/filterrealtime/guides/basicstream
arametri

Nota sulle limitazioni di Twitter

Gli esperti di marketing, i ricercatori e altri archiviano frequentemente i tweet ricevuti dallo streaming
API. Se stai archiviando i tweet, Twitter ti richiede di eliminare qualsiasi messaggio o dato sulla posizione
per cui ricevi un messaggio di cancellazione. Ciò si verificherà se un utente elimina un tweet o il file
twitta i dati sulla posizione dopo che Twitter ti ha inviato il tweet. In ogni caso, il tuo ascoltatore
Verrà chiamato il metodo on_delete . Per le regole di eliminazione e i dettagli del messaggio, vedere

ttps: //developer.twitter.com/en/docs/tweets/filterrealtime/guides/streamin messaggio

2.14 ANALISI DI TWEET SENTIMENT


1hph.SC
Pagina 534
Nel " atural Language Processing (NLP) ”, abbiamo dimostrato l'analisi del sentiment
sulle frasi. Molti ricercatori e aziende eseguono analisi del sentiment sui tweet. Per
Ad esempio, i ricercatori politici potrebbero controllare il sentimento dei tweet durante la stagione delle elezioni per
capire come le persone si sentono su politici e problemi specifici. Le aziende potrebbero controllare
twittare il sentimento per vedere cosa dicono le persone sui loro prodotti e sui concorrenti
prodotti.

In questa sezione, utilizzeremo le tecniche introdotte nella sezione precedente per creare un file
script (sentimentlistener.py) che ti consente di controllare il sentiment su uno specifico
argomento. Lo script manterrà i totali di tutti i tweet positivi, neutri e negativi che elabora
e visualizzare i risultati.

Lo script riceve due argomenti della riga di comando che rappresentano l'argomento del tweet
desidera ricevere e il numero di tweet di cui controllare il sentimento, solo quelli
i tweet non eliminati vengono conteggiati. Per gli argomenti virali, ci sono un gran numero di
retweet, che non stiamo contando, quindi potrebbe volerci del tempo per ottenere il numero di tweet
si specifica. È possibile eseguire lo script dalla cartella ch12 come segue:

lecca qui per visualizzare l'immagine del codice


ipython sentimentlistener.py football 10

che produce output come il seguente. I tweet positivi sono preceduti da un +, negativo
tweet da uno e tweet neutri da uno spazio:

lecca qui per visualizzare l'immagine del codice

ftblNeutral: terribile partita di calcio. Così noioso lento hoofball completo spreco di un

+ TBulmer28: Ho visto 2 calci in-gioco riusciti in un arco di 40 minuti. Amo co

+ CMayADay12: L'ultima domenica normale per i prossimi due mesi. Non mandarmi messaggi di testo, don '

rpimusic: Il mio cuore fa male legittimamente per i tifosi del Kansas

+ DSCunningham30: @LeahShieldsWPSD È fantastico che ti piaccia il football universitario, ma il mio

damanr: Sono dispiaciuto di non sapere abbastanza di calcio per arrostire @samesfandiari pro

+ jamesianosborne: @TheRochaSays @WatfordFC @JackHind Haha .... proprio quando pensi

+ Tshanerbeer: @PennStateFball @PennStateOnBTN Ah sì, bentornato college footbal

cougarhokie: @hokiehack @skiptyler posso verificare la cattiveria di quel calcio

N
C
Pagina 535
+ Unite_Reddevils: @Pablo_di_Don Be ', chiarisci che è il calcio non il calcio

Tweet sentiment per "football"


Positivo: 6
Neutro: 2
Negativo: 2

Lo script (sentimentlistener.py) è presentato di seguito. Ci concentriamo solo sul nuovo


capacità in questo esempio.

Importazioni

Le righe 4-8 importano il file keys.py e le librerie utilizzate in tutto lo script:

lecca qui per visualizzare l'immagine del codice

1 # sentimentlisener.py
2 "" "Script che ricerca i tweet che corrispondono a una stringa di ricerca
3 e calcola il numero di tweet positivi, neutri e negativi. "" "
4 chiavi di importazione
5 importa il preprocessore come p
6 import sys
7 da textblob importa TextBlob
8 import tweepy
9

Classe SentimentListener: metodo __init__

Oltre all'oggetto API che interagisce con Twitter, riceve il metodo __init__
tre parametri aggiuntivi:

sentiment_dict: un dizionario in cui terremo traccia dei sentimenti dei tweet,

argomento: l'argomento che stiamo cercando in modo da assicurarci che venga visualizzato nel testo del tweet
e
limite: il numero di tweet da elaborare (esclusi quelli che eliminiamo).

Ognuno di questi è archiviato nell'oggetto SentimentListener corrente (self).

lecca qui per visualizzare l'immagine del codice

10 classi SentimentListener (tweepy.StreamListener):


11 "" "Gestisce il flusso di Tweet in arrivo." ""

T
C

12
Pagina 536
13 def __init __ (self, api, sentiment_dict, topic, limit = 10 ):
14 "" "Configura SentimentListener." ""
15 self.sentiment_dict = sentiment_dict
16 self.tweet_count = 0
17 self.topic = topic
18 auto. TWEET_LIMIT = limite
19
20 # imposta tweetpreprocessor per rimuovere URL / parole riservate
21 p.set_options ( p.OPT.URL , p.OPT.RESERVED )
22 super () .__ init __ (api) # chiama l'init della superclasse
23

Metodo on_status

Quando viene ricevuto un tweet, il metodo on_status:

ottiene il testo del tweet (righe 27-30)

salta il tweet se è un retweet (righe 33-34)

pulisce il tweet per rimuovere URL e parole riservate come RT e FAV (riga 36)

salta il tweet se non ha l'argomento nel testo del tweet (righe 39-40)

usa un TextBlob per controllare il sentiment del tweet e aggiorna sentiment_dict


di conseguenza (righe 43-52)

stampa il testo del tweet (riga 55) preceduto da + per sentimento positivo, spazio per neutro
sentiment o per sentiment negativo e

controlla se abbiamo già elaborato il numero specificato di tweet (righe 57–60).

lecca qui per visualizzare l'immagine del codice

24 def on_status (self, status):


25 "" "Chiamato quando Twitter ti invia un nuovo tweet." ""
26 # ottieni il testo del tweet
27 prova :
28 tweet_text = status.extended_tweet.full_text
29 tranne :
30 tweet_text = status.text
31
32 # ignora i retweet
33 se tweet_text.startswith ( 'RT' ):
34 ritorno
35
36 tweet_text = p.clean (tweet_text) # pulisce il tweet

37
Pagina 537
38 # ignora il tweet se l'argomento non è nel testo del tweet
39 se self.topic.lower () non in tweet_text.lower ():
40 ritorno
41
42 # aggiorna self.sentiment_dict con la polarità
43 blob = TextBlob (tweet_text)
44 se blob.sentiment.polarity> 0 :
45 sentimento = '+'
46 self.sentiment_dict [ 'positivo' ] + = 1
47 elif blob.sentiment.polarity == 0:
48 sentimento = ''
49 self.sentiment_dict [ 'neutral' ] + = 1
50 altri :
51 sentimento = ''
52 self.sentiment_dict [ 'negative' ] + = 1
53
54 # visualizza il tweet
55 print (f ' {sentiment} {status.user.screen_name}: {tweet_text} \ n' )
56
57 self.tweet_count + = 1 # numero di traccia dei tweet elaborati
58
59 # se viene raggiunto TWEET_LIMIT, restituisci False per terminare lo streaming
60 return self.tweet_count! = Self.TWEET_LIMIT
61

ain Application

L'applicazione principale è definita nella funzione main (righe 62-87; discussa dopo
codice seguente), che viene chiamato dalle righe 90–91 quando eseguite il file come script. Così
sentimentlistener.py può essere importato in IPython o altri moduli per utilizzare class
SentimentListener come abbiamo fatto con TweetListener nella sezione precedente:

lecca qui per visualizzare l'immagine del codice

62 def main ():


63 # configura OAuthHandler
64 auth = tweepy.OAuthHandler (keys.consumer_key, keys.consumer_secret)
65 auth.set_access_token (keys.access_token, keys.access_token_secret)
66
67 # ottieni l'oggetto API
68 api = tweepy.API (auth, wait_on_rate_limit = True ,
69 wait_on_rate_limit_notify = True )
70
71 # crea l'oggetto della sottoclasse StreamListener
72 search_key = sys.argv [ 1 ]
73 limit = int (sys.argv [ 2 ]) # numero di tweet da conteggiare
74 sentiment_dict = { 'positive' : 0 , 'neutral' : 0 , 'negative' : 0 }
75 sentiment_listener = SentimentListener (api,
76 sentiment_dict, search_key, limit)

M
C

77
Pagina 538
78 # imposta Stream
79 stream = tweepy.Stream (auth = api.auth, listener = sentiment_listener)
80
81 # inizia a filtrare i tweet inglesi contenenti search_key
82 stream.filter (track = [search_key], languages ​= [ 'en' ], is_async = False )
83
84 print (f 'Tweet sentiment for " {search_key} "' )
85 print ( 'Positive:' , sentiment_dict [ 'positive' ])
86 print ( 'Neutral:' , sentiment_dict [ 'neutral' ])
87 print ( 'Negative:' , sentiment_dict [ 'negative' ])
88
89 # chiama main se questo file viene eseguito come uno script
90 if __name__ == '__main__' :
91 principale ()

ines 72–73 ottiene gli argomenti della riga di comando. La riga 74 crea il sentiment_dict
dizionario che tiene traccia dei sentimenti del tweet. Le righe 75-76 creano il file
SentimentListener. La riga 79 crea l'oggetto Stream. Ancora una volta iniziamo il
stream chiamando il filtro del metodo Stream (riga 82). Tuttavia, questo esempio utilizza un file
flusso sincrono in modo che le righe 84-87 visualizzino il rapporto sul sentiment solo dopo il
numero specificato di tweet (limite) vengono elaborati. In questa chiamata al filtro, anche noi
fornito l'argomento della parola chiave lingue, che specifica un elenco di codici di lingua. Il
un codice lingua "en" indica che Twitter deve restituire solo tweet in lingua inglese.

12.15 GEOCODIFICA E MAPPATURA


In questa sezione, raccoglieremo i tweet in streaming, quindi tracciamo le posizioni di quei tweet. Maggior parte
i tweet non includono le coordinate di latitudine e longitudine, perché Twitter lo disabilita per
predefinito per tutti gli utenti. Chi desidera includere la propria posizione precisa nei tweet deve optare
in quella caratteristica. Sebbene la maggior parte dei tweet non includa informazioni precise sulla posizione, una grande
la percentuale include le informazioni sulla posizione dell'abitazione dell'utente; tuttavia, anche quella a volte lo è
non valido, come "Lontano" o una posizione fittizia del film preferito di un utente.

In questa sezione, per semplicità, useremo la proprietà location dell'oggetto User del tweet
per tracciare la posizione dell'utente su una mappa interattiva. La mappa ti consentirà di ingrandire e rimpicciolire
e trascina per spostare la mappa in modo da poter guardare in diverse aree (noto come panoramica ).
Per ogni tweet, visualizzeremo un indicatore di mappa su cui puoi fare clic per vedere un popup contenente
il nome della schermata dell'utente e il testo del tweet.

Ignoreremo i retweet e i tweet che non contengono l'argomento di ricerca. Per altri tweet,
monitoreremo la percentuale di tweet con le informazioni sulla posizione. Quando otteniamo la latitudine
e le informazioni sulla longitudine per tali località, monitoreremo anche la percentuale di esse
tweet con dati sulla posizione non validi.
gL eopy Library

Pagina 539
Biblioteca di geopy

Useremo la libreria geopy ( ttps: //github.com/geopy/geopy ) per tradurre


posizioni in coordinate di latitudine e longitudine, note come geocodifica , così possiamo posizionarle
marcatori su una mappa. La libreria supporta dozzine di servizi web di geocodifica, molti dei quali
avere livelli gratuiti o lite. Per questo esempio, utilizzeremo la geocodifica OpenMapQuest
servizio (discusso a breve). Hai installato geopy in ezione 12.6 .

OpenMapQuest Geocoding API

Useremo l'API di geocodifica OpenMapQuest per convertire le località, come Boston, MA


nelle loro latitudini e longitudini, come 42.3602534 e 71.0582912, per tracciare
mappe. OpenMapQuest attualmente consente 15.000 transazioni al mese nel loro livello gratuito.
Per utilizzare il servizio, iscriviti prima a

ttps: //developer.mapquest.com/

Una volta effettuato l'accesso, vai a

ttps: //developer.mapquest.com/user/me/apps

e fai clic su Crea una nuova chiave, compila il campo Nome app con un nome a tua scelta,
lasciare vuoto l'URL di richiamata e fare clic su Crea app per creare una chiave API. Quindi fare clic su
il nome della tua app nella pagina web per vedere la tua chiave utente. Nel file keys.py che hai usato
in precedenza nel capitolo, memorizzare la chiave utente sostituendo YourKeyHere nella riga

mapquest_key = ' YourKeyHere '

Come abbiamo fatto in precedenza nel capitolo, importeremo keys.py per accedere a questa chiave.

Libreria Folium e libreria di mappatura JavaScript Leaflet.js

Per le mappe in questo esempio, useremo la libreria folium

ttps: //github.com/pythonvisualization/folium
che utilizza la popolare libreria di mappatura JavaScript Leaflet.js per visualizzare le mappe. Le mappe
che il folium produce vengono salvati come file HTML che puoi visualizzare nel tuo browser web. Per
install folium, esegui il seguente comando:

pip install folium

Mappe da OpenStreetMap.org

hS
h

Pagina 540
Per impostazione predefinita, Leaflet.js utilizza mappe open source da OpenStreetMap.org. Queste mappe sono
5
protetto da copyright dai contributori di OpenStreetMap.org. Per utilizzare queste mappe, richiedono l'estensione
seguente avviso di copyright:

5
ttps: //wiki.osmfoundation.org/wiki/Licence/Licence_and_Legal_FAQ .

lecca qui per visualizzare l'immagine del codice

Dati mappa © Collaboratori di OpenStreetMap

e affermano:

È necessario chiarire che i dati sono disponibili con la licenza Open Database. Questo
può essere ottenuto fornendo un collegamento "Licenza" o "Termini" a cui si collega
ww.openstreetmap.org/copyright o
ww.opendatacommons.org/licenses/odbl .

12.15.1 Recupero e mappatura dei tweet


Sviluppiamo in modo interattivo il codice che traccia le posizioni dei tweet. Useremo funzioni di utilità
dal nostro file tweetutilities.py e dalla classe LocationListener in

locationlistener.py. Spiegheremo i dettagli delle funzioni di utilità e della classe nel file
sezioni successive.

Ottieni l'oggetto API

Come negli altri esempi di streaming, autenticiamoci con Twitter e otteniamo Tweepy
Oggetto API. In questo caso, lo facciamo tramite la funzione di utilità get_API in
tweetutilities.py:

lecca qui per visualizzare l'immagine del codice

In [1]: da tweetutilities importa get_API

In [2]: api = get_API ()

Raccolte richieste da LocationListener

La nostra classe LocationListener richiede due raccolte: un elenco (tweets) per memorizzare il file
tweet che raccogliamo e un dizionario (conteggi) per tenere traccia del numero totale di tweet che raccogliamo
e il numero con dati sulla posizione:

C
2h
w
Pagina 541
lecca qui per visualizzare l'immagine del codice

In [3]: tweets = []
In [4]: ​counts = { 'total_tweets' : 0 , 'locations' : 0 }

Creazione del LocationListener

Per questo esempio, LocationListener raccoglierà 50 tweet sul "calcio":

lecca qui per visualizzare l'immagine del codice

In [5]: from locationlistener import LocationListener

In [6]: location_listener = LocationListener (api, counts_dict = counts,


...: tweets_list = tweets, topic = 'football' , limit = 50 )
...:

LocationListener utilizzerà la nostra funzione di utilità get_tweet_content per estrarre


il nome della schermata, il testo del tweet e la posizione di ogni tweet, colloca i dati in un dizionario.

Configura e avvia il flusso di tweet

Quindi, configuriamo il nostro Stream per cercare i tweet di "calcio" in lingua inglese:

lecca qui per visualizzare l'immagine del codice

In [7]: import tweepy

In [8]: stream = tweepy.Stream (auth = api.auth, listener = location_listener)

In [9]: stream.filter (track = [ 'football' ], languages ​= [ 'en' ], is_async = False

Aspettiamo di ricevere i tweet. Sebbene non li mostriamo qui (per risparmiare spazio), il file
LocationListener mostra il nome dello schermo e il testo di ogni tweet in modo da poter vedere il live
ruscello. Se non ne ricevi (forse perché non è la stagione calcistica), potresti
si desidera digitare Ctrl + C per terminare lo snippet precedente, quindi riprovare con un altro
termine di ricerca.

Visualizzazione delle statistiche sulla posizione

Quando viene visualizzato il successivo prompt In [], possiamo controllare quanti tweet abbiamo elaborato, come
molti avevano località e la percentuale che aveva località:

C
N
Pagina 542
lecca qui per visualizzare l'immagine del codice

In [10]: conta [ "total_tweets" ]


Out [10]: 63

In [11]: counts [ "locations" ]


Uscita [11]: 50

In [12]: print (f ' {counts [ "locations" ] / counts [ "total_tweets" ]: .1 %} ' )


79,4%

In questa particolare esecuzione, il 79,4% dei tweet conteneva dati sulla posizione.

Geocodifica delle posizioni

Ora, usiamo la nostra funzione di utilità get_geocodes da tweetutilities.py a


geocodifica la posizione di ogni tweet memorizzato nell'elenco tweet:

lecca qui per visualizzare l'immagine del codice


In [13]: da tweetutilities importa get_geocodes

In [14]: bad_locations = get_geocodes (tweets)


Ottenere le coordinate per le posizioni dei tweet ...
Servizio OpenMapQuest scaduto. In attesa.
Servizio OpenMapQuest scaduto. In attesa.
Geocodifica eseguita

A volte il servizio di geocodifica OpenMapQuest scade, il che significa che non può
gestisci subito la tua richiesta e devi riprovare. In tal caso, la nostra funzione
get_geocodes visualizza un messaggio, attende un breve periodo, quindi riprova la geocodifica
richiesta.

Come vedrai presto, per ogni tweet con una posizione valida , la funzione get_geocodes aggiunge
al dizionario del tweet nell'elenco dei tweet due nuove chiavi: "latitudine" e

'longitudine'. Per i valori corrispondenti, la funzione utilizza le coordinate del tweet


che OpenMapQuest restituisce.

Visualizzazione delle statistiche di posizione errata

Quando viene visualizzato il successivo prompt In [], possiamo controllare la percentuale di tweet che avevano
dati sulla posizione non validi:

lecca qui per visualizzare l'immagine del codice

C
Pagina 543
In [15]: bad_locations
Fuori [15]: 7

In [16]: print (f ' {bad_locations / counts [ "locations" ]: .1 %} ' )


14,0%

In questo caso, dei 50 tweet con dati sulla posizione, 7 (14%) avevano posizioni non valide.

Pulizia dei dati

Prima di tracciare le posizioni dei tweet su una mappa, usiamo un DataFrame panda per pulire il file
dati. Quando crei un DataFrame dall'elenco dei tweet, conterrà il valore NaN
per la "latitudine" e la "longitudine" di qualsiasi tweet che non aveva una posizione valida.
Possiamo rimuovere tali righe chiamando il metodo dropna di DataFrame :

lecca qui per visualizzare l'immagine del codice

In [17]: importa i panda come pd

In [18]: df = pd.DataFrame (tweets)

In [19]: df = df.dropna ()

Creazione di una mappa con Folium

Ora creiamo una mappa del folium su cui tracciamo le posizioni dei tweet:

lecca qui per visualizzare l'immagine del codice

In [20]: import folium

In [21]: usmap = folium.Map (location = [ 39.8283 , 98.5795 ],


...: tiles = 'Stamen Terrain' ,
...: zoom_start = 5 , detect_retina = True )
...:
L'argomento della parola chiave location specifica una sequenza contenente latitudine e longitudine
coordinate per il punto centrale della mappa. I valori sopra sono il centro geografico di
Stati Uniti continentali ( ttp: //bit.ly/CenterOfTheUS ). È possibile che alcuni
dei tweet che tracciamo saranno fuori dagli Stati Uniti. In questo caso, inizialmente non li vedrai
quando apri la mappa. Puoi ingrandire e rimpicciolire usando i pulsanti + e in alto a sinistra
della mappa, oppure puoi eseguire una panoramica della mappa trascinandola con il mouse per vedere ovunque nel file
mondo.

C
h
Pagina 544
L'argomento della parola chiave zoom_start specifica il livello di zoom iniziale della mappa, i valori inferiori
mostra di più del mondo e i valori più alti mostrano di meno. Sul nostro sistema, 5 visualizza l'intero
Stati Uniti continentali. L'argomento della parola chiave detect_retina abilita folium a
rilevare schermi ad alta risoluzione. Quando lo fa, richiede mappe ad alta risoluzione da
OpenStreetMap.org e modifica il livello di zoom di conseguenza.

Creazione di marcatori popup per le posizioni dei Tweet

Successivamente, iteriamo attraverso il DataFrame e aggiungiamo agli oggetti Popup del folium della mappa
contenente il testo di ogni tweet. In questo caso, useremo il metodo itertuples per creare tuple
da ogni riga del DataFrame. Ogni tupla conterrà una proprietà per ogni DataFrame
colonna:

lecca qui per visualizzare l'immagine del codice

In [22]: for t in df.itertuples ():


...: text = ':' .join ([t.screen_name, t.text])
...: popup = folium.Popup (text, parse_html = True )
...: marker = folium.Marker ((t.latitude, t.longitude),
...: popup = popup)
...: marker.add_to (usmap)
...:

Per prima cosa, creiamo una stringa (testo) contenente screen_name e testo tweet dell'utente
separati da due punti. Questo verrà visualizzato sulla mappa se fai clic sul corrispondente
pennarello. La seconda istruzione crea un Popup folium per visualizzare il testo. Il terzo
L'istruzione crea un oggetto Marker folium utilizzando una tupla per specificare la latitudine del Marker
e longitudine. L'argomento della parola chiave popup associa l'oggetto Popup del tweet con il file
nuovo Marker. Infine, l'ultima istruzione chiama il metodo add_to di Marker per specificare
la mappa che visualizzerà il marker.

Salvataggio della mappa

L'ultimo passo è quello di chiamare il Map Salva metodo per memorizzare la mappa in un file HTML, che si
può quindi fare doppio clic per aprire nel browser web:

lecca qui per visualizzare l'immagine del codice

In [23]: usmap.save ( 'tweet_map.html' )

Segue la mappa risultante. Gli indicatori sulla mappa saranno diversi:

C
Pagina 545
Dati mappa © Collaboratori di OpenStreetMap.

I dati sono disponibili sotto la licenza Open Database

ttp: //www.openstreetmap.org/copyright .

12.15.2 Funzioni di utilità in tweetutilities.py

Qui presentiamo le funzioni di utilità get_tweet_content e get_geo_codes utilizzate


nella sessione IPython della sezione precedente. In ogni caso, i numeri di riga iniziano da 1 per
scopi di discussione. Entrambi sono definiti in tweetutilities.py, che è incluso
nella cartella degli esempi ch12.

Funzione di utilità get_tweet_content

La funzione get_tweet_content riceve un oggetto Status (tweet) e crea un file


dizionario contenente lo screen_name del tweet (riga 4), il testo (righe 7–10) e

posizione (righe 12-13). La località è inclusa solo se la parola chiave località


l'argomento è vero. Per il testo del tweet, proviamo a utilizzare la proprietà full_text di un file
extended_tweet. Se non è disponibile, utilizziamo la proprietà text:

lecca qui per visualizzare l'immagine del codice

1 def get_tweet_content (tweet, location = False ):


2 "" "Restituisce il dizionario con i dati di tweet (un oggetto Status)." ""
3 campi = {}
4 campi [ 'screen_name' ] = tweet.user.screen_name
5
6 # ottieni il testo del tweet
7 prova :
8 campi [ 'text' ] = tweet.extended_tweet.full_text
9 tranne :
10 campi [ 'text' ] = tweet.text

C
h

11
Pagina 546
12 se posizione:
13 campi [ 'location' ] = tweet.user.location
14
15 campi di ritorno

Funzione di utilità get_geocodes

La funzione get_geocodes riceve un elenco di dizionari contenenti tweet e codici geografici


le loro posizioni. Se la geocodifica ha successo per un tweet, la funzione aggiunge la latitudine e
longitudine al dizionario del tweet in tweet_list. Questo codice richiede classe

OpenMapQuest dal modulo geopy, che importiamo nel file


tweetutilities.py come segue:

da geopy importa OpenMapQuest

lecca qui per visualizzare l'immagine del codice

1 def get_geocodes (tweet_list):


2 "" "Ottieni la latitudine e la longitudine per la posizione di ogni tweet.
3 Restituisce il numero di tweet con dati sulla posizione non validi. "" "
4 print ( 'Ottenere le coordinate per le posizioni dei tweet ...' )
5 geo = OpenMapQuest (api_key = keys.mapquest_key) # geocoder
6 bad_locations = 0
7
8 per tweet in tweet_list:
9 elaborato = Falso
10 delay = .1 # usato se OpenMapQuest scade per ritardare il c ll
11 mentre non elaborato:
12 prova : # ottieni le coordinate per tweet ["location"]
13 geo_location = geo.geocode (tweet [ 'location' ])
14 elaborati = vero
15 tranne : # scaduto, quindi attendi prima di riprovare
16 print ( "Servizio OpenMapQuest scaduto. In attesa." )
17 time.sleep (ritardo)
18 ritardo + = .1
19
20 se geo_location:
21 tweet [ 'latitude' ] = geo_location.latitude
22 tweet [ 'longitude' ] = geo_location.longitude
23 altro :
24 bad_locations + = 1 # tweet ["location"] non era valido
25
26 print ("Geocodifica eseguita")
27 return bad_locations

La funzione opera come segue:

C
Pagina 547
La riga 5 crea l'oggetto OpenMapQuest che useremo per geocodificare le posizioni. Il api_key
l'argomento della parola chiave viene caricato dal file keys.py modificato in precedenza.

La riga 6 inizializza bad_locations che usiamo per tenere traccia del numero di invalid
posizioni negli oggetti tweet che abbiamo raccolto.

Nel ciclo, le righe 9-18 tentano di geocodificare la posizione del tweet corrente. A volte il file
Il servizio di geocodifica OpenMapQuest scadrà, il che significa che è temporaneamente
non disponibile. Questo può accadere se fai troppe richieste troppo velocemente. Così la
mentre il ciclo continua l'esecuzione fintanto che processato è False. In ogni iterazione, this
ciclo chiama dell'oggetto OpenMapQuest metodo geocode con la posizione del Tweet
stringa come argomento. In caso di esito positivo, Processato viene impostato su True e il ciclo termina.
Altrimenti, le righe 16-18 visualizzano un messaggio di timeout, aspettano i secondi di ritardo e
aumentare il ritardo nel caso in cui otteniamo un altro timeout. La riga 17 chiama lo standard Python
Metodo di sospensione del modulo Time della libreria per sospendere l'esecuzione del codice.

Dopo che il ciclo while è terminato, le righe 20–24 controllano se i dati sulla posizione erano
restituito e, in tal caso, aggiungerlo al dizionario del tweet. Altrimenti, la riga 24 incrementa il
contatore bad_locations.

Infine, la funzione stampa un messaggio indicante che è stata eseguita la geocodifica e restituisce il file

valore bad_locations.

12.15.3 Class Location Listener

Class LocationListener esegue molte delle stesse attività che abbiamo dimostrato in
esempi di streaming precedenti, quindi ci concentreremo solo su poche righe in questa classe:

lecca qui per visualizzare l'immagine del codice

1 # locationlistener.py
2 "" "Riceve i tweet che corrispondono a una stringa di ricerca e ne memorizza un elenco
3 dizionari contenenti nome_schermo / testo / posizione di ciascun tweet. "" "
4 import tweepy
5 da tweetutilities importa get_tweet_content
6
7 classi LocationListener (tweepy.StreamListener):
8 "" "Gestisce il flusso di Tweet in arrivo per ottenere i dati sulla posizione." ""
9
10 def __init __ (self, api, counts_dict, tweets_list, topic, limit = 10 ):
11 "" "Configura LocationListener." ""
12 self.tweets_list = tweets_list
13 self.counts_dict = counts_dict
14 self.topic = topic
15 self.TWEET_LIMIT = limite

C
Pagina 548
16 super () .__ init __ (api) # chiama l'init della superclasse
17
18 def on_status (self, status):
19 "" "Chiamato quando Twitter ti invia un nuovo tweet." ""
20 # ottieni lo screen_name, il testo e la posizione di ogni tweet
21 tweet_data = get_tweet_content (stato, posizione = True )
22
23 # ignora retweet e tweet che non contengono l'argomento
24 if (tweet_data [ 'text' ] .startswith ( 'RT' ) o
25 self.topic.lower () non in tweet_data [ 'text' ] .lower ()):
26 ritorno
27
28 self.counts_dict [ 'total_tweets' ] + = 1 # tweet originale
29
30 # ignora i tweet senza posizione
31 se non status.user.location:
32 ritorno
33
34 self.counts_dict [ 'locations' ] + = 1 # tweet con la posizione
35 self.tweets_list.append (tweet_data) # memorizza il tweet
36 print (f ' {status.user.screen_name}: {tweet_data [ "text" ]} \ n' )
37
38 # se viene raggiunto TWEET_LIMIT, restituisci False per terminare lo streaming
39 return self.counts_dict [ 'locations' ]! = Self.TWEET_LIMIT

In questo caso, il metodo __init__ riceve un dizionario dei conteggi che usiamo per conservare
traccia del numero totale di tweet elaborati e una tweet_list in cui memorizziamo il file
dizionari restituiti dalla funzione di utilità get_tweet_content.

Metodo on_status:

Chiama get_tweet_content per ottenere il nome della schermata, il testo e la posizione di ogni tweet.

Ignora il tweet se è un retweet o se il testo non include l'argomento che stiamo


ricerca: useremo solo tweet originali contenenti la stringa di ricerca.

Aggiunge 1 al valore della chiave "total_tweets" nel dizionario dei conteggi per tenere traccia del file
numero di tweet originali che elaboriamo.

Ignora i tweet che non hanno dati sulla posizione.

Aggiunge 1 al valore della chiave "posizioni" nel dizionario dei conteggi per indicarlo
abbiamo trovato un tweet con una posizione.

Aggiunge a tweets_list il dizionario tweet_data that


get_tweet_content restituito.

io
Pagina 549
Visualizza il nome dello schermo del tweet e il testo del tweet in modo da poter vedere che l'app sta facendo
progresso.
Verifica se è stato raggiunto TWEET_LIMIT e, in tal caso, restituisce False a
terminare il flusso.

12.16 MODI PER MEMORIZZARE I TWEET


Per l'analisi, di solito archivierai i tweet in:

File CSV: un formato di file introdotto nel capitolo "File ed eccezioni".

panda DataFrame in memoria: i file CSV possono essere caricati facilmente in DataFrame per
pulizia e manipolazione.

Database SQL: come MySQL, un database relazionale gratuito e open source


sistema di gestione (RDBMS).

Database NoSQL: Twitter restituisce i tweet come documenti JSON, quindi il modo naturale per farlo
memorizzarli è in un database di documenti JSON NoSQL, come MongoDB. Tweepy
generalmente nasconde il JSON allo sviluppatore. Se desideri manipolare il file JSON
direttamente, utilizza le tecniche che presentiamo nella sezione
ig Dati:
" Hadoop, Spark, NoSQL e
oT ”, dove vedremo la libreria PyMongo.

12.17 TWITTER E SERIE TIME


Una serie temporale è una sequenza di valori con timestamp. Alcuni esempi sono la chiusura giornaliera
prezzi delle azioni, alte temperature giornaliere in un determinato luogo, creazione di posti di lavoro negli Stati Uniti mensili
numeri, guadagni trimestrali per una data azienda e altro ancora. I tweet sono naturali per il tempo
analisi di serie perché sono timbrate. Nel capitolo "Machine Learning", useremo
una tecnica chiamata regressione lineare semplice per fare previsioni con serie temporali. Bene
dai un'altra occhiata alle serie temporali nel capitolo "Deep Learning" quando parliamo di ricorrenti
reti neurali.

12.18 WRAP-UP
In questo capitolo abbiamo esplorato il data mining di Twitter, forse il più aperto e accessibile
tutti i siti di social media e una delle fonti di bigdata più comunemente utilizzate. tu
creato un account sviluppatore Twitter e connesso a Twitter utilizzando il tuo account
credenziali. Abbiamo discusso i limiti di frequenza di Twitter e alcune regole aggiuntive e il
importanza di conformarsi a loro.

B
io
Pagina 550
Abbiamo guardato la rappresentazione JSON di un tweet. Abbiamo usato Tweepy, uno dei più
client API Twitter ampiamente utilizzati, per autenticarsi con Twitter e accedere alle sue API. Vedemmo
che i tweet restituiti dalle API di Twitter contengono molti metadati oltre a quelli di un tweet
testo. Abbiamo determinato i follower di un account e chi segue un account e abbiamo esaminato un file
tweet recenti dell'utente.

Abbiamo utilizzato i cursori Tweepy per richiedere comodamente pagine successive di risultati da
varie API di Twitter. Abbiamo utilizzato l'API di ricerca di Twitter per scaricare i tweet precedenti che si sono incontrati
criteri specificati. Abbiamo utilizzato l'API di streaming di Twitter per attingere al flusso di tweet dal vivo come
sono accaduti. Abbiamo utilizzato l'API Twitter Trends per determinare argomenti di tendenza per vari
posizioni e ha creato una nuvola di parole da argomenti di tendenza.

Abbiamo utilizzato la libreria tweetpreprocessor per pulire e preelaborare i tweet per prepararli
per l'analisi e ha eseguito l'analisi del sentiment sui tweet. Abbiamo usato la libreria folium per
creare una mappa delle posizioni dei tweet e interagire con essa per vedere i tweet in particolare
posizioni. Abbiamo elencato modi comuni per archiviare i tweet e abbiamo notato che i tweet sono un file
forma naturale di dati di serie temporali. Nel prossimo capitolo, presenteremo IBM Watson e il suo
capacità di calcolo cognitivo.

https://avxhm.se/blogs/hill0
W
Pagina 551

laylist

13. IBM Watson e Cognitive Computing


storia

Obiettivi
opiche

In questo capitolo potrai:


guadagnando Pat

Guarda la gamma di servizi di Watson e utilizza il loro livello Lite per familiarizzare con loro su
ffers & Dea
nessun addebito.

ighlights
Prova molte demo dei servizi Watson.

ettingsComprendi cos'è il cognitive computing e come puoi incorporarlo nel tuo file
applicazioni.
Supporto

Registrati per un account IBM Cloud e ottieni le credenziali per utilizzare vari servizi.
Disconnessione

Installa Watson Developer Cloud Python SDK per interagire con i servizi Watson.

Sviluppa un'app di traduzione in lingua complementare di un viaggiatore utilizzando Python per tessere
insieme un mashup di Watson Speech to Text, Language Translator e Text to
Servizi vocali.

Dai un'occhiata a risorse aggiuntive, come IBM Watson Redbooks che ti aiuteranno
avvia immediatamente lo sviluppo di applicazioni Watson personalizzate.

Contorno
13.1 Introduzione: IBM Watson e Cognitive Computing

13.2 Account IBM Cloud e Cloud Console

13.3 Servizi Watson

13.4 Servizi e strumenti aggiuntivi

Pagina 552
3.5 Watson Developer Cloud Python SDK

3.6 Case Study: App di traduzione di Traveler's Companion

3.6.1 Prima di eseguire l'app

3.6.2 TestDriving dell'App

3.6.3 Procedura dettagliata dello script SimpleLanguageTranslator.py

3.7 Risorse Watson

3.8 WrapUp

13.1 INTRODUZIONE: IBM WATSON E COGNITIVE


COMPUTING
Nel nel capitolo 1 , abbiamo discusso alcuni risultati chiave dell'intelligenza artificiale IBM,
incluso battere i due migliori umani Jeopardy! giocatori in una partita da $ 1 milione. Watson
ha vinto il concorso e IBM ha donato il premio in denaro in beneficenza. Watson
ha eseguito contemporaneamente centinaia di algoritmi di analisi delle lingue per individuare il corretto
risposte in 200 milioni di pagine di contenuto (inclusa tutta Wikipedia) che richiedono quattro
1 ,2
terabyte di spazio di archiviazione.I ricercatori IBM hanno formato Watson utilizzando l'apprendimento automatico e
3
tecniche di rinforzo dell'apprendimento: discuteremo dell'apprendimento automatico nel prossimo capitolo.

1
ttps: //www.techrepublic.com/article/ibmwatsontheinside
storia di come è nato il pericolo che ha vinto il supercomputer e

hatitwantstodonext / .

2
ttps: //en.wikipedia.org/wiki/Watson_ (computer) .

3
ttps: //www.aaai.org/Magazine/Watson/watson.php , AI Magazine , autunno
2010.

All'inizio della nostra ricerca per questo libro, abbiamo riconosciuto l'importanza in rapida crescita di
Watson, quindi abbiamo inserito Google Alert su Watson e argomenti correlati. Attraverso quegli avvisi
e le newsletter e i blog che seguiamo, abbiamo accumulato oltre 900 attuali Watson correlati
articoli, pezzi di documentazione e video. Abbiamo studiato molti servizi competitivi
4
e ha trovato Watson “nessuna carta di credito richiesto” la politica e libero tier Lite servizi siano
tra i più cordiali con le persone che vorrebbero sperimentare con i servizi di Watson al n

1w
hC
Pagina 553
Harge.

4
Controllare sempre i termini più recenti sul sito Web di IBM poiché i termini e i servizi potrebbero cambiare.
IBM Watson è una piattaforma di elaborazione cognitiva basata su cloud utilizzata in un file
ampia gamma di scenari del mondo reale. I sistemi di elaborazione cognitiva simulano il pattern
capacità di riconoscimento e decisionali del cervello umano per "apprendere" come loro
5 , 6, 7
consumare più dati. Analizziamo l'ampia gamma di servizi Web e
fornire un trattamento manuale Watson, dimostrando molte capacità di Watson. Il
la tabella nella pagina successiva mostra solo alcuni dei modi in cui le organizzazioni stanno utilizzando
Watson.

5
TTP: //whatis.techtarget.com/definition/cognitivecomputing .

6
ttps: //en.wikipedia.org/wiki/Cognitive_computing .

7
ttps: //www.forbes.com/sites/bernardmarr/2016/03/23/ what
veryoneshouldknowaboutcognitivecomputing .

Watson offre un insieme intrigante di funzionalità che puoi incorporare nel tuo file
8
applicazioni. In questo capitolo, configurerai un account IBM Cloud e utilizzerai il livello Lite
e le demo Watson di IBM per sperimentare vari servizi web, come naturale
traduzione della lingua, speechtotext, texttospeech, comprensione del linguaggio naturale,
chatbot, che analizzano il testo per il riconoscimento del tono e degli oggetti visivi in ​immagini e video.
Faremo una breve panoramica di alcuni servizi e strumenti Watson aggiuntivi.

8
IBM Cloud in precedenza si chiamava Bluemix. Vedrai ancora bluemix in molti di questi
URL del capitolo.

Casi d'uso di Watson

targeting degli annunci


prevenzione frodi

assistenti personali
artificiale
gioco
intelligenza
manutenzione predittiva
genetica
aumentata
Prodotto
intelligenza assistenza sanitaria raccomandazioni

realtà aumentata elaborazione delle immagini

ech
Pagina 554
chatbot robot e droni
IoT (Internet of Things)
sottotitoli auto a guida autonoma
traduzione in lingua
cognitivo sentimento e umore
informatica apprendimento automatico analisi

colloquiale rilevamento di malware case intelligenti


interfacce
diagnosi medica e gli sport
prevenzione del crimine trattamento
catena di fornitura
Servizio Clienti imaging medico gestione

rilevamento musica rilevamento delle minacce


cyber bullismo
linguaggio naturale realta virtuale
sviluppo di farmaci in lavorazione
analisi vocale
formazione scolastica linguaggio naturale
comprensione previsioni del tempo
riconoscimento facciale
riconoscimento di oggetti sicurezza sul lavoro
finanza

Installerai il Watson Developer Cloud Python Software Development Kit (SDK) per
accesso programmatico ai servizi Watson dal tuo codice Python. Quindi, nelle nostre mani
caso di studio di implementazione, svilupperai un'app di traduzione complementare di un viaggiatore da
riunendo rapidamente e comodamente diversi servizi Watson. L'app abilita
Solo parlanti inglese e spagnolo per comunicare verbalmente tra loro,
nonostante la barriera linguistica. Trascriverete le registrazioni audio in inglese e spagnolo a
text, traduci il testo nell'altra lingua, quindi sintetizza e riproduci in inglese e
Audio spagnolo dal testo tradotto.

Watson è un insieme di funzionalità dinamiche e in evoluzione. Durante il tempo abbiamo lavorato su questo
book, sono stati aggiunti nuovi servizi e quelli esistenti sono stati aggiornati e / o rimossi
più volte. Le descrizioni dei servizi Watson e i passaggi che presentiamo erano
accurato al momento della stesura di questo documento. Se necessario, pubblicheremo gli aggiornamenti sul libro
pagina web all'indirizzo
ww.deitel.com .

1w 3.2 ACCOUNT IBM CLOUD E CONSOLE CLOUD


Pagina 555
3.2 ACCOUNT IBM CLOUD E CONSOLE CLOUD
Avrai bisogno di un account IBM Cloud gratuito per accedere ai servizi di livello Lite di Watson. Ogni
La pagina Web di descrizione del servizio elenca le offerte a più livelli del servizio e ciò che ottieni
ogni livello. Sebbene i servizi di livello Lite limitino il tuo utilizzo, in genere offrono ciò che offrirai
è necessario acquisire familiarità con le funzionalità di Watson e iniziare a utilizzarle per lo sviluppo
app. I limiti sono soggetti a modifiche, quindi invece di elencarli qui, ti indichiamo
pagina web di ogni servizio. IBM ha aumentato i limiti in modo significativo su alcuni servizi mentre
stavamo scrivendo questo libro. I livelli a pagamento sono disponibili per l'uso in Commercialgrade
applicazioni.

Per ottenere un account IBM Cloud gratuito, segui le istruzioni su:

ttps: //console.bluemix.net/docs/services/watson/index.html#about

Riceverai una mail. Segui le sue istruzioni per confermare il tuo account. Allora puoi
accedi alla console IBM Cloud. Una volta lì, puoi andare alla dashboard di Watson all'indirizzo:

ttps: //console.bluemix.net/developer/watson/dashboard

dove puoi:

Sfoglia i servizi Watson.

Link ai servizi che ti sei già registrato per utilizzare.

Guarda le risorse per sviluppatori, inclusa la documentazione di Watson, gli SDK e


varie risorse per l'apprendimento di Watson.

Visualizza le app che hai creato con Watson.

Successivamente, ti registrerai e otterrai le tue credenziali per utilizzare i vari servizi Watson. tu
può visualizzare e gestire il tuo elenco di servizi e le tue credenziali in IBM Cloud
dashboard in:

ttps: //console.bluemix.net/dashboard/apps

Puoi anche fare clic su Servizi esistenti nella dashboard di Watson per accedere a questo elenco.

13.3 SERVIZI WATSON


Questa sezione offre una panoramica di molti dei servizi di Watson e fornisce collegamenti ai dettagli per

h1
Pagina 556
ach. Assicurati di eseguire le demo per vedere i servizi in azione. Per i collegamenti a ogni Watson
documentazione del servizio e riferimento API, visitare:

ttps: //console.bluemix.net/developer/watson/documentation

Forniamo note a piè di pagina con collegamenti ai dettagli di ciascun servizio. Quando sei pronto per utilizzare un file
particolare servizio, fare clic sul pulsante Crea nella sua pagina dei dettagli per impostare le proprie credenziali.

Watson Assistant
9
Il servizio Watson Assistant ti aiuta a creare chatbot e assistenti virtuali che
consentire agli utenti di interagire tramite testo in linguaggio naturale. IBM fornisce un'interfaccia web che tu
puoi utilizzare per addestrare il servizio Watson Assistant per scenari specifici associati al tuo
app. Ad esempio, un chatbot meteorologico potrebbe essere addestrato a rispondere a domande come,
"Quali sono le previsioni del tempo per New York City?" In uno scenario di servizio clienti, tu
potrebbe creare chatbot che rispondono alle domande dei clienti e indirizzano i clienti a
reparto corretto, se necessario. Prova la demo nel seguente sito per vedere alcuni esempi
interazioni:

9
ttps: //console.bluemix.net/catalog/services/watsonassistant
ormerlyconversation .

ttps: //www.ibm.com/watson/services/conversation/demo/index.html#demo

Riconoscimento visivo
0
Il servizio di riconoscimento visivo consente alle app di individuare e comprendere
informazioni in immagini e video, inclusi colori, oggetti, volti, testo, cibo e
contenuto inappropriato. IBM fornisce modelli predefiniti (utilizzati nella demo del servizio) o
puoi allenarti e usare il tuo (come farai nel capitolo "Deep Learning"). Prova il
segui la demo con le immagini fornite e carica alcune delle tue:

0
ttps: //console.bluemix.net/catalog/services/visual
riconoscimento .

ttps: //watsonvisualrecognitionduodev.ng.bluemix.net/

Discorso al testo
1
Il servizio Speech to Text , che useremo per creare l'app di questo capitolo, converte
file audio vocali in trascrizioni testuali dell'audio. Puoi fornire le parole chiave del servizio
per "ascoltare", e ti dice se li ha trovati, qual è la probabilità di una corrispondenza

erf
1h

Pagina 557
come e dove si è verificata la corrispondenza nell'audio. Il servizio può distinguere tra
più altoparlanti. Puoi utilizzare questo servizio per implementare app con controllo vocale,
trascrivi audio dal vivo e altro ancora. Prova la seguente demo con i suoi clip audio di esempio o
carica il tuo:

1
TTP: //console.bluemix.net/catalog/services/speechtotext .

ttps: //speechtotextdemo.ng.bluemix.net/

Text to Speech
2
Il servizio Text to Speech , che useremo anche per creare l'app di questo capitolo,
consente di sintetizzare il parlato dal testo. Puoi utilizzare il markup della sintesi vocale
Linguaggio (SSML) per incorporare le istruzioni nel testo per il controllo sull'inflessione vocale,
cadenza, altezza e altro. Attualmente, questo servizio supporta l'inglese (USA e Regno Unito),
Francese, tedesco, italiano, spagnolo, portoghese e giapponese. Prova la seguente demo
con il suo testo di esempio semplice, il suo testo di esempio che include SSML e il testo che fornisci:

2
TTP: //console.bluemix.net/catalog/services/texttospeech .

ttps: //texttospeechdemo.ng.bluemix.net/

Traduttore
3
Il servizio Language Translator , che useremo anche nella creazione di questo capitolo
app, ha due componenti chiave:

3
ttps: //console.bluemix.net/catalog/services/language

traduttore .

traduzione di testi tra lingue e

identificare il testo come scritto in una delle oltre 60 lingue.

La traduzione è supportata da e verso l'inglese e molte lingue, nonché tra


altre lingue. Prova a tradurre il testo in varie lingue con la seguente demo:

ttps: //languagetranslatordemo.ng.bluemix.net/

Comprensione del linguaggio naturale


4
Il servizio di comprensione del linguaggio naturale analizza il testo e produce

hw
1t

Pagina 558
nformazioni che includono il sentimento e l'emozione complessivi del testo e le parole chiave classificate
dalla loro rilevanza. Tra le altre cose, il servizio può identificare

4
ttps: //console.bluemix.net/catalog/services/naturallanguage
intendere .

persone, luoghi, titoli di lavoro, organizzazioni, aziende e quantità.

categorie e concetti come sport, governo e politica.

parti del discorso come soggetti e verbi.

È inoltre possibile addestrare il servizio per settori industriali e domini specifici per applicazioni con
Watson Knowledge Studio (discusso a breve). Prova la seguente demo con il suo campione
testo, con il testo che incolli o fornendo un collegamento a un articolo o documento online:

ttps: //naturallanguageunderstandingdemo.ng.bluemix.net/
Scoperta
5
Il servizio Watson Discovery condivide molte funzionalità con il linguaggio naturale
Comprende il servizio ma consente anche alle aziende di archiviare e gestire i documenti. Così,
ad esempio, le organizzazioni possono utilizzare Watson Discovery per archiviare tutti i loro documenti di testo
ed essere in grado di utilizzare la comprensione del linguaggio naturale nell'intera raccolta. Prova questo
demo del servizio, che ti consente di cercare articoli di notizie recenti per le aziende:

5
ttps: //console.bluemix.net/catalog/services/discovery .

ttps: //discoverynewsdemo.ng.bluemix.net/

Approfondimenti sulla personalità


6
Il servizio Personality Insights analizza il testo per i tratti della personalità. Secondo
la descrizione del servizio, può aiutarti a "ottenere informazioni dettagliate su come e perché le persone pensano, agiscono,
e sentire il modo in cui lo fanno. Questo servizio applica analisi linguistiche e teoria della personalità
per dedurre attributi dal testo non strutturato di una persona. " Queste informazioni potrebbero essere utilizzate per
mirare alla pubblicità dei prodotti presso le persone più propense ad acquistare tali prodotti. Prova il
seguente demo con tweet da vari account Twitter o documenti incorporati nel file
demo, con documenti di testo che incolli nella demo o con il tuo Twitter
account:

6
ttps: //console.bluemix.net/catalog/services/personality

uio
1h

Pagina 559
nsights .

ttps: //personalityinsightslivedemo.ng.bluemix.net/

Tone Analyzer
7
Il servizio Tone Analyzer analizza il testo per il suo tono in tre categorie:

7
TTP: //console.bluemix.net/catalog/services/toneanalyzer .

emozioni: rabbia, disgusto, paura, gioia, tristezza.

propensioni sociali: apertura, coscienziosità, estroversione, gradevolezza e


gamma emotiva.

stile linguistico: analitico, sicuro di sé, provvisorio.

Prova la seguente demo con tweet di esempio, una recensione di un prodotto di esempio, un'e-mail di esempio
o il testo fornito. Vedrai le analisi del tono sia nel documento che nella frase
livelli:

ttps: //toneanalyzerdemo.ng.bluemix.net/

Classificatore del linguaggio naturale


8
Tu formi il servizio Natural Language Classifier con frasi e frasi
specifici per l'applicazione e classificano ogni frase o frase. Per esempio,
potresti classificare "Ho bisogno di aiuto con il tuo prodotto" come "supporto tecnico" e "Il mio conto è
errato "come" fatturazione ". Dopo aver addestrato il classificatore, il servizio può ricevere
frasi e frasi, quindi usa le capacità di calcolo cognitivo di Watson e le tue
classifier per restituire le migliori classificazioni di corrispondenza e le loro probabilità di corrispondenza. tu
potrebbe quindi utilizzare le classificazioni e le probabilità restituite per determinare il successivo
passaggi nella tua app. Ad esempio, in un'app del servizio clienti in cui qualcuno sta chiamando
con una domanda su un particolare prodotto, potresti usare Speech to Text per convertire un file
domanda in testo, usa il servizio Natural Language Classifier per classificare il testo, quindi
instradare la chiamata alla persona o al dipartimento appropriato. Questo servizio non offre a
Livello Lite . Nella demo seguente, inserisci una domanda sul meteo: il servizio lo farà
rispondi indicando se la tua domanda riguardava la temperatura o il tempo
condizioni:

8
ttps: //console.bluemix.net/catalog/services/naturallanguage

1io
h
Pagina 560
lassificatore .

ttps: //naturallanguageclassifierdemo.ng.bluemix.net/

Funzionalità sincrone e asincrone

Molte delle API di cui discutiamo in tutto il libro sono sincrone: quando chiami a
funzione o metodo, il programma attende che la funzione o il metodo ritorni prima
passando all'attività successiva. I programmi asincroni possono avviare un'attività, continuare a farlo
altre cose, quindi ricevere una notifica quando l'attività originale viene completata e restituisce i risultati.
Molti servizi Watson offrono API sia sincrone che asincrone.

La demo di Speech to Text è un buon esempio di API asincrone. I processi demo


audio di esempio di due persone che parlano. Quando il servizio trascrive l'audio, ritorna
risultati di trascrizione intermedi, anche se non è stato ancora possibile distinguerli
gli altoparlanti. La demo mostra questi risultati intermedi parallelamente a quelli del servizio
lavoro continuato. A volte la demo mostra "Rilevamento altoparlanti" durante il servizio
capisce chi sta parlando. Alla fine, il servizio invia i risultati della trascrizione aggiornati
per distinguere tra gli altoparlanti, e la demo sostituisce quindi il precedente
risultati di trascrizione.

Con i computer multicore e i cluster multicomputer odierni, l'asincrono


Le API possono aiutarti a migliorare le prestazioni del programma. Tuttavia, programmare con loro
può essere più complicato della programmazione con API sincrone. Quando discutiamo
installando l'SDK Watson Developer Cloud Python, forniamo un collegamento al codice dell'SDK
esempi su GitHub, dove puoi vedere esempi che utilizzano sincrono e
versioni asincrone di diversi servizi. Il riferimento API di ogni servizio fornisce il
dettagli completi.

13.4 SERVIZI E STRUMENTI AGGIUNTIVI


In questa sezione, presentiamo una panoramica di diversi servizi e strumenti avanzati di Watson.

Watson Studio
9
Watson Studio è la nuova interfaccia Watson per creare e gestire il tuo Watson
progetti e per collaborare con i membri del tuo team su tali progetti. Puoi aggiungere
dati, prepara i tuoi dati per l'analisi, crea notebook Jupyter per interagire con il tuo
dati, creare e addestrare modelli e lavorare con le capacità di deeplearning di Watson.
Watson Studio offre un livello Lite per utente singolo. Dopo aver configurato Watson Studio Lite
accedere facendo clic su Crea nella pagina Web dei dettagli del servizio

9
1h
c
9 Pagina 561
ttps: //console.bluemix.net/catalog/services/datascience

xesperienza .
ttps: //console.bluemix.net/catalog/services/datascienceexperience

puoi accedere a Watson Studio all'indirizzo

ttps: //dataplatform.cloud.ibm.com/

0
Watson Studio contiene progetti preconfigurati. Fare clic su Crea un progetto per visualizzarlo
loro:

0
ttps: //dataplatform.cloud.ibm.com/ .

Standard: "Lavora con qualsiasi tipo di risorsa. Aggiungi servizi per risorse analitiche come te
bisogno di loro."

Data Science: "Analizza i dati per scoprire approfondimenti e condividere le tue scoperte
altri."

Riconoscimento visivo: "Contrassegna e classifica i contenuti visivi utilizzando Watson Visual


Servizio di riconoscimento. "

Apprendimento profondo: "Costruisci reti neurali e distribuisci modelli di apprendimento profondo".

Modeler: "Crea flussi di modellazione per addestrare modelli SPSS o progettare deep neural
reti. "

Analisi aziendale: "Crea dashboard visivi dai tuoi dati per ottenere informazioni approfondite
Più veloce."

Ingegneria dei dati: "Combina, pulisci, analizza e modella i dati utilizzando i dati
Raffineria."

Streams Flow: "Importa e analizza i dati di streaming utilizzando Streaming Analytics


servizio."

Knowledge Studio

Vari servizi Watson funzionano con modelli predefiniti , ma consentono anche di fornire
modelli personalizzati addestrati per settori o applicazioni specifici. Watson's
1
Knowledge Studio ti aiuta a costruire modelli personalizzati. Consente ai team aziendali di

21h
e
Pagina 562
ork insieme per creare e addestrare nuovi modelli, che possono quindi essere distribuiti per essere utilizzati da
Servizi Watson.

1
TTP: //console.bluemix.net/catalog/services/knowledgestudio .

Apprendimento automatico
2
Il servizio Watson Machine Learning consente di aggiungere capacità predittive
alle tue app tramite i framework di machine learning più diffusi, tra cui Tensorflow, Keras,
scikitlearn e altri. Userai scikitlearn e Keras nei prossimi due capitoli.

2
TTP: //console.bluemix.net/catalog/services/machinelearning .

Catalogo della conoscenza


3, 4
Il catalogo della conoscenza di Watson è uno strumento avanzato a livello di impresa per
gestire, trovare e condividere in modo sicuro i dati della tua organizzazione. Lo strumento offre:
3 ttps: //medium.com/ibmwatson/introducingibmwatsonknowledge
atalogcf42c13032c1 .

4
ttps: //dataplatform.cloud.ibm.com/docs/content/catalog/overview
kc.html .

Accesso centrale ai dati locali e basati su cloud e all'apprendimento automatico di un'azienda


Modelli.

Supporto di Watson Studio in modo che gli utenti possano trovare e accedere ai dati, quindi utilizzarli facilmente in
progetti di machine learning.

Politiche di sicurezza che garantiscono solo le persone che dovrebbero avere accesso a dati specifici
davvero.

Supporto per oltre 100 operazioni di pulizia dei dati e wrangling.

E altro ancora.

Cognos Analytics
5
IBM Cognos Analytics service, che ha una prova gratuita di 30 giorni, utilizza AI e
machine learning per scoprire e visualizzare le informazioni nei tuoi dati, senza alcuna
programmazione da parte vostra. Fornisce anche un'interfaccia naturallanguage che consente
per porre domande a cui Cognos Analytics risponde in base alla conoscenza che raccoglie

w
hc2
Pagina 563
dai tuoi dati.

5
TTP: //www.ibm.com/products/cognosanalytics .

13.5 WATSON DEVELOPER CLOUD PYTHON SDK


In questa sezione, installerai i moduli necessari per la sezione successiva completa
implementazione del caso di studio Watson. Per comodità di codifica, IBM fornisce il
Watson Developer Cloud Python SDK (kit di sviluppo software). Suo
Il modulo watson_developer_cloud contiene classi con cui interagirai
Servizi Watson. Creerai oggetti per ogni servizio di cui hai bisogno, quindi interagirai con il file
servizio chiamando i metodi dell'oggetto.

6
Per installare l'SDK apri un prompt di Anaconda (Windows; apri come amministratore),
7
Terminal (macOS / Linux) o shell (Linux), quindi esegui il seguente comando :

6
Per istruzioni dettagliate sull'installazione e suggerimenti per la risoluzione dei problemi, vedere
ttps: //github.com/watsondevelopercloud/python

dk / blob / Develop / README.md .

7
Gli utenti Windows potrebbero dover installare gli strumenti di compilazione C ++ di Microsoft da
ttps: //visualstudio.microsoft.com/visualcppbuildtools/ , quindi
installa il modulo watsondevelopercloud.

pip installa aggiornamento watsondevelopercloud

Moduli necessari per la registrazione e la riproduzione audio


Avrai anche bisogno di due moduli aggiuntivi per la registrazione audio (PyAudio) e la riproduzione
8
(PyDub). Per installarli, usa i seguenti comandi :
8 Gli utenti Mac potrebbero dover prima eseguire conda install c condaforge
portaudio.

pip installa pyaudio


pip installa pydub

Esempi di SDK

Su GitHub, IBM fornisce un codice di esempio che dimostra come accedere ai servizi Watson
utilizzando le classi di Watson Developer Cloud Python SDK. Puoi trovare gli esempi su:

2h
S
Pagina 564
ttps: //github.com/watsondevelopercloud/pythonsdk/tree/master/examples

13.6 CASO DI STUDIO: COMPAGNO DI VIAGGIATORE


APP DI TRADUZIONE
Supponi di viaggiare in un paese di lingua spagnola, ma non parli spagnolo,
e devi comunicare con qualcuno che non parla inglese. Potresti
usa un'app di traduzione per parlare in inglese e l'app potrebbe tradurlo, quindi parlarlo
in spagnolo. La persona che parla spagnolo potrebbe quindi rispondere e l'app potrebbe
traducetelo e parlatelo in inglese.

Qui, utilizzerai tre potenti servizi IBM Watson per implementare tale viaggiatore
9
app di traduzione complementare, che consente a persone che parlano lingue diverse
conversare quasi in tempo reale. La combinazione di servizi come questo è nota come creazione di un file
mashup . Questa app utilizza anche semplici funzionalità di elaborazione dei file che abbiamo introdotto in
il capitolo "File ed eccezioni".

9
Questi servizi potrebbero cambiare in futuro. Se lo fanno, pubblicheremo gli aggiornamenti sui libri
pagina web all'indirizzo
ttp: //www.deitel.com/books/IntroToPython .

13.6.1 Prima di eseguire l'app


Svilupperai questa app utilizzando i livelli Lite (gratuiti) di diversi servizi IBM Watson. Prima
eseguendo l'app, assicurati di esserti registrato per un account IBM Cloud, come noi
discusso in precedenza nel capitolo, in modo da poter ottenere le credenziali per ciascuno dei tre servizi
l'app utilizza. Una volta ottenute le credenziali (descritte di seguito), le inserirai in
il nostro file keys.py (che si trova nella cartella degli esempi ch13) che importiamo nel file
esempio. Non condividere mai le tue credenziali.

Durante la configurazione dei servizi di seguito, la pagina delle credenziali di ciascun servizio mostra anche il file
URL del servizio. Questi sono gli URL predefiniti utilizzati da Watson Developer Cloud Python
SDK, quindi non è necessario copiarli. Nel ezione 13.6.3, presentiamo il

Script SimpleLanguageTranslator.py e una procedura dettagliata del codice.

Registrazione per il servizio di sintesi vocale


Questa app utilizza il servizio Watson Speech to Text per trascrivere l'inglese e lo spagnolo
file audio rispettivamente in inglese e spagnolo. Per interagire con il servizio, tu
deve ottenere un nome utente e una password. Fare così:

1. Creare un'istanza di servizio: vai a

S
2h

Pagina 565
ttps: //console.bluemix.net/catalog/services/speechtotext
e fare clic sul pulsante Crea nella parte inferiore della pagina. Questo genera automaticamente un'API
key per te e ti porta a un tutorial per lavorare con il servizio Speech to Text.

2. Ottieni le tue credenziali di servizio: per vedere la tua chiave API, fai clic su Gestisci in alto
a sinistra della pagina. A destra di Credenziali, fai clic su Mostra credenziali, quindi copia
la chiave API e incollala nella stringa della variabile speech_to_text_key nel file

Il file keys.py è fornito nella cartella degli esempi ch13 di questo capitolo.

Registrazione per il servizio di sintesi vocale

In questa app, utilizzerai il servizio Watson Text to Speech per sintetizzare il parlato dal testo.
Questo servizio richiede anche di ottenere un nome utente e una password. Fare così:

1. Creare un'istanza di servizio: vai a

ttps: //console.bluemix.net/catalog/services/texttospeech
e fare clic sul pulsante Crea nella parte inferiore della pagina. Questo genera automaticamente un'API
key per te e ti porta a un'esercitazione per lavorare con il servizio Text to Speech.

2. Ottieni le tue credenziali di servizio: per vedere la tua chiave API, fai clic su Gestisci in alto
a sinistra della pagina. A destra di Credenziali, fai clic su Mostra credenziali, quindi copia
la chiave API e incollala nella stringa della variabile text_to_speech_key nel file

Il file keys.py è fornito nella cartella degli esempi ch13 di questo capitolo.

Registrazione per il servizio di traduzione di lingue


In questa app, utilizzerai il servizio Watson Language Translator per passare il testo a Watson
e ricevere indietro il testo tradotto in un'altra lingua. Questo servizio richiede che tu lo faccia
ottenere una chiave API. Fare così:

1. Creare un'istanza di servizio: vai a

ttps: //console.bluemix.net/catalog/services/language
ranslator e fare clic sul pulsante Crea nella parte inferiore della pagina. Questa auto
genera una chiave API per te e ti porta a una pagina per gestire la tua istanza di
servizio.

2. Ottieni le tue credenziali di servizio: a destra di Credenziali, fai clic su Mostra


credenziali, quindi copia la chiave API e incollala nella variabile
La stringa translate_key nel file keys.py fornito in ch13 di questo capitolo
cartella di esempi.

R trasferire le tue credenziali


th

Recupero delle tue credenziali Pagina 566

Per visualizzare le tue credenziali in qualsiasi momento, fai clic sull'istanza del servizio appropriata in:

ttps: //console.bluemix.net/dashboard/apps

13.6.2 Test-guida dell'app


Dopo aver aggiunto le tue credenziali allo script, apri un prompt di Anaconda
0
(Windows), un terminale (macOS / Linux) o una shell (Linux). Esegui lo script eseguendo
il seguente comando dalla cartella degli esempi ch13:

0
Il modulo pydub.playback che utilizziamo in questa app emette un avviso quando esegui il nostro
script. L'avvertimento ha a che fare con le funzionalità del modulo che non usiamo e può essere ignorato. Per
eliminare questo avviso, è possibile installare ffmpeg per Windows, macOS o Linux da

ttps: //www.ffmpeg.org .
ipython SimpleLanguageTranslator.py

Elaborazione della domanda

L'app esegue 10 passaggi, che segnaliamo tramite commenti nel codice. Quando il
inizia l'esecuzione dell'app:

Il passaggio 1 richiede e registra una domanda. Innanzitutto, l'app visualizza:

Premi Invio quindi fai la tua domanda in inglese

e attende che tu prema Invio . Quando lo fai, l'app visualizza:

Registrazione di 5 secondi di audio

Pronuncia la tua domanda. Abbiamo detto: "Dov'è il bagno più vicino?" Dopo cinque secondi, il
visualizza l'app:

Registrazione completata

Il passaggio 2 interagisce con il servizio Speech to Text di Watson per trascrivere l'audio in testo
e visualizza il risultato:

3h

Pagina 567
Inglese: dov'è il bagno più vicino

Il passaggio 3 utilizza quindi il servizio Traduttore di lingue di Watson per tradurre il testo in inglese
Spagnolo e visualizza il testo tradotto restituito da Watson:

Spagnolo: ¿Dónde está el baño más cercano?

Il passaggio 4 passa questo testo spagnolo al servizio Text to Speech di Watson per convertire il testo in
un file audio.

Il passaggio 5 riproduce il file audio spagnolo risultante.

Elaborazione della risposta

A questo punto, siamo pronti per elaborare la risposta dell'oratore spagnolo.

Viene visualizzato il passaggio 6:

Premere Invio, quindi pronunciare la risposta in spagnolo

e attende che tu prema Invio . Quando lo fai, l'app visualizza:

Registrazione di 5 secondi di audio

e lo spagnolo registra una risposta. Non parliamo spagnolo, quindi abbiamo usato
Il servizio di sintesi vocale di Watson per preregistrare Watson che dice la risposta spagnola "El
baño más cercano está en el restaurante ", quindi ha riprodotto l'audio abbastanza forte per il nostro
microfono del computer per registrarlo. Abbiamo fornito questo audio preregistrato per te come
SpokenResponse.wav nella cartella ch13. Se usi questo file, riproducilo subito dopo
1
premendo Invio sopra mentre l'app registra per soli 5 secondi . Per garantire che l'audio
carica e riproduce velocemente, potresti volerlo riprodurre una volta prima di premere Invio per iniziare
registrazione. Dopo cinque secondi, l'app visualizza:

1
Per semplicità, abbiamo impostato l'app per registrare cinque secondi di audio. Puoi controllare il file
duration con la variabile SECONDS nella funzione record_audio. È possibile creare

un registratore che inizia a registrare una volta rilevato il suono e interrompe la registrazione dopo a
periodo di silenzio, ma il codice è più complicato.

Registrazione completata

Pagina 568

Il passaggio 7 interagisce con il servizio Speech to Text di Watson per trascrivere l'audio in spagnolo
al testo e visualizza il risultato:

Risposta spagnola: el baño más cercano está en el restaurante

Il passaggio 8 utilizza quindi il servizio Traduttore di lingue di Watson per tradurre il testo in spagnolo
Inglese e visualizza il risultato:

Risposta inglese: Il bagno più vicino è nel ristorante

Il passaggio 9 passa il testo inglese al servizio Text to Speech di Watson per convertirlo
un file audio.

Il passaggio 10 riproduce quindi l'audio in inglese risultante.

13.6.3 Procedura dettagliata dello script SimpleLanguageTranslator.py


In questa sezione, presentiamo il sorgente dello script SimpleLanguageTranslator.py
codice, che abbiamo suddiviso in piccoli pezzi numerati consecutivamente. Usiamo un top
approccio down come abbiamo fatto nel capitolo “Control Statements”. Ecco il top:

Crea un'app di traduzione che consenta di comunicare in inglese e spagnolo.

Il primo affinamento è:

Traduci una domanda pronunciata in inglese in spagnolo.

Traduci la risposta pronunciata in spagnolo in lingua inglese.

Possiamo suddividere la prima riga del secondo perfezionamento in cinque passaggi:

Passaggio 1: richiedere quindi registrare il parlato inglese in un file audio.

Passaggio 2: trascrivi il discorso inglese in testo inglese.

Passaggio 3: traduci il testo inglese in testo spagnolo.

Passaggio 4: sintetizza il testo spagnolo in parlato spagnolo e salvalo in un file audio.

Passaggio 5: riproduci il file audio spagnolo.

Pagina 569
Possiamo suddividere la seconda riga del secondo raffinamento in cinque passaggi:
Passaggio 6: richiedere quindi registrare il discorso spagnolo in un file audio.

Passaggio 7: trascrivi il discorso spagnolo in testo spagnolo.

Passaggio 8: traduci il testo spagnolo in testo inglese.

Passaggio 9: sintetizza il testo inglese in parlato inglese e salvalo in un file audio.

Passaggio 10: riprodurre l'audio in inglese.

Questo sviluppo dall'alto verso il basso offre i vantaggi dell'approccio divideandconquer


chiaro, concentrando la nostra attenzione su piccoli pezzi di un problema più significativo.

Nello script di questa sezione, implementiamo i 10 passaggi specificati nel secondo perfezionamento.
I passaggi 2 e 7 utilizzano il servizio Watson Speech to Text, i passaggi 3 e 8 utilizzano Watson
Il servizio Language Translator ei passaggi 4 e 9 utilizzano il servizio Text to Speech di Watson.

Importazione di classi SDK Watson


Le righe 4–6 importano classi dal modulo watson_developer_cloud che era
installato con Watson Developer Cloud Python SDK. Ciascuna di queste classi utilizza l'estensione
Credenziali Watson ottenute in precedenza per interagire con un Watson corrispondente
servizio:

2
Class SpeechToTextV1 consente di passare un file audio a Watson Speech a
3
Servizio di testo e ricevi un documento JSON contenente la trascrizione del testo.

2
La V1 nel nome della classe indica il numero di versione del servizio. Mentre IBM rivede il suo
services, aggiunge piuttosto nuove classi al modulo watson_developer_cloud
che modificare le classi esistenti. Ciò garantisce che le app esistenti non si interrompano
quando i servizi vengono aggiornati. I servizi Speech to Text e Text to Speech sono
ogni versione 1 (V1) e il servizio di traduzione della lingua è la versione 3 (V3) in

momento in cui scrivo.

3
Abbiamo introdotto JSON nel capitolo precedente, Data Mining Twitter.

Class LanguageTranslatorV3 ti consente di passare il testo alla lingua Watson

Servizio di traduzione e ricevi un documento JSON contenente il testo tradotto.

La classe TextToSpeechV1 consente di passare il testo a Watson Text to Speech

3W

Pagina 570
servizio e ricevere l'audio del testo parlato in una lingua specificata.

lecca qui per visualizzare l'immagine del codice

1 # SimpleLanguageTranslator.py
2 "" "Utilizza IBM Watson Speech to Text, Language Translator e Text to Spe ch
3 API per consentire la comunicazione di lingua inglese e spagnola. "" "
4 da watson_developer_cloud import SpeechToTextV1
5 da watson_developer_cloud import LanguageTranslatorV3
6 da watson_developer_cloud importa TextToSpeechV1

Altri moduli importati

La riga 7 importa il file keys.py contenente le tue credenziali Watson. Importazione righe 8-11
moduli che supportano le capacità di elaborazione audio di questa app:
Il modulo pyaudio ci permette di registrare l'audio dal microfono.

I moduli pydub e pydub.playback ci consentono di caricare e riprodurre file audio.

Il modulo wave della Python Standard Library ci consente di salvare WAV (Waveform
Formato file audio). WAV è un popolare formato audio originariamente sviluppato da
Microsoft e IBM. Questa app utilizza il modulo wave per salvare l'audio registrato in un file

.wav che inviamo al servizio Speech to Text di Watson per la trascrizione.

lecca qui per visualizzare l'immagine del codice

7 import keys # contiene le tue chiavi API per accedere ai servizi Watson
8 import pyaudio # utilizzato per registrare dal microfono
9 import pydub # utilizzato per caricare un file WAV
10 import pydub.playback # utilizzato per riprodurre un file WAV
11 import wave # utilizzato per salvare un file WAV
12

Programma principale: funzione run_translator

Diamo un'occhiata alla parte principale del programma definita nella funzione run_translator (lines
13–54), che richiama le funzioni definite successivamente nello script. A scopo di discussione,
abbiamo suddiviso run_translator nei 10 passaggi che esegue. Nel passaggio 1 (righe 15-17), noi
chiedere all'utente in inglese di premere Invio , quindi pronunciare una domanda. Funzione

C
Pagina 571
record_audio quindi registra l'audio per cinque secondi e lo memorizza nel file
english.wav:

lecca qui per visualizzare l'immagine del codice

13 def run_translator ():


14 "" "Chiama le funzioni che interagiscono con i servizi Watson." ""
15 # Passaggio 1: richiedere quindi registrare il parlato inglese in un file audio
16 input ( "Premi Invio e fai la tua domanda in inglese" )
17 record_audio ( 'english.wav' )
18

Nel passaggio 2, chiamiamo la funzione speech_to_text, passando il file english.wav per


trascrizione e dicendo al servizio Speech to Text di trascrivere il testo usando il suo
4
modello predefinito "enUS_BroadbandModel". Quindi visualizziamo il trascritto
testo:

4
Per la maggior parte delle lingue, il servizio Watson Speech to Text supporta la banda larga e
modelli a banda stretta . Ognuno ha a che fare con la qualità dell'audio. Per l'audio acquisito a 16
kHZ e superiori, IBM consiglia di utilizzare i modelli a banda larga. In questa app, noi
catturare l'audio a 44,1 kHZ.

lecca qui per visualizzare l'immagine del codice

19 # Passaggio 2: trascrivi il discorso inglese in testo inglese


20 inglese = speech_to_text (
21 file_name = 'english.wav' , model_id = 'enUS_BroadbandModel' )
22 print ( 'English:' , inglese)
23

Nel passaggio 3, chiamiamo la funzione translate, passando il testo trascritto dal passaggio 2 come
il testo da tradurre. Qui diciamo al servizio Language Translator di tradurre il testo
utilizzando il suo modello predefinito "enes" per tradurre dall'inglese (en) allo spagnolo (es).

Visualizziamo quindi la traduzione in spagnolo:

lecca qui per visualizzare l'immagine del codice

24 # Passaggio 3: traduci il testo inglese in testo spagnolo


25 spagnolo = traduci (text_to_translate = inglese, model ='enes' )
26 print ( 'Spanish:' , Spanish)
27

3C

Pagina 572
Nel passaggio 4, chiamiamo la funzione text_to_speech, passando il testo spagnolo dal passaggio 3
affinché il servizio di sintesi vocale parli usando la sua voce "esUS_SofiaVoice". Anche noi
specificare il file in cui salvare l'audio:

lecca qui per visualizzare l'immagine del codice

28 # Passaggio 4: sintetizza il testo spagnolo nel discorso spagnolo


29 text_to_speech (text_to_speak = spagnolo, voice_to_use = 'esUS_SofiaV ice'
30 file_name = 'spanish.wav' )
31

Nel passaggio 5, chiamiamo la funzione play_audio per riprodurre il file "spanish.wav", che
contiene l'audio spagnolo per il testo che abbiamo tradotto nel passaggio 3.

lecca qui per visualizzare l'immagine del codice

32 # Passaggio 5: riproduci il file audio spagnolo


33 play_audio (file_name = 'spanish.wav' )
34

Infine, i passaggi 6–10 ripetono ciò che abbiamo fatto nei passaggi 1–5, ma per la lingua spagnola
Discorso inglese:

Il passaggio 6 registra l' audio spagnolo .

Il passaggio 7 trascrive l'audio spagnolo in testo spagnolo utilizzando la sintesi vocale


modello predefinito del servizio "esES_BroadbandModel".

Il passaggio 8 traduce il testo spagnolo in testo inglese utilizzando il traduttore di lingua


Modello "esen" (spagnolo-inglese) del servizio.

Il passaggio 9 crea l'audio in inglese utilizzando la voce del servizio di sintesi vocale "en

US_AllisonVoice '.

Il passaggio 10 riproduce l'audio in inglese.

lecca qui per visualizzare l'immagine del codice

35 # Passaggio 6: chiedi di registrare il parlato spagnolo in un file audio


36 input ( "Premi Invio e pronuncia la risposta in spagnolo")
37 record_audio ( 'spanishresponse.wav' )

38 Pagina 573
39 # Passaggio 7: trascrivi il discorso spagnolo in testo spagnolo
40 spagnolo = speech_to_text (
41 nome_file = 'spanishresponse.wav' , model_id = 'esES_BroadbandModel'
42 print ( "Spanish response:" , spagnolo)
43
44 # Passaggio 8: traduci il testo spagnolo in testo inglese
45 inglese = traduci (text_to_translate = spagnolo, modello ='esen' )
46 print ( "English response:" , inglese)
47
48 # Passaggio 9: sintetizza il testo inglese nel discorso inglese
49 text_to_speech (text_to_speak = inglese,
50 voice_to_use = 'enUS_AllisonVoice' ,
51 nome_file = 'englishresponse.wav' )
52
53 # Passaggio 10: riproduci l'audio in inglese
54 play_audio (file_name = 'englishresponse.wav' )
55

Ora implementiamo le funzioni che chiamiamo dai passaggi da 1 a 10 .

Funzione speech_to_text

Per accedere al servizio Speech to Text di Watson, funzione speech_to_text (righe 56-87)
crea un oggetto SpeechToTextV1 denominato stt (abbreviazione di speechtotext), passando come

l'argomento la chiave API che hai impostato in precedenza. Si apre l'istruzione with (righe 62-65)
il file audio specificato dal parametro file_name e assegna il file risultante

oggetto in audio_file. La modalità aperta 'rb' indica che leggeremo (r) dati binari
(b): i file audio vengono memorizzati come byte in formato binario. Successivamente, le righe 64–65 utilizzano l'estensione

Metodo di riconoscimento dell'oggetto SpeechToTextV1 per richiamare il servizio Speech to Text.


Il metodo riceve tre argomenti di parole chiave:

audio è il file (audio_file) da passare al servizio Speech to Text.

content_type è il tipo di supporto del contenuto del file, indica "audio / wav"
5
che questo è un file audio memorizzato in formato WAV.

5
I tipi di supporto erano precedentemente noti come MIME (Multipurpose Internet Mail
Extensions) digita uno standard che specifica i formati dei dati, che possono essere utilizzati dai programmi
interpretare i dati correttamente.

model indica quale modello di lingua parlata il servizio utilizzerà per riconoscere il file
discorso e trascriverlo in testo. Questa app utilizza modelli predefiniti, o "en

US_BroadbandModel "(per inglese) o" esES_BroadbandModel "(per

3N

Pagina 574
Spagnolo).

lecca qui per visualizzare l'immagine del codice

56 def speech_to_text (file_name, model_id):


57 "" "Usa Watson Speech to Text per convertire file audio in testo." ""
58 # crea il client Watson Speech to Text
59 stt = SpeechToTextV1 (iam_apikey = keys.speech_to_text_key)
60
61 # apri il file audio
62 con open (file_name, 'rb' ) come audio_file:
63 # passa il file a Watson per la trascrizione
64 risultato = stt.recognize (audio = audio_file,
65 content_type = 'audio / wav' , model = model_id) .get_result ()
66
67 # Ottieni l'elenco dei "risultati". Questo può contenere intermedi e fina
68 # risultati, a seconda degli argomenti di riconoscimento del metodo. Noi abbiamo chiesto
69 # solo per i risultati finali, quindi questo elenco contiene un elemento.
70 results_list = risultato [ "risultati" ]
71
72 # Ottieni il risultato finale del riconoscimento vocale l'unico elemento della lista.
73 speech_recognition_result = results_list [ 0 ]
74
75 # Ottieni l'elenco delle "alternative". Questo può contenere più alternative
76 # trascrizioni, a seconda del metodo riconosce gli argomenti. Noi id
77 # Non chiedere alternative, quindi questo elenco contiene un elemento.
78 alternatives_list = speech_recognition_result [ "alternative" ]
79
80 # Ottieni l'unica trascrizione alternativa da alternatives_list.
81 first_alternative = alternatives_list [ 0 ]
82
83 # Ottieni il valore della chiave 'trascrizione', che contiene l'audio
84 # trascrizione del testo.
85 transcript = first_alternative [ "transcript" ]
86
87 restituisce la trascrizione # restituisce la trascrizione del testo dell'audio
88

Il metodo riconosce restituisce un oggetto DetailedResponse. È getResult


restituisce un documento JSON contenente il testo trascritto, in cui archiviamo

risultato. Il JSON sarà simile al seguente ma dipende dalla domanda che hai
Chiedi:

C
Pagina 575

JSON contiene dizionari ed elenchi annidati . Per semplificare la navigazione di questi dati
struttura, le righe 70-85 utilizzano piccole affermazioni separate per "riprendere" un pezzo alla volta
finché non otteniamo il testo trascritto - "dov'è il bagno più vicino", che noi
poi ritorna. Le caselle attorno a parti del JSON e i numeri di riga in ciascuna casella
corrispondono alle dichiarazioni nelle righe 70-85. Le dichiarazioni funzionano come segue:

La riga 70 assegna a results_list l'elenco associato alla chiave 'results':

lecca qui per visualizzare l'immagine del codice

results_list = risultato [ "risultati" ]

A seconda degli argomenti passati al riconoscimento del metodo, questo elenco può contenere
risultati intermedi e finali. I risultati intermedi potrebbero essere utili, ad esempio, se
stavi trascrivendo audio dal vivo, come un telegiornale. Abbiamo chiesto solo i risultati finali,
6
quindi questo elenco contiene un elemento.

6
Per il metodo riconosce gli argomenti ei dettagli della risposta JSON, vedere

ttps: //www.ibm.com/watson/developercloud/speechto
ext / api / v1 / python.html? python # recognizesessionless .

La riga 73 assegna a speech_recognition_result il riconoscimento vocale finale

risultato: l'unico elemento in results_list:

lecca qui per visualizzare l'immagine del codice

speech_recognition_result = results_list [ 0 ]

Linea 78

tC
3h

Pagina 576
lecca qui per visualizzare l'immagine del codice

alternatives_list = speech_recognition_result [ "alternative" ]

assegna a alternatives_list l'elenco associato alla chiave

"alternative". Questo elenco può contenere più trascrizioni alternative,


a seconda del metodo riconoscere gli argomenti. Gli argomenti che abbiamo passato risultano
un elenco di un elemento.

La riga 81 assegna a first_alternative l'unico elemento in

alternatives_list:

lecca qui per visualizzare l'immagine del codice

first_alternative = alternatives_list [ 0 ]

La riga 85 assegna alla trascrizione il valore della chiave "transcript", che contiene il
trascrizione del testo dell'audio:

lecca qui per visualizzare l'immagine del codice

transcript = first_alternative [ "transcript" ]

Infine, la riga 87 restituisce la trascrizione del testo dell'audio.

Le righe 70-85 potrebbero essere sostituite con l'affermazione più densa

lecca qui per visualizzare l'immagine del codice

restituisci risultato [ "risultati" ] [ 0 ] [ "alternative" ] [ 0 ] [ "trascrizione" ]

ma preferiamo le affermazioni più semplici separate.

Funzione translate

Per accedere al servizio Watson Language Translator, funzione translate (righe 89–111)
crea prima un oggetto LanguageTranslatorV3 denominato language_translator,
7
passando come argomenti la versione del servizio ("20180531" ), la chiave API che hai impostato
in precedenza e l'URL del servizio. Le righe 93–94 utilizzano gli oggetti LanguageTranslatorV3

3C

Pagina 577
translate metodo per richiamare il servizio Language Translator, passando due parole chiave
argomenti:
7
Secondo il riferimento API del servizio Language Translator, "20180531" è il file
stringa della versione corrente al momento della stesura di questo documento. IBM modifica la stringa della versione solo se
apportano modifiche alle API che non sono compatibili con le versioni precedenti. Anche quando lo fanno, il file
il servizio risponderà alle chiamate utilizzando la versione API specificata nella stringa della versione.
Per ulteriori dettagli, vedere ttps: //www.ibm.com/watson

/developercloud/languagetranslator/api/v3/python.html?
ython # versioning .

text è la stringa da tradurre in un'altra lingua.

model_id è il modello predefinito che verrà utilizzato dal servizio Language Translator
comprendere il testo originale e tradurlo nella lingua appropriata. In questo
app, model sarà uno dei modelli di traduzione predefiniti di IBM: 'enes '(per
Da inglese a spagnolo) o "esen" (da spagnolo a inglese).

lecca qui per visualizzare l'immagine del codice

89 def translate (text_to_translate, modello):


90 "" "Usa Watson Language Translator per tradurre dall'inglese allo spagnolo
91 (enes) o dallo spagnolo all'inglese (esen) come specificato dal modello. ""
92 # crea il client Watson Translator
93 language_translator = LanguageTranslatorV3 (versione = '20180531' ,
94 iam_apikey = keys.translate_key)
95
96 # esegue la traduzione
97 Translated_text = language_translator.translate (
98 text = text_to_translate, model_id = model) .get_result ()
99
100 # Ottieni l'elenco delle "traduzioni". Se l'argomento di testo del metodo translate come
101 # più stringhe, l'elenco conterrà più voci. Abbiamo passato
102 # una stringa, quindi l'elenco contiene solo un elemento.
103 translation_list = translation_text [ "traduzioni" ]
104
105 # ottieni l'unico elemento translation_list
106 first_translation = translation_list [ 0 ]
107
108 # ottiene il valore della chiave 'traduzione', che è il testo tradotto
109 translation = first_translation [ 'translation' ]
110
111 return translation # restituisce la stringa tradotta
112

hC
3p

Pagina 578
Il metodo restituisce una DetailedResponse. Il metodo getResult di quell'oggetto restituisce

un documento JSON, come:

Il JSON che ottieni come risposta dipende dalla domanda che hai posto e, ancora una volta,
contiene dizionari ed elenchi annidati. Le righe 103-109 utilizzano piccole istruzioni per evidenziare
il testo tradotto "¿Dónde está el baño más cercano?". Le scatole in giro
parti di JSON e i numeri di riga in ogni casella corrispondono alle istruzioni in
righe 103-109. Le dichiarazioni funzionano come segue:
La riga 103 ottiene l'elenco delle "traduzioni":

lecca qui per visualizzare l'immagine del codice

translation_list = translation_text [ "traduzioni" ]

Se l'argomento di testo del metodo translate ha più stringhe, l'elenco avrà


entrate multiple. Abbiamo passato solo una stringa, quindi l'elenco contiene un solo elemento.

La riga 106 ottiene l'unico elemento translation_list:

lecca qui per visualizzare l'immagine del codice

first_translation = Translations_list [ 0 ]

La riga 109 ottiene il valore della chiave 'translation', che è il testo tradotto:

lecca qui per visualizzare l'immagine del codice

translation = first_translation [ 'translation' ]

La riga 111 restituisce la stringa tradotta.

C
Pagina 579
Le righe 103-109 potrebbero essere sostituite con l'affermazione più concisa

lecca qui per visualizzare l'immagine del codice

restituisci il testo tradotto [ "traduzioni" ] [ 0 ] [ "traduzione" ]

ma ancora una volta, preferiamo le affermazioni più semplici separate.

Funzione text_to_speech

Per accedere al servizio Text to Speech di Watson, la funzione text_to_speech (righe 113–

122) crea un oggetto TextToSpeechV1 chiamato tts (abbreviazione di texttospeech), passando


come argomento la chiave API impostata in precedenza. L'istruzione with apre il file
specificato da nome_file e associa il file al nome file_audio. Il modo

'wb' apre il file per la scrittura (w) in formato binario (b). Scriveremo in quel file il file
contenuto dell'audio restituito dal servizio Speech to Text.

lecca qui per visualizzare l'immagine del codice

113 def text_to_speech (text_to_speak, voice_to_use, file_name):


114 "" "Usa Watson Text to Speech per convertire il testo in una voce specifica
115 e salvare in un file WAV. "" "
116 # crea il client Text to Speech
117 tts = TextToSpeechV1 (iam_apikey = keys.text_to_speech_key)
118
119 # apre il file e scrive il contenuto audio sintetizzato nel fi e
120 con open (nome_file, 'wb' ) come file_audio:
121 audio_file.write (tts.synthesize (text_to_speak,
122 accept = 'audio / wav' , voice = voice_to_use) .get_result (). Cont nt)
123
Le righe 121–122 chiamano due metodi. Innanzitutto, invochiamo il servizio Speech to Text chiamando
il metodo synthesize dell'oggetto TextToSpeechV1 , passando tre argomenti:

text_to_speak è la stringa da pronunciare.

l'argomento della parola chiave accept è il tipo di media che indica il formato audio del file
Il servizio Speech to Text dovrebbe tornare, di nuovo, "audio / wav" indica un file audio
in formato WAV.

l'argomento della parola chiave voice è uno dei predefiniti del servizio Speech to Text
voci. In questa app, useremo "enUS_AllisonVoice" per parlare in inglese e

C
Pagina 580
"esUS_SofiaVoice" per parlare in spagnolo. Watson fornisce molti maschi e
8
voci femminili in varie lingue.

8
o un elenco completo, vedere
ttps: //www.ibm.com/watson/developercloud/textto
Peech / api / v1 / python.html? python # getvoice . Prova a sperimentare
altre voci.

La risposta dettagliata di Watson contiene il file audio del testo parlato, accessibile tramite

get_result. Accediamo all'attributo content del file restituito per ottenere i byte del file
audio e passarli al metodo di scrittura dell'oggetto audio_file in cui inviare i byte
un file .wav.

Funzione record_audio

Il modulo pyaudio ti consente di registrare l'audio dal microfono. La funzione

record_audio (righe 124–154) definisce diverse costanti (righe 126–130) usate per
configurare il flusso di informazioni audio provenienti dal microfono del computer.
Abbiamo utilizzato le impostazioni dalla documentazione in linea del modulo pyaudio:

FRAME_RATE: 44100 fotogrammi al secondo rappresenta 44,1 kHz, che è comune


per audio di qualità CD.

CHUNK — 1024 è il numero di fotogrammi in streaming nel programma alla volta.

FORMATO — pyaudio.paInt16 è la dimensione di ogni fotogramma (in questo caso, 16 bit o 2 byte
numeri interi).

CANALI — 2 è il numero di campioni per fotogramma.

SECONDI: 5 è il numero di secondi per i quali registreremo l'audio in questa app.

lecca qui per visualizzare l'immagine del codice

124 def record_audio (nome_file):


125 "" "Usa pyaudio per registrare 5 secondi di audio in un file WAV." ""
126 FRAME_RATE = 44100 # numero di fotogrammi al secondo
127 CHUNK = 1024 # numero di frame letti alla volta
128 FORMAT = pyaudio.paInt16 # ogni frame è un numero intero a 16 bit (2 byte)
129 CANALI = 2 # 2 campioni per frame
130 SECONDI = 5 # tempo di registrazione totale
131

ChF
3S

132 recorder = pyaudio.PyAudio () # apre / chiude i flussi audio Pagina 581


133
134 # configura e apri il flusso audio per la registrazione (input = True)
135 audio_stream = recorder.open (format = FORMAT , channels = CHANNELS ,
136 rate = FRAME_RATE , input = True , frames_per_buffer = CHUNK )
137 audio_frames = [] # memorizza i byte grezzi dell'ingresso del microfono
138 print ( 'Registrazione di 5 secondi di audio' )
139
140 # legge 5 secondi di audio in pezzi di dimensioni CHUNK
141 per i in range ( 0 , int ( FRAME_RATE * SECONDI / CHUNK )):
142 audio_frames.append (audio_stream.read ( CHUNK ))
143
144 print ( 'Registrazione completata' )
145 audio_stream.stop_stream () # interrompe la registrazione
146 audio_stream.close ()
147 recorder.terminate () # rilascia le risorse sottostanti usate da PyAudio
148
149 # salva audio_frames in un file WAV
150 con wave.open (file_name, 'wb' ) come output_file:
151 output_file.setnchannels ( CANALI )
152 output_file.setsampwidth (recorder.get_sample_size ( FORMAT ))
153 output_file.setframerate ( FRAME_RATE )
154 output_file.writeframes (b '' .join (audio_frames))
155

ine 132 crea l' oggetto PyAudio da cui otterremo il flusso di input da registrare
audio dal microfono. Le righe 135-136 utilizzano il metodo open dell'oggetto PyAudio per
aprire il flusso di input, utilizzando le costanti FORMAT, CHANNELS, FRAME_RATE e

CHUNK per configurare il flusso. L'impostazione dell'argomento della parola chiave di input su True indica
che il flusso verrà utilizzato per ricevere l'ingresso audio. Il metodo open restituisce un file

pyaudio Oggetto Stream per interagire con il flusso.

Le righe 141-142 utilizzano il metodo di lettura dell'oggetto Stream per ottenere 1024 (ovvero CHUNK)
frame alla volta dal flusso di input, che poi aggiungiamo a audio_frames
elenco. Per determinare il numero totale di iterazioni del ciclo necessarie per produrre 5 secondi di
audio utilizzando CHUNK frame alla volta, moltiplichiamo FRAME_RATE per SECONDS, quindi
dividere il risultato per CHUNK. Una volta completata la lettura, la riga 145 chiama l'oggetto Stream

stop_stream per terminare la registrazione, la riga 146 chiama l'oggetto Stream


close per chiudere lo Stream e la riga 147 chiama l'oggetto PyAudio
terminate per rilasciare le risorse audio sottostanti a cui erano state utilizzate
gestire il flusso audio.

L'istruzione with nelle righe 150–154 usa la funzione open del modulo wave per aprire
il file WAV specificato da nome_file per la scrittura in formato binario ('wb'). Linee 151–
153 configurare il numero di canali del file WAV, l'ampiezza del campione (ottenuta dal file

L
Pagina 582
Metodo get_sample_size dell'oggetto PyAudio ) e frame rate. Quindi la riga 154 scrive
il contenuto audio del file. L'espressione b ''. Join (audio_frames)
concatena tutti i byte dei frame in una stringa di byte . Premendo una stringa con b
indica che è una stringa di byte anziché una stringa di caratteri.

Funzione play_audio

Per riprodurre i file audio restituiti dal servizio Text to Speech di Watson, utilizziamo le funzionalità di
i moduli pydub e pydub.playback. Innanzitutto, dal modulo pydub, riga 158
utilizza l'AudioSegment della classe metodo from_wav per caricare un file WAV. Il metodo
restituisce un nuovo oggetto AudioSegment che rappresenta il file audio. Per riprodurre il file

AudioSegment, la riga 159 chiama la funzione di riproduzione del modulo pydub.playback ,


passando l'AudioSegment come argomento.

lecca qui per visualizzare l'immagine del codice


156 def play_audio (nome_file):
157 "" "Usa il modulo pydub (pip install pydub) per riprodurre un file WAV." "
158 sound = pydub.AudioSegment.from_wav (nome_file)
159 pydub.playback.play (suono)
160

Esecuzione della funzione run_translator


Chiamiamo la funzione run_translator quando esegui SimpleLanguage

Translator.py come script:

lecca qui per visualizzare l'immagine del codice

161 if __name__ == '__main__' :


162 run_translator ()

Si spera che abbiamo adottato un approccio di divisione e di conquista su questo caso sostanziale
il copione dello studio lo rendeva gestibile. Molti dei passaggi combaciano perfettamente con alcune chiavi
Servizi Watson, che ci consentono di creare rapidamente una potente applicazione di mashup.

13.7 RISORSE WATSON


IBM fornisce una vasta gamma di risorse per sviluppatori per aiutarti a familiarizzare con
i loro servizi e iniziare a usarli per creare applicazioni.

W
C Documentazione sui servizi atson

Documentazione sui servizi atson Pagina 583

La documentazione dei servizi Watson si trova su:

ttps: //console.bluemix.net/developer/watson/documentation

Per ogni servizio sono disponibili documentazione e collegamenti di riferimento API. Ogni servizio è
la documentazione in genere include alcuni o tutti i seguenti:

un tutorial per iniziare.

una panoramica video del servizio.

un collegamento a una demo del servizio.

collegamenti a documenti tutorial e howto più specifici.

app di esempio.

risorse aggiuntive, come tutorial più avanzati, video, post di blog e altro ancora.

Il riferimento API di ogni servizio mostra tutti i dettagli di interazione con il servizio utilizzando
uno qualsiasi dei diversi linguaggi, incluso Python. Fare clic sulla scheda Python per vedere il Python
documentazione specifica ed esempi di codice corrispondenti per Watson Developer
SDK Cloud Python. Il riferimento API spiega tutte le opzioni per invocare un dato
servizio, i tipi di risposte che può restituire, risposte di esempio e altro ancora.

Watson SDK

Abbiamo utilizzato Watson Developer Cloud Python SDK per sviluppare lo script di questo capitolo.
Esistono SDK per molti altri linguaggi e piattaforme. L'elenco completo si trova in:
ttps: //console.bluemix.net/developer/watson/sdksandtools

Risorse di apprendimento

Nella pagina Risorse di apprendimento

ttps: //console.bluemix.net/developer/watson/learningresources

troverai collegamenti a:

Post di blog sulle funzionalità di Watson e su come Watson e AI vengono utilizzati nell'industria.

hW
Pagina 584
Repository GitHub di Watson (strumenti per sviluppatori, SDK e codice di esempio).

Il canale YouTube di Watson (discusso di seguito).

Pattern di codice, che IBM definisce "roadmap per la risoluzione di una programmazione complessa
sfide. " Alcuni sono implementati in Python, ma potresti comunque trovare l'altro codice
modelli utili per progettare e implementare le tue app Python.

Video di Watson
Il canale YouTube di Watson

ttps: //www.youtube.com/user/IBMWatsonSolutions/

contiene centinaia di video che mostrano come utilizzare tutti gli aspetti di Watson. Ci sono
riflettono anche video che mostrano come viene utilizzato Watson.

Redbook IBM

Le seguenti pubblicazioni IBM Redbooks trattano i servizi IBM Cloud e Watson in


dettagli, aiutandoti a sviluppare le tue abilità Watson.

Elementi essenziali dello sviluppo di applicazioni su IBM Cloud:

ttp: //www.redbooks.ibm.com/abstracts/sg248374.html

Creazione di applicazioni cognitive con IBM Watson Services: Volume 1 Getting


Iniziato: ttp: //www.redbooks.ibm.com/abstracts/sg248387.html

Creazione di applicazioni cognitive con IBM Watson Services: Volume 2


Conversazione (ora chiamata Watson Assistant):

ttp: //www.redbooks.ibm.com/abstracts/sg248394.html

Creazione di applicazioni cognitive con IBM Watson Services: Volume 3 Visual


Riconoscimento:

ttp: //www.redbooks.ibm.com/abstracts/sg248393.html

Creazione di applicazioni cognitive con IBM Watson Services: Volume 4 Natural


Classificatore di lingue:

ttp: //www.redbooks.ibm.com/abstracts/sg248391.html

Creazione di applicazioni cognitive con IBM Watson Services: Volume 5 Language


Traduttore: ttp: //www.redbooks.ibm.com/abstracts/sg248392.html

h
Pagina 585
Creazione di applicazioni cognitive con IBM Watson Services: Volume 6 Speech to
Testo e sintesi vocale:
ttp: //www.redbooks.ibm.com/abstracts/sg248388.html

Creazione di applicazioni cognitive con IBM Watson Services: Volume 7 Natural


Comprensione della lingua:
ttp: //www.redbooks.ibm.com/abstracts/sg248398.html

13.8 WRAP-UP
In questo capitolo, abbiamo introdotto la piattaforma cognitivecomputing IBM Watson e
ha esaminato la sua vasta gamma di servizi. Hai visto che Watson offre intriganti
capacità che puoi integrare nelle tue applicazioni. IBM incoraggia l'apprendimento e
sperimentazione tramite i suoi livelli Lite gratuiti. Per trarne vantaggio, configuri un IBM
Account cloud. Hai provato le demo di Watson per sperimentare vari servizi, come
traduzione in linguaggio naturale, speechtotext, texttospeech, linguaggio naturale
comprensione, chatbot, analisi del testo per il riconoscimento del tono e degli oggetti visivi nelle immagini
e video.

Hai installato Watson Developer Cloud Python SDK per l'accesso programmatico a
Servizi Watson dal tuo codice Python. Nell'app di traduzione complementare del viaggiatore,
abbiamo unito diversi servizi Watson per abilitare solo l'inglese e solo lo spagnolo
altoparlanti per comunicare facilmente tra loro verbalmente. Abbiamo trascritto in inglese e
Registrazioni audio in spagnolo in testo, quindi tradotto il testo in un'altra lingua
audio sintetizzato in inglese e spagnolo dal testo tradotto. Infine, abbiamo discusso
varie risorse Watson, inclusi documentazione, blog, Watson GitHub
repository, il canale YouTube di Watson, modelli di codice implementati in Python (e
altre lingue) e IBM Redbooks.

h
Pagina 586

14. Apprendimento automatico: classificazione, regressione


storia

e clustering
opiche

Obiettivi
guadagnando Pat
In questo capitolo potrai:

ffers & Dea


Usa scikitlearn con set di dati popolari per eseguire studi di machine learning.
ighlights
Usa Seaborn e Matplotlib per visualizzare ed esplorare i dati.

ettings
Eseguire l'apprendimento automatico supervisionato con la classificazione dei vicini più esperti e
regressione lineare.
Supporto

Eseguire la multiclassificazione con il set di dati di cifre.


Disconnessione

Dividi un set di dati in set di addestramento, test e convalida.

Ottimizza gli iperparametri del modello con la convalida incrociata kfold.

Misura le prestazioni del modello.

Visualizza una matrice di confusione che mostra gli hit e gli errori di previsione della classificazione.

Esegui la regressione lineare multipla con il set di dati California Housing.

Eseguire la riduzione della dimensionalità con PCA e tSNE sui set di dati Iris e Digits
per prepararli per visualizzazioni bidimensionali.

Esegui un machine learning senza supervisione con kmeans clustering e il set di dati Iris.

Contorno

4.1 Introduzione al machine learning

1
Pagina 587
4.1.1 ScikitLearn

4.1.2 Tipi di machine learning

4.1.3 Set di dati in bundle con ScikitLearn

4.1.4 Fasi di un tipico studio di data science

4.2 Case Study: Classificazione con kNearest Neighbors e Digits Dataset, Parte 1

4.2.1 kAlgoritmo kNearest Neighbors

4.2.2 Caricamento del set di dati

4.2.3 Visualizzazione dei dati

4.2.4 Suddivisione dei dati per addestramento e test

4.2.5 Creazione del modello

4.2.6 Training del Modello

4.2.7 Previsione delle classi di cifre

4.3 Case Study: Classificazione con kNearest Neighbors e Digits Dataset, Parte 2

4.3.1 Metriche per l'accuratezza del modello

4.3.2 KFold CrossValidation

4.3.3 Esecuzione di più modelli per trovare quello migliore


4.3.4 Ottimizzazione degli iperparametri

4.4 Case Study: serie storiche e regressione lineare semplice

4.5 Case Study: regressione lineare multipla con il set di dati sulle abitazioni in California

4.5.1 Caricamento del set di dati

4.5.2 Esplorazione dei dati con Panda

4.5.3 Visualizzazione delle caratteristiche

1
Pagina 588
4.5.4 Suddivisione dei dati per addestramento e test

4.5.5 Formazione del modello

4.5.6 Test del modello

4.5.7 Visualizzazione dei prezzi attesi rispetto a quelli previsti

4.5.8 Metriche del modello di regressione

4.5.9 Scelta del modello migliore

4.6 Case Study: Machine Learning non supervisionato, Parte 1 - Riduzione della dimensionalità

4.7 Case Study: Machine Learning senza supervisione, parte 2 - kMeans Clustering

4.7.1 Caricamento del set di dati Iris

4.7.2 Esplorazione del set di dati Iris: statistiche descrittive con i panda

4.7.3 Visualizzazione del set di dati con un pairplot Seaborn

4.7.4 Utilizzo di uno stimatore KMeans

4.7.5 Riduzione della dimensionalità con analisi dei componenti principali

4.7.6 Scelta del miglior stimatore di clustering

4.8 WrapUp

14.1 INTRODUZIONE ALL'APPRENDIMENTO MACCHINARIO


In questo capitolo e nel prossimo presenteremo l'apprendimento automatico, uno dei più entusiasmanti
e promettenti sottocampi dell'intelligenza artificiale. Vedrai come risolvere rapidamente
problemi impegnativi e intriganti che i neofiti e i programmatori più esperti
probabilmente non ci avrei provato solo pochi anni fa. L'apprendimento automatico è un grande
argomento complesso che solleva molti problemi sottili. Il nostro obiettivo qui è darti un'amichevole,
introduzione manuale ad alcune delle tecniche di apprendimento automatico più semplici.

Cos'è l'apprendimento automatico?


Possiamo davvero far imparare le nostre macchine (cioè i nostri computer)? In questo e nel prossimo

1
Pagina 589
hapter, mostreremo esattamente come avviene quella magia. Qual è la "salsa segreta" di questo
nuovo stile di sviluppo dell'applicazione? Sono dati e molto altro. Piuttosto che programmare
esperienza nelle nostre applicazioni, le programmiamo per imparare dai dati. Vi presentiamo
molti esempi di codice basati su Python che creano modelli di apprendimento automatico funzionanti
usali per fare previsioni straordinariamente accurate.

Predizione

Non sarebbe fantastico se potessi migliorare le previsioni del tempo per salvare vite umane,
ridurre al minimo lesioni e danni alla proprietà? E se potessimo migliorare le diagnosi di cancro
e regimi di trattamento per salvare vite umane o migliorare le previsioni aziendali per massimizzare i profitti
e garantire il lavoro delle persone? Che dire del rilevamento di acquisti fraudolenti con carta di credito e
reclami assicurativi? Che ne dici di prevedere il "tasso di abbandono" dei clienti, quali sono i prezzi delle case
probabilità di vendita, vendita di biglietti di nuovi film e entrate previste di nuovi prodotti
e servizi? Che ne dici di prevedere le migliori strategie per allenatori e giocatori da utilizzare
vincere più partite e campionati? Tutti questi tipi di previsioni stanno accadendo
oggi con il machine learning.

Applicazioni di machine learning

Ecco una tabella di alcune popolari applicazioni di machine learning:

Applicazioni di machine learning

Rilevamento di anomalie

Chatbot
Rilevamento di oggetti in
scene
Classificazione delle email
come spam o meno
Rilevamento di modelli in Sistemi di raccomandazione
spam
dati ("Persone che hanno acquistato questo

Classificazione delle notizie prodotto acquistato anche ")


Medicina diagnostica
articoli come sport,
Auto SelfDriving (altro
finanziaria, politica, Riconoscimento facciale
generalmente, autonomo
eccetera.
veicoli)
Frode assicurativa
Visione computerizzata rilevamento
Analisi del sentiment (come
e immagine
classificare le recensioni di film come

c
Pagina 590
classificazione Rilevamento delle intrusioni in positivo, negativo o
reti di computer neutro)
Frode con carta di credito
rilevamento Riconoscimento della grafia Filtro antispam

Fidelizzazione dei clienti Marketing: dividere Previsioni di serie temporali come


predizione clienti in cluster previsione dei prezzi di borsa e
previsioni del tempo
Compressione dati Linguaggio naturale
traduzione (dall'inglese al Riconoscimento vocale
Esplorazione dei dati Spagnolo, francese a
Giapponese, ecc.)
Data mining sociale
media (come Prevedere un mutuo ipotecario
Facebook, Twitter, impostazioni predefinite
LinkedIn)
14.1.1 Scikit-Learn
Useremo la popolare libreria di machine learning scikitlearn . Scikitlearn, chiamato anche
sklearn, impacchetta comodamente gli algoritmi di machine learning più efficaci come
stimatori . Ognuno è incapsulato, quindi non vedi i dettagli intricati e pesanti
matematica di come funzionano questi algoritmi. Dovresti sentirti a tuo agio con questo - tu
guidare la tua auto senza conoscere i dettagli intricati di come motori, trasmissioni,
gli impianti frenanti e gli impianti sterzanti funzionano. Pensaci la prossima volta che fai un passo
in un ascensore e seleziona il piano di destinazione oppure accendi il televisore e seleziona
il programma che desideri guardare. Capisci davvero il funzionamento interno del tuo
hardware e software dello smartphone?

Con scikitlearn e una piccola quantità di codice Python, creerai modelli potenti
rapidamente per analizzare i dati, estrarre informazioni dai dati e, cosa più importante
Fare previsioni. Utilizzerai scikitlearn per addestrare ogni modello su un sottoinsieme di dati,
quindi prova ogni modello sul resto per vedere come funziona il tuo modello. Una volta che i tuoi modelli
sono addestrati, li metterai al lavoro facendo previsioni basate su dati che non hanno
visto. Rimarrai spesso stupito dai risultati. All'improvviso il tuo computer che hai
usato principalmente nelle faccende meccaniche assumerà caratteristiche di intelligenza.

Scikitlearn dispone di strumenti che automatizzano l'addestramento e il test dei modelli. Anche se puoi

Pagina 591
specificare i parametri per personalizzare i modelli ed eventualmente migliorarne le prestazioni, in
in questo capitolo, useremo tipicamente i parametri predefiniti dei modelli , ma continueremo a ottenere
risultati impressionanti. Ci sono anche strumenti come autosklearn
( TTP: //automl.github.io/autosklearn ), che automatizza molte delle
compiti che svolgi con scikitlearn.

Quale stimatore Scikit-Learn dovresti scegliere per il tuo progetto


È difficile sapere in anticipo quale / i modello / i avrà il rendimento migliore sui tuoi dati, quindi tu
in genere prova molti modelli e scegli quello che funziona meglio. Come vedrai, scikitlearn
lo rende conveniente per te. Un approccio popolare consiste nell'eseguire molti modelli e scegliere il file
il migliore (i). Come valutiamo quale modello ha funzionato meglio?

Ti consigliamo di sperimentare con molti modelli diversi su diversi tipi di set di dati.
Raramente conoscerai i dettagli dei complessi algoritmi matematici in
sklearn estimators, ma con l'esperienza acquisirai familiarità con quali algoritmi
può essere la soluzione migliore per particolari tipi di set di dati e problemi. Anche con quell'esperienza,
è improbabile che sarai in grado di intuire il modello migliore per ogni nuovo set di dati. Quindi scikit
imparare rende facile per te "provarli tutti". Ci vogliono al massimo poche righe di codice per farlo
creare e utilizzare ogni modello. I modelli riportano le loro prestazioni in modo da poterle confrontare
i risultati e scegli i modelli con le migliori prestazioni.

14.1.2 Tipi di machine learning


Presenteremo i due tipi principali di machine learning: machine learning supervisionato,
che funziona con dati etichettati e machine learning non supervisionato , che funziona con
dati senza etichetta .

Se, ad esempio, stai sviluppando un'applicazione di visione artificiale per riconoscere cani e
gatti, addestrerai il tuo modello su molte foto di cani etichettate come "cane" e foto di gatti etichettate
"gatto." Se il tuo modello è efficace, quando lo metti al lavoro elaboralo con foto senza etichetta
riconoscerà cani e gatti che non ha mai visto prima. Più foto ti alleni,
maggiore è la possibilità che il tuo modello preveda accuratamente quali sono le nuove foto
cani e quali sono i gatti. In quest'era di big data e computer enormi ed economici
potenza, dovresti essere in grado di costruire alcuni modelli abbastanza accurati con le tecniche
stai per vedere.

In che modo può essere utile esaminare i dati senza etichetta? Le librerie online vendono molti libri. Essi
registrare enormi quantità di dati sulle transazioni di acquisto di libri (senza etichetta). Hanno notato
All'inizio le persone che compravano certi libri probabilmente ne acquisteranno altri
argomenti uguali o simili. Ciò ha portato ai loro sistemi di raccomandazione . Ora, quando tu

S
h
Pagina 592
Rowse un sito di una libreria per un libro particolare, è probabile che tu veda consigli
come "le persone che hanno acquistato questo libro hanno acquistato anche questi altri libri". Raccomandazione
i sistemi sono un grande business oggi, e aiutano a massimizzare le vendite di prodotti di ogni tipo.

Machine learning supervisionato

L'apprendimento automatico supervisionato si divide in due categorie: classificazione e regressione .


I modelli di apprendimento automatico vengono addestrati su set di dati costituiti da righe e colonne. Ogni
riga rappresenta un campione di dati . Ogni colonna rappresenta una caratteristica di quel campione. Nel
apprendimento automatico supervisionato, ogni campione ha un'etichetta associata chiamata target (come
"Cane" o "gatto"). Questo è il valore che stai cercando di prevedere per i nuovi dati a cui presenti
i tuoi modelli.

Set di dati

Lavorerai con alcuni set di dati "giocattolo", ciascuno con un piccolo numero di campioni con estensione
numero limitato di funzioni. Lavorerai anche con diversi mondi reali ricchi di funzionalità
set di dati, uno contenente alcune migliaia di campioni e uno contenente decine di migliaia
di campioni. Nel mondo dei big data, i set di dati hanno comunemente, milioni e miliardi di
campioni, o anche di più.

C'è un numero enorme di set di dati gratuiti e aperti disponibili per la scienza dei dati
studi. Librerie come scikitlearn impacchettano set di dati popolari da sperimentare
con e forniscono meccanismi per il caricamento di set di dati da vari repository (come
openml.org). Governi, aziende e altre organizzazioni in tutto il mondo offrono
set di dati su una vasta gamma di argomenti. Lavorerai con diversi set di dati gratuiti popolari,
utilizzando una varietà di tecniche di apprendimento automatico.

Classificazione

Useremo uno degli algoritmi di classificazione più semplici, vicini più cari , per analizzare
il set di dati Digits in bundle con scikitlearn. Gli algoritmi di classificazione prevedono il
classi discrete (categorie) a cui appartengono i campioni. La classificazione binaria ne utilizza due
classi, come "spam" o "non spam" in un'applicazione di classificazione e-mail. Multi
la classificazione utilizza più di due classi, ad esempio le 10 classi, da 0 a 9, in
Set di dati cifre. Uno schema di classificazione che esamina le descrizioni dei film potrebbe provare a farlo
classificali come "azione", "avventura", "fantasia", "romanticismo", "storia" e simili.

Regressione

I modelli di regressione prevedono un output continuo , come la temperatura prevista


output nell'analisi delle serie temporali meteorologiche da Introduzione alla scienza dei dati del capitolo 10

b
C
Pagina 593
ezione. In questo capitolo , questa volta rivisiteremo quel semplice esempio di regressione lineare
implementandolo usando lo stimatore LinearRegression di scikitlearn. Successivamente, usiamo un file

Stimatore LinearRegression per eseguire la regressione lineare multipla con l' estensione
Set di dati California Housing in bundle con scikitlearn. Prevediamo la mediana
valore della casa di un blocco di case censito negli Stati Uniti, considerando otto elementi per blocco, come
come numero medio di stanze, età media della casa, numero medio di camere da letto e
reddito medio. Lo stimatore LinearRegression, per impostazione predefinita, utilizza tutti i valori numerici

caratteristiche in un set di dati per fare previsioni più sofisticate di quanto non sia possibile con un singolo
caratteristica semplice regressione lineare.

Machine Learning senza supervisione

Successivamente, introdurremo l'apprendimento automatico non supervisionato con algoritmi di clustering . Bene
utilizzare la riduzione della dimensionalità (con lo stimatore TSNE di scikitlearn) per comprimere il file

Le 64 funzioni del set di dati di cifre fino a due per scopi di visualizzazione. Questo ci consentirà
per vedere come i dati di Digits "si raggruppano". Questo set di dati contiene cifre scritte a mano
come quelli che i computer dell'ufficio postale devono riconoscere per indirizzare ogni lettera al suo
codice postale designato. Questo è un problema impegnativo di computervision, dato che ciascuno
la grafia della persona è unica. Tuttavia, costruiremo questo modello di clustering con pochi
righe di codice e ottenere risultati impressionanti. E lo faremo senza doverlo fare
comprendere il funzionamento interno dell'algoritmo di clustering. Questa è la bellezza dell'oggetto
programmazione basata. Vedremo di nuovo questo tipo di comoda programmazione basata su oggetti
nel prossimo capitolo, dove costruiremo potenti modelli di deep learning usando l'open
libreria di origine Keras.

K-Means Clustering e Iris Dataset

Presenteremo il più semplice algoritmo di apprendimento automatico non supervisionato, kmeans


clustering e usalo sul set di dati Iris che è anche in bundle con scikitlearn. Useremo
riduzione della dimensionalità (con lo stimatore PCA di scikitlearn) per comprimere l'iride
le quattro funzionalità del set di dati a due per scopi di visualizzazione. Mostreremo il raggruppamento di
tre specie di Iris nel set di dati e rappresentare graficamente il centroide di ciascun cluster , che è il cluster
punto centrale. Infine, eseguiremo più stimatori di cluster per confrontare la loro capacità con
dividere efficacemente i campioni del set di dati Iris in tre cluster.

Normalmente si specifica il numero desiderato di cluster, k . Kmeans lavora attraverso il


dati che cercano di dividerli in tanti cluster. Come con molti machine learning
algoritmi, kmeans è iterativo e gradualmente azzera i cluster per abbinare i file
numero specificato.

Il clustering di Kmeans può trovare somiglianze nei dati senza etichetta. Questo alla fine può aiutare

S
Pagina 594
con l'assegnazione di etichette a quei dati in modo che gli stimatori dell'apprendimento supervisionato possano quindi
elaboralo. Dato che è noioso e soggetto a errori per gli esseri umani dover assegnare etichette
dati senza etichetta e dato che la stragrande maggioranza dei dati mondiali è priva di etichetta,
l'apprendimento automatico senza supervisione è uno strumento importante.

Big Data e potenza di elaborazione di Big Computer

La quantità di dati disponibili oggi è già enorme e continua a crescere


esponenzialmente. I dati prodotti nel mondo negli ultimi anni sono pari alla quantità
prodotta fino a quel momento dagli albori della civiltà. Parliamo comunemente di grande
dati, ma "grande" potrebbe non essere un termine abbastanza forte per descrivere veramente quanto siano enormi i dati
ottenere.

La gente diceva "Sto annegando nei dati e non so cosa farne". Con
machine learning, ora diciamo: "Inondami di big data così posso utilizzare il machine learning
tecnologia per estrarre informazioni e fare previsioni ".

Ciò accade in un momento in cui la potenza di calcolo sta esplodendo e la memoria del computer
e lo storage secondario stanno esplodendo di capacità mentre i costi diminuiscono drasticamente. Tutto di
questo ci consente di pensare in modo diverso agli approcci alla soluzione. Ora possiamo programmare
computer per imparare dai dati, e molti altri. Ora si tratta solo di prevedere dai dati.

14.1.3 Set di dati in bundle con Scikit-Learn


1
La tabella seguente elenca i set di dati in bundle di scikitlearn . Fornisce anche funzionalità
per caricare set di dati da altre fonti, come gli oltre 20.000 set di dati disponibili all'indirizzo
openml.org.

1
ttp: //scikitlearn.org/stable/datasets/index.html .

Set di dati in bundle con scikitlearn

Set di dati "giocattolo" Set di dati del mondo reale

Prezzi delle case di Boston Olivetti si affaccia

Piante di iris 20 newsgroup di testo

Diabete Facce etichettate in faccia selvaggia


riconoscimento

hw
Pagina 595
Riconoscimento ottico del manoscritto Tipi di copertura forestale
cifre
RCV1
Linnerrud
Kddcup 99
Riconoscimento del vino
California Housing
Cancro al seno Wisconsin (diagnostico)

14.1.4 Fasi di un tipico studio di scienza dei dati


Eseguiremo i passaggi di un tipico caso di studio di machine learning, tra cui:

caricamento del set di dati

esplorare i dati con i panda e le visualizzazioni

trasformare i tuoi dati (convertire dati non numerici in dati numerici perché
scikitlearn richiede dati numerici, nel capitolo usiamo set di dati che sono "pronti per
vai ", ma discuteremo di nuovo il problema nel capitolo" Apprendimento approfondito ")

suddividendo i dati per l'addestramento e il test

creazione del modello

formazione e test del modello

messa a punto del modello e valutazione della sua accuratezza


fare previsioni su dati in tempo reale che il modello non ha visto prima.

In "ArrayOriented Programming with NumPy" e "Strings: A Deeper Look"


nei capitoli delle sezioni Introduzione alla scienza dei dati, abbiamo discusso dell'uso dei panda da affrontare
valori mancanti ed errati. Questi sono passaggi importanti per la pulizia dei dati prima
usandolo per l'apprendimento automatico.

14.2 CASO DI STUDIO: CLASSIFICAZIONE CON K-NEAREST


NEIGHBORS AND THE DIGITS DATASET, PARTE 1

Pagina 596
o elaborare la posta in modo efficiente e instradare ogni lettera alla destinazione corretta, postale
i computer di servizio devono essere in grado di eseguire la scansione di nomi, indirizzi e codici postali scritti a mano
e riconoscere le lettere e le cifre. Come vedrai in questo capitolo, potenti librerie come
scikitlearn consente anche ai programmatori alle prime armi di creare tali problemi di apprendimento automatico
gestibile. Nel prossimo capitolo useremo una computervision ancora più potente
capacità quando presentiamo la tecnologia di apprendimento profondo del neurale convoluzionale
reti.

Problemi di classificazione

In questa sezione, esamineremo la classificazione nell'apprendimento automatico supervisionato, che


2
tenta di prevedere la classe distinta a cui appartiene un campione. Ad esempio, se tu
avere immagini di cani e immagini di gatti, puoi classificare ogni immagine come "cane" o come
"gatto." Questo è un problema di classificazione binaria perché ci sono due classi.

2
Nota che il termine classe in questo caso significa categoria, non il concetto Python di a
classe.

3
Useremo il set di dati Digits in bundle con scikitlearn, che consiste in 8by8
immagini pixel che rappresentano 1797 cifre scritte a mano (da 0 a 9). Il nostro obiettivo è prevedere
quale cifra rappresenta un'immagine. Poiché ci sono 10 possibili cifre (le classi), questo è un file
problema di multiclassificazione . Si addestra un modello di classificazione utilizzando dati etichettati
—Conosciamo in anticipo la classe di ogni cifra. In questo caso di studio, useremo uno dei più semplici
algoritmi di classificazione di machine learning , knearest neighbors (kNN) , da riconoscere
cifre scritte a mano.

3
ttp: //scikitlearn.org/stable/datasets/index.html#optical
ecognitionofhandwrittendigitsdataset .

La seguente visualizzazione delle cifre a bassa risoluzione di un 5 è stata prodotta con Matplotlib
da dati grezzi di 8 x 8 pixel di una cifra. Mostreremo come visualizzare immagini come questa con
Matplotlib momentaneamente:

rT
h
Pagina 597
I ricercatori hanno creato le immagini in questo set di dati dalle decine del database MNIST
migliaia di immagini da 32 x 32 pixel prodotte nei primi anni '90. A oggi
risoluzioni di fotocamere e scanner ad alta definizione con cui è possibile acquisire tali immagini
risoluzioni molto più elevate.

Il nostro approccio
Tratteremo questo caso di studio in due sezioni. In questa sezione inizieremo con il basic
passaggi di un case study di machine learning:

Decidi i dati da cui addestrare un modello.

Carica ed esplora i dati.

Dividi i dati per l'addestramento e il test.

Seleziona e costruisci il modello.

Addestra il modello.

Fare previsioni.

Come vedrai, in scikitlearn ognuno di questi passaggi richiede al massimo poche righe di codice. Nel
nella prossima sezione, lo faremo

Valuta i risultati.

Regola il modello.

Esegui diversi modelli di classificazione per scegliere il migliore (i).

Pagina 598
Visualizzeremo i dati usando Matplotlib e Seaborn, quindi avvia IPython con
Supporto Matplotlib:

ipython matplotlib

14.2.1 Algoritmo k-Nearest Neighbors


Scikitlearn supporta molti algoritmi di classificazione , incluso il più semplice: k
vicini più vicini (kNN) . Questo algoritmo tenta di prevedere la classe di un campione di prova
osservando i k campioni di addestramento più vicini (in distanza) al campione di prova.
Ad esempio, si consideri il diagramma seguente in cui i punti pieni rappresentano quattro
classi di esempio: A, B, C e D. Per questa discussione, useremo queste lettere come classe
nomi:
Vogliamo prevedere le classi a cui appartengono i nuovi campioni X, Y e Z. Facciamo
supponiamo di voler fare queste previsioni usando i tre vicini più vicini di ogni campione
- tre è k nell'algoritmo dei vicini più simpatici:

I tre vicini più vicini del campione X sono tutti punti di classe D, quindi prediremmo che X's
classe è D.

I tre vicini più vicini del campione Y sono tutti punti di classe B, quindi prediremmo che la classe di Y.
è B.

Pagina 599
Per Z, la scelta non è così chiara, perché appare tra i punti B e C. Del
tre vicini più vicini, uno è di classe B e due sono di classe C. Nel più simpatico
algoritmo dei vicini, vince la classe con il maggior numero di "voti". Quindi, sulla base di due voti C.
a un voto B, prediremmo che la classe di Z è C. Scegliendo un valore k dispari nel kNN
l'algoritmo evita i pareggi garantendo che non ci sia mai un numero uguale di voti.

Iperparametri e ottimizzazione degli iperparametri

Nell'apprendimento automatico, un modello implementa un algoritmo di apprendimento automatico . In scikit


imparare, i modelli sono chiamati stimatori . Esistono due tipi di parametri nella macchina
apprendimento:

quelli che lo stimatore calcola man mano che apprende dai dati forniti e

quelli che specifichi in anticipo quando crei l'oggetto stimatore scikitlearn that
rappresenta il modello.

I parametri specificati in anticipo sono chiamati iperparametri .

Nell'algoritmo dei vicini più simpatici, k è un iperparametro. Per semplicità, useremo


valori dell'iperparametro predefinito di scikitlearn . Negli studi sul machine learning del mondo reale,
ti consigliamo di sperimentare diversi valori di k per produrre i migliori modelli possibili
per i tuoi studi. Questo processo è chiamato ottimizzazione degli iperparametri . Più tardi useremo
sintonizzazione iperparametro per scegliere il valore di k che abilita i vicini più scarsi
algoritmo per fare le migliori previsioni per il set di dati Digits. Scikitlearn ha anche
capacità di ottimizzazione automatizzata degli iperparametri.

14.2.2 Caricamento del set di dati


La funzione load_digits dal modulo sklearn.datasets restituisce uno scikit
impara l' oggetto Bunch contenente i dati delle cifre e le informazioni sul set di dati delle cifre
(chiamati metadati ):

lecca qui per visualizzare l'immagine del codice

In [1]: da sklearn.datasets importa load_digits

In [2]: digits = load_digits ()

Bunch è una sottoclasse di dict che ha attributi aggiuntivi per interagire con
set di dati.

D
C sta riproducendo la descrizione

Visualizzazione della descrizione Pagina 600

Il set di dati Digits in bundle con scikitlearn è un sottoinsieme dell'UCI (University of


California Irvine) Set di dati con cifre scritte a mano ML all'indirizzo:

ttp: //archive.ics.uci.edu/ml/datasets/Optical+Recognition+of+Handwritten+Digits

Il set di dati UCI originale contiene 5620 campioni: 3823 per l'addestramento e 1797 per
test. La versione del set di dati in bundle con scikitlearn contiene solo il 1797
campioni di prova . L' attributo DESCR di un gruppo contiene una descrizione del set di dati.
4
Secondo la descrizione del set di dati Digits , ogni campione ha 64 caratteristiche (come
specificato da Numero di attributi) che rappresentano un'immagine 8by8 con pixel

valori compresi tra 0 e 16 (specificati da Informazioni sugli attributi). Questo set di dati ha
nessun valore mancante (come specificato da Missing Attribute Values). Le 64 caratteristiche
può sembrare molto, ma i set di dati del mondo reale a volte possono contenere centinaia, migliaia
o anche milioni di funzionalità.

4
Abbiamo evidenziato alcune informazioni chiave in grassetto.

lecca qui per visualizzare l'immagine del codice

n [3]: stampa (cifre.DESCR)


.. _digits_dataset:

Riconoscimento ottico del dataset di cifre scritte a mano

** Caratteristiche del set di dati: **

: Numero di istanze: 5620


: Numero di attributi: 64
: Informazioni sugli attributi: immagine 8x8 di pixel interi nell'intervallo
0..16.
: Valori attributo mancanti: Nessuno
: Creatore: E. Alpaydin (alpaydin '@' boun.edu.tr)
: Data: luglio; 1998

Questa è una copia del set di prova dei set di dati con cifre scritte a mano dell'UCI ML
http://archive.ics.uci.edu/ml/datasets/
Ottico + Riconoscimento + di + cifre scritte a mano

Il set di dati contiene immagini di cifre scritte a mano: 10 classi dove


ogni classe si riferisce a una cifra.

Per l'estrazione sono stati utilizzati programmi di pre-elaborazione messi a disposizione dal NIST
bitmap normalizzate di cifre scritte a mano da un modulo prestampato. Da un
totale di 43 persone, 30 hanno contribuito al set formativo e differenti 13
al set di prova. Le bitmap 32x32 sono suddivise in blocchi non sovrapposti di

h
C
W
4x4 e il numero di pixel vengono contati in ogni blocco. Questo genera Pagina 601
una matrice di input di 8x8 in cui ogni elemento è un numero intero nell'intervallo
0..16. Questo riduce la dimensionalità e conferisce invarianza al piccolo
distorsioni.

Per informazioni sulle routine di pre-elaborazione NIST, vedere M. D. Garris, J. L. Blue, G.


T. Candela, D. L. Dimmick, J. Geist, P. J. Grother, S. A. Janet e C.
L. Wilson, NIST FormBased Handprint Recognition System, NISTIR 5469,
1994.

.. argomento :: Riferimenti

C. Kaynak (1995) Methods of Combining Multiple Classifiers and their


Applicazioni al riconoscimento delle cifre scritte a mano, tesi di laurea magistrale, istituto
of Graduate Studies in Science and Engineering, Bogazici University.
E. Alpaydin, C. Kaynak (1998) Cascading Classifiers, Kybernetika.
Ken Tang e Ponnuthurai N. Suganthan e Xi Yao e A. Kai Qin.
Riduzione della dimensionalità lineare utilizzando LDA ponderato in base alla rilevanza. Scuola
di ingegneria elettrica ed elettronica Nanyang tecnologica
Università. 2005.
Claudio Gentile. Una nuova classificazione del margine massimo approssimativo
Algoritmo. NIPS. 2000.

controllo delle dimensioni del campione e del target

I dati e gli attributi di destinazione dell'oggetto Bunch sono array NumPy:

L'array di dati contiene i 1797 campioni (le immagini delle cifre), ciascuno con 64 caratteristiche,
con valori compresi tra 0 e 16, che rappresentano le intensità dei pixel . Con Matplotlib,
visualizzeremo queste intensità in tonalità di scala di grigi dal bianco (0) al nero (16):

La matrice di destinazione contiene le etichette delle immagini, ovvero le classi che indicano quali

cifra ogni immagine rappresenta. L'array si chiama target perché, quando fai
previsioni, stai mirando a "centrare l'obiettivo" valori. Per vedere le etichette dei campioni
in tutto il set di dati, visualizziamo i valori target di ogni 100 ° campione:

lecca qui per visualizzare l'immagine del codice

In [4]: ​digits.target [:: 100 ]


Uscita [4]: ​matrice ([0, 4, 1, 7, 4, 8, 2, 2, 4, 4, 1, 9, 7, 3, 2, 1, 2, 5])

C
C
Pagina 602
Possiamo confermare il numero di campioni e caratteristiche (per campione) guardando il file

l'attributo shape dell'array di dati, che mostra che ci sono 1797 righe (campioni) e 64
colonne (caratteristiche):

lecca qui per visualizzare l'immagine del codice

In [5]: digits.data.shape
Uscita [5]: (1797, 64)

È possibile confermare che il numero di valori target corrisponde al numero di campioni di


guardando la forma della matrice di destinazione:

lecca qui per visualizzare l'immagine del codice


In [6]: digits.target.shape
Uscita [6]: (1797,)

Un'immagine di cifre di esempio

Ogni immagine è bidimensionale: ha una larghezza e un'altezza in pixel. L'oggetto Bunch


restituito da load_digits contiene un attributo images, un array in cui ogni
L'elemento è un array bidimensionale 8by8 che rappresenta le intensità dei pixel dell'immagine di una cifra.
Sebbene il set di dati originale rappresenti ogni pixel come un valore intero compreso tra 0 e 16, scikit
imparare memorizza questi valori come virgola mobile valori (NumPy tipo float64). Per esempio,
ecco l'array bidimensionale che rappresenta l'immagine campione all'indice 13:

lecca qui per visualizzare l'immagine del codice

In [7]: digits.images [ 13 ]
Fuori [7]:
matrice ([[0., 2., 9., 15., 14., 9., 3., 0.],
[0., 4., 13., 8., 9., 16., 8., 0.],
[0., 0., 0., 6., 14., 15., 3., 0.],
[0., 0., 0., 11., 14., 2., 0., 0.],
[0., 0., 0., 2., 15., 11., 0., 0.],
[0., 0., 0., 0., 2., 15., 4., 0.],
[0., 1., 5., 6., 13., 16., 6., 0.],
[0., 2., 12., 12., 13., 11., 0., 0.]])

ed ecco l'immagine rappresentata da questo array bidimensionale: presto mostreremo il file


codice per la visualizzazione di questa immagine:

C
Pagina 603

Preparazione dei dati per l'uso con Scikit-Learn

Gli algoritmi di apprendimento automatico di Scikitlearn richiedono che i campioni siano memorizzati in due
array bidimensionale di valori in virgola mobile (o bidimensionale arraylike raccolta,
come un elenco di elenchi o un DataFrame panda):

Ogni riga rappresenta un campione .

Ogni colonna in una determinata riga rappresenta una caratteristica per quel campione.

Per rappresentare ogni campione come una riga, dati multidimensionali come il bidimensionale
l'array di immagini mostrato nello snippet [7] deve essere appiattito in un array monodimensionale.

Se stavi lavorando con dati contenenti caratteristiche categoriali (in genere


rappresentato come stringhe, come "spam" o "notspam"), dovresti anche preelaborarlo
queste caratteristiche in valori numerici, noti come codifica onehot, di cui trattiamo
il prossimo capitolo. Fornisce il modulo sklearn.preprocessing di Scikitlearn

capacità per convertire i dati categoriali in dati numerici. Il set di dati Digits non ha
caratteristiche categoriali.

Per tua comodità, la funzione load_digits restituisce i dati preelaborati pronti


per l'apprendimento automatico. Il set di dati Digits è numerico, quindi load_digits si appiattisce semplicemente
l'array bidimensionale di ciascuna immagine in un array monodimensionale. Ad esempio, 8
by8 array digits.images [13] mostrato nello snippet [7] corrisponde a 1by64
array digits.data [13] mostrato di seguito:

lecca qui per visualizzare l'immagine del codice

In [8]: digits.data [ 13 ]
Fuori [8]:
matrice ([0., 2., 9., 15., 14., 9., 3., 0., 0., 4., 13., 8., 9.,

16., 8., 0., 0., 0., 0., 6., 14., 15., 3., 0., 0., 0., Pagina 604
0., 11., 14., 2., 0., 0., 0., 0., 0., 2., 15., 11., 0.,
0., 0., 0., 0., 0., 2., 15., 4., 0., 0., 1., 5., 6.,
13., 16., 6., 0., 0., 2., 12., 12., 13., 11., 0., 0.])

In questo array unidimensionale, i primi otto elementi sono l'array bidimensionale


riga 0, i successivi otto elementi sono la riga 1 dell'array bidimensionale e così via.

14.2.3 Visualizzazione dei dati


Dovresti sempre familiarizzare con i tuoi dati. Questo processo è chiamato dati
esplorazione . Per le immagini delle cifre, puoi avere un'idea di come sono
visualizzandoli con la funzione implot Matplotlib. L'immagine seguente mostra il file
le prime 24 immagini del set di dati. Per vedere quanto sia difficile il riconoscimento delle cifre scritte a mano
cioè, considera le variazioni tra le immagini delle 3 nella prima, terza e quarta
righe e guarda le immagini dei 2 nella prima, terza e quarta riga.

Creazione del diagramma

Diamo un'occhiata al codice che mostrava queste 24 cifre. La seguente chiamata alla funzione
subplots crea una figura di 6 x 4 pollici (specificata dalla parola chiave figsize (6, 4)
argomento) contenente 24 sottotrame disposte su 4 righe (nrows = 4) e 6 colonne
(ncols = 6). Ogni sottotrama ha il proprio oggetto Axes, che useremo per visualizzare una cifra
Immagine:
lecca qui per visualizzare l'immagine del codice Pagina 605

In [9]: importa matplotlib.pyplot come plt

In [10]: figura, assi = plt.subplots (nrows =4 , ncols = 6 , figsize = ( 6 , 4 ))

Le sottotrame delle funzioni restituiscono gli oggetti Axes in un array NumPy bidimensionale.

Inizialmente, la figura appare come mostrato di seguito con le etichette (che rimuoveremo) su ogni file
assi x e y della sottotrama :

Visualizzazione di ciascuna immagine e rimozione delle etichette degli assi

Quindi, usa un'istruzione for con la funzione zip incorporata per iterare in parallelo
i 24 oggetti Assi, le prime 24 immagini in digits.images ei primi 24 valori in

digits.target:

lecca qui per visualizzare l'immagine del codice

In [11]: per l' elemento in zip (axes.ravel (), digits.images, digits.target):


...: assi, immagine, target = elemento
...: axes.imshow (image, cmap = plt.cm.gray_r )
...: axes.set_xticks ([]) # rimuove i segni di graduazione dell'asse x
...: axes.set_yticks ([]) # rimuove i segni di graduazione yaxis
...: axes.set_title (target)
...: plt.tight_layout ()

...: Pagina 606


...:

Ricorda che il metodo array NumPy ravel crea una vista unidimensionale di un file
array multidimensionale. Inoltre, ricorda che zip produce tuple contenenti elementi da
lo stesso indice in ciascuno degli argomenti di zip e quello con il minor numero di
elementi determina quante tuple restituisce zip.

Ogni iterazione del ciclo:

Decomprime una tupla dagli elementi compressi in tre variabili che rappresentano il file

Oggetto assi, immagine e valore target.

Chiama il metodo imshow dell'oggetto Axes per visualizzare un'immagine. La parola chiave
argomento cmap = plt.cm.gray_r determina i colori visualizzati nell'immagine.
Il valore plt.cm.gray_r è una mappa dei colori, un gruppo di colori che sono tipicamente
scelti per lavorare bene insieme. Questa particolare mappa a colori ci consente di visualizzare il file
pixel dell'immagine in scala di grigi, con 0 come bianco, 16 come nero e i valori intermedi come
sfumature di grigio che si scuriscono gradualmente. Per i nomi delle mappe dei colori di Matplotlib vedere
ttps: //matplotlib.org/examples/color/colormaps_reference.html .
Ciascuno è accessibile tramite l'oggetto plt.cm o tramite una stringa, come "gray_r".

Chiama i metodi set_xticks e set_yticks dell'oggetto Axes con elenchi vuoti a


indicano che le x ed y assi non devono avere segni di graduazione.

Chiama il metodo set_title dell'oggetto Axes per visualizzare il valore di destinazione sopra
immagine: mostra il valore effettivo rappresentato dall'immagine.

Dopo il ciclo, chiamiamo tight_layout per rimuovere lo spazio bianco extra nella figura
in alto, a destra, in basso e a sinistra, in modo che le righe e le colonne delle immagini delle cifre possano riempire più file

Figura.

14.2.4 Suddivisione dei dati per addestramento e test


In genere si addestra un modello di apprendimento automatico con un sottoinsieme di un set di dati. In genere, il file
più dati hai per l'addestramento, meglio puoi addestrare il modello. È importante impostare
accantonare una parte dei dati per il test, in modo da poter valutare le prestazioni di un modello
utilizzando dati che il modello non ha ancora visto. Una volta che sei sicuro che il modello lo sia
se funziona bene, puoi usarlo per fare previsioni utilizzando nuovi dati che non ha visto.

h
Pagina 607
Per prima cosa suddividiamo i dati in un set di addestramento e un set di test per prepararci alla formazione e
prova il modello. La funzione train_test_split di

Il modulo sklearn.model_selection mescola i dati per renderli casuali, quindi divide il file
campioni nella matrice di dati e i valori di destinazione nella matrice di destinazione in addestramento e
set di test. Questo aiuta a garantire che i set di addestramento e test siano simili
caratteristiche. Il mescolamento e la divisione vengono eseguiti comodamente da un file
Oggetto ShuffleSplit dal modulo sklearn.model_selection. Funzione
train_test_split restituisce una tupla di quattro elementi in cui i primi due sono i file
i campioni si dividono in set di addestramento e test e gli ultimi due sono i corrispondenti
valori target suddivisi in set di addestramento e test. Per convenzione, viene utilizzata la X maiuscola
rappresentano i campioni e la y minuscola viene utilizzata per rappresentare i valori target:

lecca qui per visualizzare l'immagine del codice

In [12]: from sklearn.model_selection import train_test_split

In [13]: X_train, X_test, y_train, y_test = train_test_split (


...: digits.data, digits.target, random_state = 11 )
...:

Assumiamo che i dati abbiano classi bilanciate, ovvero che i campioni siano divisi equamente
tra le classi. Questo è il caso di ciascuna classificazione in bundle di scikitlearn
set di dati. Le classi sbilanciate potrebbero portare a risultati errati.

Nel capitolo "Funzioni", hai visto come eseguire il seeding di un generatore di numeri casuali
riproducibilità . Negli studi sull'apprendimento automatico, questo aiuta gli altri a confermare i tuoi risultati
lavorare con gli stessi dati selezionati in modo casuale. Funzione train_test_split
fornisce l'argomento parola chiave random_state per la riproducibilità . Quando esegui il file
codice in futuro con lo stesso valore seed, train_test_split selezionerà lo stesso
dati per il set di addestramento e gli stessi dati per il set di test. Abbiamo scelto il valore del seme
(11) arbitrariamente.

Dimensioni dei set di addestramento e test

Guardando le forme di X_train e X_test, puoi vedere che, per impostazione predefinita ,

train_test_split riserva il 75% dei dati per la formazione e il 25% per i test:

lecca qui per visualizzare l'immagine del codice

In [14]: X_train.shape
Uscita [14]: (1347, 64)

C
Pagina 608
In [15]: X_test.shape
Uscita [15]: (450, 64)

Per specificare divisioni diverse , è possibile impostare le dimensioni dei set di test e training con
Gli argomenti delle parole chiave della funzione train_test_split test_size e train_size.
Utilizzare valori a virgola mobile compresi tra 0,0 e 1,0 per specificare le percentuali dei dati a
utilizzare per ciascuno. È possibile utilizzare valori interi per impostare il numero esatto di campioni. Se tu
specificare uno di questi argomenti di parole chiave, l'altro viene dedotto. Ad esempio, il file
dichiarazione

lecca qui per visualizzare l'immagine del codice

X_train, X_test, y_train, y_test = train_test_split (


digits.data, digits.target, random_state = 11 , test_size = 0.20 )

specifica che il 20% dei dati è per il test, quindi train_size è dedotto come 0.80.

14.2.5 Creazione del modello


Lo stimatore KNeighborsClassifier (modulo sklearn.neighbors ) implementa

l'algoritmo dei vicini più simpatici. Innanzitutto, creiamo il KNeighborsClassifier


oggetto stimatore:

lecca qui per visualizzare l'immagine del codice

In [16]: from sklearn.neighbors import KNeighborsClassifier

In [17]: knn = KNeighborsClassifier ()

Per creare uno stimatore, devi semplicemente creare un oggetto. I dettagli interni di come questo
oggetto implementa l'algoritmo dei vicini più simpatici nascosti nell'oggetto. Tu
chiama semplicemente i suoi metodi. Questa è l'essenza della programmazione basata su oggetti Python .

14.2.6 Addestramento del modello


Successivamente, invochiamo il metodo fit dell'oggetto KNeighborsClassifier , che carica il file
sample training set (X_train) e target training set (y_train) nello stimatore:

lecca qui per visualizzare l'immagine del codice

C
Pagina 609
In [18]: knn.fit (X = X_train, y = y_train)
Fuori [18]:
KNeighborsClassifier (algoritmo = 'auto', leaf_size = 30, metric = 'minkowski',
metric_params = Nessuno, n_jobs = Nessuno, n_neighbors = 5, p = 2,
weights = 'uniform')

Per la maggior parte degli stimatori scikitlearn, il metodo di adattamento carica i dati nello stimatore

quindi utilizza quei dati per eseguire calcoli complessi dietro le quinte da cui apprendere
i dati e addestrare il modello. Il metodo di adattamento di KNeighborsClassifier viene caricato
i dati nello stimatore, perché kNN in realtà non ha un processo di apprendimento iniziale. Il
si dice che lo stimatore sia pigro perché il suo lavoro viene eseguito solo quando lo si utilizza per fare
predizioni. In questo e nel prossimo capitolo, utilizzerai molti modelli significativi
fasi di formazione. Nelle applicazioni di machine learning del mondo reale, a volte può richiedere
minuti, ore, giorni o addirittura mesi per addestrare i tuoi modelli. Vedremo nel prossimo capitolo,
"Deep Learning", quell'hardware speciale e ad alte prestazioni chiamato GPU e
Le TPU possono ridurre significativamente il tempo di addestramento del modello.

Come mostrato nell'output di snippet [18], il metodo fit restituisce lo stimatore, quindi IPython
mostra la sua rappresentazione di stringa, che include le impostazioni predefinite dello stimatore . Il
Il valore di n_neighbors corrisponde a k nell'algoritmo di knearest neighbors. Per impostazione predefinita,
a KNeighborsClassifier guarda i cinque vicini più vicini per fare le sue previsioni.
Per semplicità, generalmente utilizziamo le impostazioni predefinite dello stimatore. Per
KNeighborsClassifier, questi sono descritti in:

ttp: // scikit
guadagna.org/stable/modules/generated/sklearn.neighbors.KNeighborsClassifier.html

Molte di queste impostazioni esulano dallo scopo di questo libro. Nella parte 2 di questo caso di studio,
discuteremo come scegliere il miglior valore per n_neighbors.

14.2.7 Previsione delle classi di cifre


Ora che abbiamo caricato i dati in KNeighborsClassifier, possiamo usarli con
i campioni di prova per fare previsioni. Chiamando il metodo di previsione dello stimatore con

X_test come argomento restituisce un array contenente la classe prevista di ogni test
Immagine:

lecca qui per visualizzare l'immagine del codice

In [19]: predicted = knn.predict (X = X_test)

lh
C
Pagina 610
In [20]: previsto = y_test

Diamo un'occhiata alle cifre previste rispetto alle cifre previste per i primi 20 campioni di test:

lecca qui per visualizzare l'immagine del codice

In [21]: predetto [: 20 ]
Uscita [21]: matrice ([0, 4, 9, 9, 3, 1, 4, 1, 5, 0, 4, 9, 4, 1, 5, 3, 3, 8, 5, 6)

n [22]: previsto [: 20 ]
Uscita [22]: array ([0, 4, 9, 9, 3, 1, 4, 1, 5, 0, 4, 9, 4, 1, 5, 3, 3, 8, 3, 6)

s puoi vedere, nei primi 20 elementi, solo gli array previsti e attesi '
i valori all'indice 18 non corrispondono. Ci aspettavamo un 3, ma il modello prevedeva un 5.

Usiamo una comprensione dell'elenco per individuare tutte le previsioni errate per l' intero test
set, ovvero i casi in cui i valori previsti e attesi non corrispondono:

lecca qui per visualizzare l'immagine del codice

In [23]: sbagliato = [(p, e) for (p, e) in zip (predetto, atteso) se p! =]

n [24]: sbagliato
Fuori [24]:
[(5, 3),
(8, 9),
(4, 9),
(7, 3),
(7, 4),
(2, 8),
(9, 8),
(3, 8),
(3, 8),
(1, 8)]

La comprensione dell'elenco utilizza zip per creare tuple contenenti il ​corrispondente


elementi previsti e attesi. Includiamo una tupla nel risultato solo se è p
(il valore previsto) ed e (il valore atteso) differiscono, ovvero il valore previsto era
sbagliato. In questo esempio, lo stimatore ha previsto in modo errato solo 10 dei 450 test
campioni. Quindi l'accuratezza della previsione di questo stimatore è addirittura del 97,78%
sebbene abbiamo usato solo i parametri di default dello stimatore.

1CUN
io
io 4.3 CASO DI STUDIO: CLASSIFICAZIONE CON K-NEAREST
Pagina 611
14.3 CASO DI STUDIO: CLASSIFICAZIONE CON K-NEAREST
NEIGHBORS AND THE DIGITS DATASET, PARTE 2
In questa sezione, continuiamo il case study sulla classificazione delle cifre. Bene:

valutare l'accuratezza dello stimatore della classificazione kNN,

eseguire più stimatori e confrontare i loro risultati in modo da poter scegliere il file
il migliore (i), e

mostra come regolare l'iperparametro kNN k per ottenere le migliori prestazioni da un file
KNeighborsClassifier.

14.3.1 Metriche per l'accuratezza del modello


Dopo aver addestrato e testato un modello, ti consigliamo di misurarne l'accuratezza. Ecco, lo faremo
guarda due modi per farlo: un metodo del punteggio dello stimatore di classificazione e a
matrice di confusione .

Punteggio del metodo della stima

Ogni stimatore ha un metodo di punteggio che restituisce un'indicazione di quanto bene il


lo stimatore esegue per i dati di test che passi come argomenti. Per la classificazione
stimatori, questo metodo restituisce l' accuratezza della previsione per i dati del test:

lecca qui per visualizzare l'immagine del codice

In [25]: print (f ' {knn.score (X_test, y_test): .2 %} ' )


97,78%
Il kNeighborsClassifier con il suo valore predefinito k (ovvero n_neighbors = 5) raggiunto
Precisione della previsione del 97,78%. A breve, eseguiremo l'ottimizzazione degli iperparametri per provare
determinare il valore ottimale per k , sperando di ottenere una precisione ancora migliore.

Matrice di confusione

Un altro modo per verificare l'accuratezza di uno stimatore di classificazione è tramite una matrice di confusione ,
che mostra i valori previsti corretti e non corretti (noti anche come hit e
manca ) per una determinata classe. Chiama semplicemente la funzione confusion_matrix dal file

modulo sklearn.metrics , passando le classi previste e quelle previste


classi come argomenti, come in:

C
Pagina 612
lecca qui per visualizzare l'immagine del codice

In [26]: da sklearn.metrics import confusion_matrix

In [27]: confusion = confusion_matrix (y_true = atteso, y_pred = predetto)

L'argomento della parola chiave y_true specifica le classi effettive dei campioni di prova. La gente guardava
alle immagini del set di dati e le etichettiamo con classi specifiche (i valori delle cifre). Il

L'argomento della parola chiave y_pred specifica le cifre previste per quelle immagini di prova.

Di seguito è riportata la matrice di confusione prodotta dalla chiamata precedente. Le previsioni corrette
sono mostrati sulla diagonale da in alto a sinistra a in basso a destra. Questo è chiamato il principale
diagonale . I valori diversi da zero che non sono sulla diagonale principale indicano errati
predizioni:

lecca qui per visualizzare l'immagine del codice

In [28]: confusione
Fuori [28]:
matrice ([[45, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 45, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 54, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 42, 0, 1, 0, 1, 0, 0],
[0, 0, 0, 0, 49, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 38, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 42, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 45, 0, 0],
[0, 1, 1, 2, 0, 0, 0, 0, 39, 1],
[0, 0, 0, 0, 1, 0, 0, 0, 1, 41]])

Ogni riga rappresenta una classe distinta, ovvero una delle cifre da 0 a 9. Le colonne
all'interno di una riga specificare quanti dei campioni di prova sono stati classificati in ogni distinto
classe. Ad esempio, riga 0:

lecca qui per visualizzare l'immagine del codice

[45, 0, 0, 0, 0, 0, 0, 0, 0, 0]

rappresenta la classe della cifra 0. Le colonne rappresentano le dieci possibili classi di destinazione 0
fino a 9. Poiché stiamo lavorando con cifre, le classi (0-9) e la riga e
i numeri di indice delle colonne (0–9) coincidono. Secondo la riga 0, 45 campioni di prova

C
Pagina 613
sono stati classificati come cifra 0 e nessuno dei campioni di prova è stato classificato erroneamente come uno di
le cifre da 1 a 9. Quindi il 100% degli 0 è stato previsto correttamente.

D'altra parte, considera la riga 8 che rappresenta i risultati per la cifra 8:

lecca qui per visualizzare l'immagine del codice

[0, 1, 1, 2, 0, 0, 0, 0, 39, 1]

L'1 all'indice di colonna 1 indica che un 8 è stato classificato erroneamente come 1.

L'1 nell'indice di colonna 2 indica che un 8 è stato classificato erroneamente come 2.

Il 2 all'indice di colonna 3 indica che due 8 sono stati classificati erroneamente come 3.

Il 39 all'indice di colonna 8 indica che 39 8 sono stati correttamente classificati come 8.

L'1 nell'indice di colonna 9 indica che un 8 è stato classificato erroneamente come 9.

Quindi l'algoritmo ha previsto correttamente l'88,63% (39 su 44) degli 8. L'abbiamo visto prima
l'accuratezza complessiva della previsione di questo stimatore è stata del 97,78%. La previsione inferiore
la precisione per 8 secondi indica che sono apparentemente più difficili da riconoscere rispetto agli altri
cifre.

Rapporto di classificazione
Il modulo sklearn.metrics fornisce anche la funzione classification_report ,
5
che produce una tabella di metriche di classificazione basata sull'atteso e
valori previsti:

5
ttp: // scikit
learn.org/stable/modules/model_evaluation.html#precisionrecall
ndfmeasures .

lecca qui per visualizzare l'immagine del codice

In [29]: da sklearn.metrics import classification_report

In [30]: names = [str (digit) for digit in digits.target_names]

In [31]: print (classification_report (expected, predicted,


...: target_names = nomi))

C
h
un'
...: Pagina 614
supporto di richiamo di precisione f1score

0 1,00 1,00 1,00 45


1 0,98 1,00 0,99 45
2 0,98 1,00 0,99 54
3 0,95 0,95 0,95 44
4 0,98 0,98 0,98 50
5 0,97 1,00 0,99 38
6 1,00 1,00 1,00 42
7 0,96 1,00 0,98 45
8 0,97 0,89 0,93 44
9 0,98 0,95 0,96 43

micro media 0,98 0,98 0,98 450


media macro 0,98 0,98 0,98 450
media ponderata 0,98 0,98 0,98 450
Nella relazione:

la precisione è il numero totale di previsioni corrette per una data cifra diviso per
numero totale di previsioni per quella cifra. Puoi confermare la precisione guardando
in ogni colonna nella matrice di confusione. Ad esempio, se osservi l'indice di colonna 7,
vedrai 1 nelle righe 3 e 4, a indicare che uno 3 e uno 4 non erano corretti
classificato come 7 e un 45 nella riga 7 che indica che le 45 immagini sono state classificate correttamente
come 7s. Quindi la precisione per la cifra 7 è 45/47 o 0,96.

il richiamo è il numero totale di previsioni corrette per una data cifra diviso per il totale
numero di campioni che avrebbero dovuto essere previsti come quella cifra. Puoi confermare
il richiamo guardando ogni riga nella matrice di confusione. Ad esempio, se guardi
indice di riga 8, vedrai tre 1 e un 2 che indicano che alcuni 8 erano errati
classificato come altre cifre e un 39 che indica che 39 immagini sono state classificate correttamente.
Quindi il richiamo per la cifra 8 è 39/44 o 0,89.

f1score -Questa è la media della precisione e del richiamo .

supporto : il numero di campioni con un dato valore atteso. Ad esempio, 50


i campioni sono stati etichettati come 4s e 38 campioni sono stati etichettati come 5s.

Per i dettagli sulle medie visualizzate nella parte inferiore del report, vedere:

ttp: // scikit
guadagna.org/stable/modules/generated/sklearn.metrics.classification_report.html

V
lh isualizzare la Confusion Matrix

Visualizzazione della matrice di confusione Pagina 615

Una mappa termica visualizza i valori come colori, spesso con valori di grandezza maggiore visualizzati
come colori più intensi. Le funzioni grafiche di Seaborn funzionano con dati bidimensionali.
Quando si utilizza un DataFrame panda come origine dati, Seaborn le etichetta automaticamente
visualizzazioni che utilizzano i nomi delle colonne e gli indici di riga. Convertiamo la confusione
matrice in un DataFrame, quindi rappresentalo graficamente:

lecca qui per visualizzare l'immagine del codice

In [32]: importa i panda come pd

In [33]: confusion_df = pd.DataFrame (confusion, index = range ( 10 ),


...: colonne = intervallo ( 10 ))
...:

In [34]: importa seaborn come sns

In [35]: axes = sns.heatmap (confusion_df, annot = True ,


...: cmap = 'nipy_spectral_r' )
...:

La funzione Seaborn mappa termica crea una mappa di calore dal dataframe specificato. Il
l'argomento della parola chiave annot = True (abbreviazione di "annotation") mostra una barra colorata per il file
a destra del diagramma, che mostra come i valori corrispondono ai colori della mappa termica. Il

cmap = L'argomento della parola chiave "nipy_spectral_r" specifica quale mappa dei colori utilizzare. Noi
ha utilizzato la mappa dei colori nipy_spectral_r con i colori mostrati nel colore della mappa termica
bar. Quando visualizzi una matrice di confusione come mappa termica, la diagonale principale e il file
le previsioni sbagliate risaltano bene.
C
Pagina 616

14.3.2 K-Fold Cross-Validation


Kfold convalida incrociata consente di utilizzare tutti i dati per entrambi la formazione e
test, per avere un'idea migliore di quanto bene il tuo modello farà previsioni per nuovi dati
addestrando e testando ripetutamente il modello con diverse parti del set di dati. K
fold crossvalidation divide il set di dati in k è uguale a pieghe (questo k non è correlato a k in
l'algoritmo dei vicini più simpatici). Quindi addestrate ripetutamente il vostro modello con k - 1
pieghe e prova il modello con la piega rimanente. Ad esempio, considera l'utilizzo di k = 10
con le pieghe numerate da 1 a 10. Con 10 pieghe, faremmo 10 allenamenti successivi e
cicli di prova:

Per prima cosa, ci alleniamo con le pieghe 1-9, quindi testiamo con la piega 10.

Successivamente, ci alleniamo con le pieghe 1–8 e 10, quindi testiamo con la piega 9.

Successivamente, ci alleniamo con le pieghe 1–7 e 9-10, quindi testiamo con la piega 8.

Questo ciclo di addestramento e test continua finché ogni piega non è stata utilizzata per testare il file
modello.

K Fold Class
Pagina 617
Classe KFold
Scikitlearn fornisce la classe KFold e la funzione cross_val_score (entrambe in
il modulo sklearn.model_selection) per aiutarti a eseguire la formazione e
cicli di prova sopra descritti. Eseguiamo la convalida incrociata kfold con le cifre
dataset e KNeighborsClassifier creato in precedenza. Innanzitutto, crea un oggetto KFold:

lecca qui per visualizzare l'immagine del codice

In [36]: from sklearn.model_selection importa KFold

In [37]: kfold = KFold (n_splits = 10 , random_state = 11 , shuffle = True )

Gli argomenti delle parole chiave sono:

n_splits = 10, che specifica il numero di pieghe.

random_state = 11, che esegue il seed del generatore di numeri casuali


riproducibilità .

shuffle = True, che fa sì che l'oggetto KFold renda casualmente i dati mescolando
prima di dividerlo in pieghe. Ciò è particolarmente importante se i campioni potrebbero esserlo
ordinato o raggruppato. Ad esempio, il set di dati Iris che useremo più avanti in questo capitolo ha
150 campioni di tre specie di Iris : le prime 50 sono Iris setosa , le successive 50 sono Iris
versicolor e gli ultimi 50 sono Iris virginica . Se non mescoliamo i campioni, allora
i dati di addestramento potrebbero non contenere nessuna specie di Iris particolare ei dati di prova
potrebbe essere tutto di una specie.

Usare l'oggetto KFold con la funzione cross_val_score

Successivamente, utilizza la funzione cross_val_score per addestrare e testare il tuo modello:

lecca qui per visualizzare l'immagine del codice

In [38]: from sklearn.model_selection import cross_val_score

In [39]: score = cross_val_score (estimator = knn, X = digits.data,


...: y = digits.target, cv = kfold)
...:

Gli argomenti delle parole chiave sono:

C
Pagina 618
estimator = knn, che specifica lo stimatore che desideri convalidare.

X = digits.data, che specifica i campioni da utilizzare per l'addestramento e il test.

y = digits.target, che specifica le previsioni di destinazione per i campioni.

cv = kfold, che specifica il generatore di convalida incrociata che definisce come suddividere
i campioni e gli obiettivi per la formazione e il test.

La funzione cross_val_score restituisce un array di punteggi di precisione, uno per ogni piega. Come
puoi vedere sotto, il modello era abbastanza preciso. Il suo punteggio di precisione più basso era
0,97777778 (97,78%) e in un caso era accurato al 100% nel prevedere un intero
piega:
lecca qui per visualizzare l'immagine del codice

In [40]: punteggi
Fuori [40]:
matrice ([0.97777778, 0.99444444, 0.98888889, 0.97777778, 0.98888889,
0.99444444, 0.97777778, 0.98882682, 1., 0.98324022])

Una volta ottenuti i punteggi di precisione, puoi avere un'idea generale dell'accuratezza del modello
calcolando il punteggio medio di accuratezza e la deviazione standard tra i 10
punteggi di precisione (o qualunque sia il numero di pieghe che scegli):

lecca qui per visualizzare l'immagine del codice

In [41]: print (f 'Precisione media: {score.mean (): .2 %} ' )


Precisione media: 98,72%

In [42]: print (f 'Deviazione standard accuratezza: {score.std (): .2 %} ' )


Deviazione standard di precisione: 0,75%

In media, il modello era accurato al 98,72%, persino migliore del 97,78% che abbiamo ottenuto
quando abbiamo addestrato il modello con il 75% dei dati e testato il modello con il 25% in precedenza.

14.3.3 Esecuzione di più modelli per trovare quello migliore


È difficile sapere in anticipo per quali modelli di machine learning funzioneranno meglio
un dato set di dati, soprattutto quando nascondono i dettagli di come operano dal proprio
utenti. Anche se KNeighborsClassifier prevede immagini con cifre elevate

C
Pagina 619
grado di accuratezza, è possibile che altri stimatori di scikitlearn lo siano ancora di più
accurato. Scikitlearn fornisce molti modelli con i quali puoi allenarti e testare rapidamente
i tuoi dati. Questo ti incoraggia a eseguire più modelli per determinare qual è il migliore
per un particolare studio di machine learning.

Usiamo le tecniche della sezione precedente per confrontare diverse classificazioni


stimatori: KNeighborsClassifier, SVC e GaussianNB (ce ne sono altri).
Sebbene non abbiamo studiato gli stimatori SVC e GaussianNB, scikitlearn
6
tuttavia rende facile testdriverli utilizzando le impostazioni predefinite.
Per prima cosa, importiamo gli altri due stimatori:

6
Per evitare un avviso nella versione corrente di scikitlearn al momento della stesura di questo documento
(versione 0.20), abbiamo fornito un argomento per la parola chiave durante la creazione dello stimatore SVC.

Il valore di questo argomento diventerà il valore predefinito nella versione 0.22 di scikitlearn.

lecca qui per visualizzare l'immagine del codice

In [43]: da sklearn.svm import SVC

In [44]: da sklearn.naive_bayes importa GaussianNB

Successivamente, creiamo gli stimatori. Il seguente dizionario contiene coppie chiave-valore per
il KNeighborsClassifier esistente che abbiamo creato in precedenza, più il nuovo SVC e

Stimatori Gaussian NB:

lecca qui per visualizzare l'immagine del codice


In [45]: estimators = {
...: "KNeighborsClassifier" : knn,
...: 'SVC' : SVC (gamma = 'scale' ),
...: 'GaussianNB' : GaussianNB ()}
...:

Ora possiamo eseguire i modelli:

lecca qui per visualizzare l'immagine del codice

In [46]: per estimator_name, estimator_object in estimators.items ():


...: kfold = KFold (n_splits = 10 , random_state = 11 , shuffle = True )
...: score = cross_val_score (estimator = estimator_object,
...: X = digits.data, y = digits.target, cv = kfold)
...: print (f ' {estimator_name:> 20 } :' +

...: f 'accuratezza media = {score.mean (): .2 %} ;' + Pagina 620


...: f 'deviazione standard = {score.std (): .2 %} ' )
...:
KNeighborsClassifier: precisione media = 98,72%; deviazione standard = 0,75%
SVC: precisione media = 99,00%; deviazione standard = 0,85%
NB gaussiano: precisione media = 84,48%; deviazione standard = 3,47%

Questo ciclo itera attraverso gli elementi nel dizionario degli stimatori e per ogni valore chiave
pair esegue le seguenti attività:

Decomprime la chiave in estimator_name e il valore in estimator_object.

Crea un oggetto KFold che mescola i dati e produce 10 pieghe. La parola chiave
l'argomento random_state è particolarmente importante qui perché lo assicura

ogni stimatore funziona con pieghe identiche, quindi stiamo confrontando "mele con mele".

Valuta l'attuale estimator_object utilizzando cross_val_score.

Stampa il nome dello stimatore, seguito dalla media e dalla deviazione standard di
punteggi di precisione calcolati per ciascuna delle 10 pieghe.

Sulla base dei risultati, sembra che possiamo ottenere una precisione leggermente migliore dall'SVC
stimatore: almeno quando si utilizzano le impostazioni predefinite dello stimatore. È possibile che da
sintonizzando alcune delle impostazioni degli stimatori, potremmo ottenere risultati ancora migliori. Il
Le precisioni di KNeighborsClassifier e SVC sono quasi identiche, quindi noi
potrebbe voler eseguire l'ottimizzazione degli iperparametri su ciascuno per determinare il migliore.

Diagramma della stima di Scikit-Learn

La documentazione di scikitlearn fornisce un diagramma utile per la scelta del diritto


stimatore, in base al tipo e alla dimensione dei dati e al compito di apprendimento automatico
desidera eseguire:

ttps: //scikitlearn.org/stable/tutorial/machine_learning_map/index.html

14.3.4 Ottimizzazione iperparametro


In precedenza in questa sezione, abbiamo accennato al fatto che k nell'algoritmo dei vicini più affezionati è a
iperparametro dell'algoritmo. Gli iperparametri vengono impostati prima di utilizzare l'algoritmo
per addestrare il tuo modello. Negli studi sull'apprendimento automatico del mondo reale, ti consigliamo di utilizzare
ottimizzazione iperparametro per scegliere valori iperparametrici che producono il meglio possibile
h Pagina 621
predizioni.

Per determinare il valore migliore per k nell'algoritmo kNN, provare diversi valori di k quindi
confrontare le prestazioni dello stimatore con ciascuno. Possiamo farlo usando le tecniche
simile al confronto degli stimatori. Il ciclo seguente crea KNeighbors

Classificatori con valori k dispari da 1 a 19 (di nuovo, usiamo valori k dispari in kNN
per evitare legami) ed esegue la convalida incrociata kfold su ciascuno. Come puoi vedere dal
punteggi di precisione e deviazioni standard, il valore k 1 in kNN produce di più
previsioni accurate per il set di dati Digits. Puoi anche vedere che la precisione tende a
diminuzione per valori k maggiori :

lecca qui per visualizzare l'immagine del codice

In [47]: per k in serie ( 1 , 20 , 2 ):


...: kfold = KFold (n_splits = 10 , random_state = 11 , shuffle = True )
...: knn = KNeighborsClassifier (n_neighbors = k)
...: score = cross_val_score (estimator = knn,
...: X = digits.data, y = digits.target, cv = kfold)
...: print (f 'k = {k: < 2 } ; media accuratezza = {score.mean (): .2 %} ;' +
...: f 'deviazione standard = {score.std (): .2 %} ' )
...:
k = 1; accuratezza media = 98,83%; deviazione standard = 0,58%
k = 3; precisione media = 98,78%; deviazione standard = 0,78%
k = 5; accuratezza media = 98,72%; deviazione standard = 0,75%
k = 7; precisione media = 98,44%; deviazione standard = 0,96%
k = 9; accuratezza media = 98,39%; deviazione standard = 0,80%
k = 11; accuratezza media = 98,39%; deviazione standard = 0,80%
k = 13; precisione media = 97,89%; deviazione standard = 0,89%
k = 15; precisione media = 97,89%; deviazione standard = 1,02%
k = 17; precisione media = 97,50%; deviazione standard = 1,00%
k = 19; precisione media = 97,66%; deviazione standard = 0,96%

L'apprendimento automatico non è privo di costi, soprattutto perché ci dirigiamo verso i big data e
apprendimento approfondito. Devi "conoscere i tuoi dati" e "conoscere i tuoi strumenti". Per esempio,
il tempo di calcolo cresce rapidamente con k , perché kNN deve eseguire più calcoli
per trovare i vicini più vicini. C'è anche la funzione cross_validate, che lo fa
convalida incrociata e tempi dei risultati.

14.4 CASE STUDY: TIME SERIES E SEMPLICE LINEARE


REGRESSIONE
Nella sezione precedente, abbiamo dimostrato la classificazione in cui si trovava ogni campione
associato a una classe distinta . Qui, continuiamo la nostra discussione sul lineare semplice

C
Pagina 622
regressione, il più semplice degli algoritmi di regressione, che ha avuto inizio in Introduzione al capitolo 10
alla sezione Data Science. Ricorda che data una raccolta di valori numerici che rappresentano un file
variabile indipendente e una variabile dipendente, la regressione lineare semplice descrive la
relazione tra queste variabili con una linea retta, nota come linea di regressione.

In precedenza, abbiamo eseguito una semplice regressione lineare su una serie temporale di New York media
Dati relativi alle alte temperature di gennaio della città dal 1895 al 2018. In questo esempio, abbiamo utilizzato
La funzione regplot di Seaborn per creare un grafico a dispersione dei dati con un corrispondente

linea di regressione. Abbiamo anche usato la funzione linregress del modulo scipy.stats per
calcolare la pendenza e l'intercetta della retta di regressione. Abbiamo quindi utilizzato quei valori per prevedere
temperature future e stimare le temperature passate.

In questa sezione, lo faremo


utilizzare uno stimatore scikitlearn per reimplementare la semplice regressione lineare che abbiamo mostrato
nel capitolo 10 ,

utilizzare la funzione scatterplot di Seaborn per tracciare i dati e il diagramma di Matplotlib

funzione per visualizzare la linea di regressione, quindi

utilizzare il coefficiente e i valori di intercetta calcolati dallo stimatore scikitlearn per


fare previsioni.

Successivamente, esamineremo la regressione lineare multipla (chiamata anche semplicemente regressione lineare ).

Per tua comodità, forniamo i dati di temperatura nella cartella degli esempi ch14 in
un file CSV denominato ave_hi_nyc_jan_18952018.csv. Ancora una volta, avvia IPython
con l'opzione matplotlib:

ipython matplotlib

Caricamento delle temperature medie alte in un DataFrame

Come abbiamo fatto


capitolo
noi 10 , carichiamo i dati da ave_hi_nyc_jan_18952018.csv,
rinominare la colonna "Valore" in "Temperatura", rimuovere 01 dalla fine di ciascuna
valore della data e visualizzare alcuni campioni di dati:

lecca qui per visualizzare l'immagine del codice

In [1]: importa i panda come pd

C
Pagina 623
In [2]: nyc = pd.read_csv ( 'ave_hi_nyc_jan_18952018.csv' )

In [3]: nyc.columns = [ "Date" , "Temperature" , "Anomaly" ]

In [4]: ​nyc.Date = nyc.Date.floordiv ( 100 )

In [5]: nyc.head ( 3 )
Fuori [5]:
Anomalia della temperatura della data
0 1895 34,2 3.2
1 1896 34,7 2.7
2 1897 35,5 1.9

Suddivisione dei dati per addestramento e test

In questo esempio, utilizzeremo lo stimatore LinearRegression da

sklearn.linear_model . Per impostazione predefinita, questo stimatore utilizza tutte le caratteristiche numeriche in un file
set di dati, eseguendo una regressione lineare multipla (di cui parleremo nel prossimo
sezione). Qui, eseguiamo una semplice regressione lineare utilizzando una funzione come
variabile indipendente. Quindi, dovremo selezionare una funzione (la data) dal set di dati.

Quando si seleziona una colonna da un DataFrame bidimensionale, il risultato è uno


Serie dimensionale . Tuttavia, gli estimatori di scikitlearn richiedono la loro formazione e
dati di test per essere matrici bidimensionali (o bidimensionali arraylike dati, ad
come elenchi di elenchi o DataFrame panda). Per utilizzare dati unidimensionali con estensione
estimatore, devi trasformarlo da una dimensione contenente n elementi, in due
dimensioni contenenti n righe e una colonna come vedrai di seguito.

Come abbiamo fatto nel caso di studio precedente, suddividiamo i dati in set di addestramento e test.
Ancora una volta, abbiamo utilizzato l'argomento della parola chiave random_state per la riproducibilità:

lecca qui per visualizzare l'immagine del codice

In [6]: from sklearn.model_selection import train_test_split

In [7]: X_train, X_test, y_train, y_test = train_test_split (


...: nyc.Date.values.reshape ( 1 , 1 ), nyc.Temperature.values,
...: random_state = 11 )
...:

L'espressione nyc.Date restituisce la serie della colonna della data e la serie

l'attributo values ​restituisce l'array NumPy contenente i valori di quella serie. Per
trasformare questo array unidimensionale in due dimensioni, chiamiamo rimodellamento dell'array

C
Pagina 624
metodo . Normalmente, due argomenti sono il numero preciso di righe e colonne.
Tuttavia, il primo argomento 1 dice a reshape di dedurre il numero di righe, in base a
il numero di colonne (1) e il numero di elementi (124) nella matrice. Il
l'array trasformato avrà solo una colonna, quindi reshape deduce il numero di righe a

essere 124, perché l'unico modo per inserire 124 elementi in un array con una colonna è
distribuendoli su 124 file.

Possiamo confermare la divisione traintest del 75% –25% controllando le forme di X_train e

X_test:

lecca qui per visualizzare l'immagine del codice

In [8]: X_train.shape
Uscita [8]: (93, 1)

In [9]: X_test.shape
Uscita [9]: (31, 1)

Formazione del modello

Scikitlearn non ha una classe separata per la regressione lineare semplice perché è solo
un caso speciale di regressione lineare multipla, quindi addestriamo una regressione lineare

estimatore:

lecca qui per visualizzare l'immagine del codice

In [10]: da sklearn.linear_model import LinearRegression

In [11]: linear_regression = LinearRegression ()

In [12]: linear_regression.fit (X = X_train, y = y_train)


Fuori [12]:
LinearRegression (copy_X = True, fit_intercept = True, n_jobs = Nessuno,
normalize = False)

Dopo aver addestrato lo stimatore, fit restituisce lo stimatore e IPython mostra la sua stringa
rappresentazione. Per le descrizioni delle impostazioni predefinite, vedere:

ttp: // scikit
guadagna.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html

Per trovare la retta di regressione più adatta per i dati, utilizzare lo stimatore LinearRegression
regola iterativamente i valori di pendenza e intercetta per ridurre al minimo la somma dei quadrati di
hl
C
Pagina 625
le distanze dei punti dati dalla linea. Nel apo 10 ‘s Introduzione alla sezione Science Data,
abbiamo fornito alcune informazioni su come vengono scoperti i valori di pendenza e intercetta.

Ora, possiamo ottenere la pendenza e l'intercetta utilizzate nel calcolo y = mx + b da eseguire


predizioni. La pendenza è memorizzata nell'attributo coeff_ dello stimatore ( m nell'equazione)

e l'intercetta viene memorizzato nella del stimatore intercept_ attributo ( b nell'equazione):

lecca qui per visualizzare l'immagine del codice

In [13]: linear_regression.coef_
Uscita [13]: array ([0.01939167])

In [14]: linear_regression.intercept_
Uscita [14]: 0.30779820252656265

Li utilizzeremo in seguito per tracciare la linea di regressione e fare previsioni per date specifiche.

Testare il modello

Testiamo il modello utilizzando i dati in X_test e controlliamo alcune delle previsioni


in tutto il set di dati visualizzando i valori previsti e attesi per ogni
quinto elemento: discutiamo di come valutare l'accuratezza del modello di regressione in ezione
4.5.8 :

lecca qui per visualizzare l'immagine del codice

In [15]: predicted = linear_regression.predict (X_test)

In [16]: previsto = y_test

In [17]: for p, e in zip (previsto [:: 5 ], previsto [:: 5 ]):


...: print (f 'previsto: {p: .2 f} , previsto: {e: .2 f} ' )
...:
previsto: 37,86, previsto: 31,70
previsto: 38,69, previsto: 34,80
previsto: 37.00, previsto: 39.40
previsto: 37.25, previsto: 45.70
previsto: 38.05, previsto: 32.30
previsto: 37,64, previsto: 33,80
previsto: 36.94, previsto: 39.70

Previsione delle temperature future e stima delle temperature passate

Usiamo i valori del coefficiente e dell'intercetta per prevedere il massimo medio di gennaio 2019
temperatura e per stimare quale fosse la temperatura media alta nel mese di gennaio

1S
C
Pagina 626
1890. Il lambda nel frammento seguente implementa l'equazione per una linea

y = mx + b

usando il coef_ come me l'intercept_ come b .

lecca qui per visualizzare l'immagine del codice

In [18] : predicire = ( lambda x: linear_regression.coef_ * x +


...: linear_regression.intercept_)
...:

In [19]: predicire (2019)


Uscita [19]: array ([38.84399018])

In [20]: predire (1890)


Uscita [20]: array ([36.34246432])

Visualizzazione del set di dati con la riga di regressione

Successivamente, creiamo un grafico a dispersione del set di dati utilizzando la funzione scatterplot di Seaborn
e la funzione plot di Matplotlib . Innanzitutto, usa il grafico a dispersione con il nyc DataFrame per

visualizzare i punti dati:

lecca qui per visualizzare l'immagine del codice

In [21]: importa seaborn come sns

In [22]: axes = sns.scatterplot (data = nyc, x ='Date' , y = 'Temperature' ,


...: hue = 'Temperature' , palette = 'winter' , legend = False )
...:

Gli argomenti delle parole chiave sono:

data, che specifica il DataFrame (nyc) contenente i dati da visualizzare.

x e y, che specificano i nomi delle colonne di New York che sono l'origine dei dati
lungo il x ed y assi, rispettivamente. In questo caso, x è la "Data" ey è la

'Temperatura'. I valori corrispondenti di ciascuna forma colonna xy coordinate


coppie utilizzate per tracciare i punti.

tonalità, che specifica i dati della colonna da utilizzare per determinare il punto

C
Pagina 627
colori. In questo caso, utilizziamo la colonna "Temperatura". Il colore non è particolarmente
importante in questo esempio, ma volevamo aggiungere un po 'di interesse visivo al grafico.

tavolozza, che specifica una mappa dei colori Matplotlib da cui scegliere i punti
colori.

legend = False, che specifica che il grafico a dispersione non deve mostrare una legenda per
il grafico: l'impostazione predefinita è True, ma non è necessaria una legenda per questo esempio.

Come abbiamo fatto


al capitolo
noi 10 , ridimensioniamo l'intervallo di valori dell'asse y in modo da poter vedere il file
relazione lineare migliore una volta visualizzata la linea di regressione:

lecca qui per visualizzare l'immagine del codice

In [23]: axes.set_ylim ( 10 , 70 )
Uscita [23]: (10, 70)

Successivamente, mostriamo la linea di regressione. Innanzitutto, crea un array contenente il minimo


e i valori di data massimi in nyc.Date. Queste sono le coordinate x della regressione

punti di inizio e fine della linea:

lecca qui per visualizzare l'immagine del codice

In [24]: importa numpy come np

In [25]: x = np.array ([min (nyc.Date.values), max (nyc.Date.values)])


Il passaggio dell'array x alla previsione lambda dallo snippet [16] produce un array
contenente i corrispondenti valori previsti, che useremo come coordinate y :

lecca qui per visualizzare l'immagine del codice

In [26]: y = predire (x)

Infine, possiamo usare la funzione plot di Matplotlib per tracciare una linea basata su x e y

array, che rappresentano le x ed y coordinate dei punti, rispettivamente:

lecca qui per visualizzare l'immagine del codice

In [27]: importa matplotlib.pyplot come plt

C
Pagina 628
In [28]: line = plt.plot (x, y)

Il grafico a dispersione e la linea di regressione risultanti sono mostrati di seguito. Questo grafico è quasi
identico a quello in cui hai visto apo 10 ‘s Introduzione alla sezione Science Data.

Overfitting / Underfitting

Quando si crea un modello, un obiettivo chiave è garantire che sia in grado di essere accurato
previsioni per dati che non ha ancora visto. Due problemi comuni che impediscono l'accuratezza
le previsioni sono overfitting e underfitting:

L'underfitting si verifica quando un modello è troppo semplice per fare previsioni, basate su di esso
dati di allenamento. Ad esempio, puoi utilizzare un modello lineare, come semplice lineare
regressione, quando in realtà il problema richiede davvero un modello non lineare. Per
Ad esempio, le temperature variano notevolmente durante le quattro stagioni. Se tu sei
cercando di creare un modello generale in grado di prevedere le temperature tutto l'anno, un semplice
il modello di regressione lineare non si adatta ai dati.

L'overfitting si verifica quando il modello è troppo complesso. Il caso più estremo, sarebbe
essere un modello che memorizza i suoi dati di allenamento. Potrebbe essere accettabile se sei nuovo
i dati sono esattamente come i dati di addestramento, ma normalmente non è così. quando
C
Pagina 629
fai previsioni con un modello overfit, nuovi dati che corrispondono alla formazione
i dati produrranno previsioni perfette, ma il modello non saprà cosa farne
dati che non ha mai visto.

Per ulteriori informazioni su underfitting e overfitting, vedere

ttps: //en.wikipedia.org/wiki/Overfitting

ttps: //machinelearningmastery.com/overfittingand
nderfittingwithmachinelearningalgorithms /

14.5 CASO DI STUDIO: REGRESSIONE LINEARE MULTIPLA


CON IL DATASET DELLA CUSTODIA DELLA CALIFORNIA
Nel Nel capitolo 10 della sezione Introduzione alla scienza dei dati, abbiamo eseguito una semplice regressione lineare su
una piccola serie temporale di dati meteorologici che utilizza i panda, la funzione regplot di Seaborn e l'estensione

Funzione linregress del modulo delle statistiche di SciPy. Nella sezione precedente, noi
reimplementato lo stesso esempio utilizzando lo stimatore LinearRegression di scikitlearn,
Funzione scatterplot di Seaborn e funzione plot di Matplotlib. Ora ci esibiremo
regressione lineare con un set di dati del mondo reale molto più ampio.

7
Il set di dati California Housing in bundle con scikitlearn ha 20.640 campioni,
ciascuno con otto caratteristiche numeriche. Eseguiremo una regressione lineare multipla che utilizza
tutte le otto caratteristiche numeriche per fare previsioni sui prezzi delle abitazioni più sofisticate rispetto a
se dovessimo utilizzare solo una singola funzionalità o un sottoinsieme delle funzionalità. Ancora una volta, scikit
learn farà la maggior parte del lavoro per te: LinearRegression esegue più operazioni lineari

regressione per impostazione predefinita.

7
ttp: //lib.stat.cmu.edu/datasets . Pace, R. Kelley e Ronald Barry,
Autoregressioni spaziali sparse, statistiche e lettere di probabilità, 33 (1997) 291297.
Inserito nell'archivio dei dataset di StatLib da Kelley Pace
( pace@unix1.sncc.lsu.edu ). [9 / Nov / 99].

Visualizzeremo alcuni dati usando Matplotlib e Seaborn, quindi avvia IPython con
Supporto Matplotlib:

ipython matplotlib

14.5.1 Caricamento del set di dati

C
hu
K
Pagina 630
Secondo la descrizione del set di dati dei prezzi degli alloggi della California su scikitlearn, "This
set di dati è stato ricavato dal censimento degli Stati Uniti del 1990, utilizzando una riga per gruppo di blocchi di censimento. UN
block group è la più piccola unità geografica per la quale lo US Census Bureau
pubblica dati campione (un gruppo di blocchi ha tipicamente una popolazione compresa tra 600 e 3000
persone)." Il set di dati ha 20.640 campioni, uno per gruppo di blocchi, con otto funzioni
ogni:

reddito medio: in decine di migliaia, quindi 8,37 rappresenterebbero $ 83.700

età media della casa: nel set di dati, il valore massimo per questa funzione è 52

numero medio di stanze


numero medio di camere da letto

bloccare la popolazione

occupazione media della casa

latitudine dell'isolato

longitudine dell'isolato

Ogni campione ha anche come obiettivo un valore della casa mediana corrispondente in centinaia di
migliaia, quindi 3,55 rappresenterebbe $ 355.000. Nel set di dati, il valore massimo per
questa funzione è 5, che rappresenta $ 500.000.

È ragionevole aspettarsi che più camere da letto o più stanze o un reddito più elevato lo farebbero
significa valore della casa più alto. Combinando queste caratteristiche per fare previsioni, siamo di più
probabilità di ottenere previsioni più accurate.

Caricamento dei dati


Carichiamo il set di dati e familiarizziamo con esso. Il

funzione fetch_california_housing dal modulo sklearn.datasets


restituisce un oggetto Bunch contenente i dati e altre informazioni sul set di dati:

lecca qui per visualizzare l'immagine del codice

In [1]: from sklearn.datasets import fetch_california_housing

In [2]: california = fetch_california_housing ()

D
C sta riproducendo la descrizione del set di dati

Visualizzazione della descrizione del set di dati Pagina 631

Diamo un'occhiata alla descrizione del set di dati. Le informazioni DESCR includono:

Numero di istanze: questo set di dati contiene 20.640 campioni.

Numero di attributi: sono disponibili 8 funzioni (attributi) per campione.

Informazioni sugli attributi: descrizioni delle funzioni.

Valori di attributo mancanti: nessuno manca in questo set di dati.

Secondo la descrizione, la variabile target in questo set di dati è la casa mediana


valore: questo è il valore che tenteremo di prevedere tramite la regressione lineare multipla.

lecca qui per visualizzare l'immagine del codice

n [3]: print (california.DESCR)


.. _california_housing_dataset:

Set di dati California Housing

** Caratteristiche del set di dati: **

: Numero di istanze: 20640

: Numero di attributi: 8 attributi numerici, predittivi e


il bersaglio

: Informazioni sugli attributi:


Reddito mediano MedInc in blocco
HouseAge Età media della casa nel blocco
Numero medio di camere AveRooms
Numero medio di camere da letto di AveBedrms
Popolazione a blocco della popolazione
Occupazione media della casa AveOccup
Latitudine latitudine dell'isolato
Longitudine longitudine dell'isolato

: Valori attributo mancanti: Nessuno

Questo set di dati è stato ottenuto dal repository StatLib.


http://lib.stat.cmu.edu/datasets/

La variabile target è il valore mediano della casa per i distretti della California.

Questo set di dati è stato ricavato dal censimento statunitense del 1990, utilizzando una riga per blocco di censimento

Può essere scaricato / caricato utilizzando il file Pagina 632


: func: funzione `sklearn.datasets.fetch_california_housing`.

.. argomento :: Riferimenti

Pace, R. Kelley e Ronald Barry, Sparse Spatial Autoregressions,


Statistics and Probability Letters, 33 (1997) 291297

gain, i dati dell'oggetto Bunch e gli attributi di destinazione sono array di NumPy contenenti
rispettivamente i 20.640 campioni e i loro valori target. Possiamo confermare il numero di
campioni (righe) e caratteristiche (colonne) osservando l'attributo di forma della matrice di dati,
che mostra che ci sono 20.640 righe e 8 colonne:

lecca qui per visualizzare l'immagine del codice

In [4]: ​california.data.shape
Uscita [4]: ​(20640, 8)

Allo stesso modo, puoi vedere il numero di valori target, ovvero la casa mediana
valori: corrisponde al numero di campioni osservando la forma della matrice di destinazione:

lecca qui per visualizzare l'immagine del codice

In [5]: california.target.shape
Uscita [5]: (20640,)

L' attributo feature_names di Bunch contiene i nomi che corrispondono a ciascuno

colonna nella matrice di dati:

lecca qui per visualizzare l'immagine del codice

In [6]: california.feature_names
Fuori [6]:
["MedInc",
"HouseAge",
"AveRooms",
"AveBedrms",
'Popolazione',
"AveOccup",
'Latitudine',
'Longitudine']
1
C
UN 4.5.2 Esplorazione dei dati con Panda
14.5.2 Esplorazione dei dati con i Panda Pagina 633

Usiamo un DataFrame panda per esplorare ulteriormente i dati. Useremo anche il file

DataFrame con Seaborn nella sezione successiva per visualizzare alcuni dati. Per prima cosa, andiamo
importa i panda e imposta alcune opzioni:

lecca qui per visualizzare l'immagine del codice

In [7]: importa i panda come pd

In [8]: pd.set_option ( 'precision' , 4 )

In [9]: pd.set_option ( 'max_columns' , 9 )

In [10]: pd.set_option ( 'display.width' , Nessuno )

Nelle precedenti chiamate set_option:

"precisione" è il numero massimo di cifre da visualizzare a destra di ciascuna


punto decimale.

"max_columns" è il numero massimo di colonne da visualizzare durante l'output


la rappresentazione di stringa del DataFrame. Per impostazione predefinita, se i panda non possono adattarsi a tutti i file
colonne da sinistra a destra, taglia le colonne al centro e visualizza i puntini di sospensione ()
anziché. L'impostazione "max_columns" consente ai panda di mostrare tutte le colonne che utilizzano
più righe di output. Come vedrai tra poco, avremo nove colonne nel file

DataFrame: le otto funzionalità del set di dati in california.data e un altro


colonna per i valori della casa mediana di destinazione (california.target).

"display.width" specifica la larghezza in caratteri del prompt dei comandi


(Windows), Terminal (macOS / Linux) o shell (Linux). Il valore Nessuno dice ai panda
per rilevare automaticamente la larghezza di visualizzazione durante la formattazione delle rappresentazioni di stringa di Series

e DataFrames.

Successivamente, creiamo un DataFrame dai dati, target e feature_names di Bunch


array. Il primo frammento di seguito crea il DataFrame iniziale utilizzando i dati in

california.data e con i nomi delle colonne specificati da


california.feature_names. La seconda istruzione aggiunge una colonna per la mediana
valori della casa memorizzati in california.target:

lecca qui per visualizzare l'immagine del codice

C
Pagina 634
In [11]: california_df = pd.DataFrame (california.data,
...: colonne = california.feature_names)
...:

In [12]: california_df [ 'MedHouseValue' ] = pd.Series (california.target)

Possiamo dare un'occhiata ad alcuni dati usando la funzione head. Notare che i panda vengono visualizzati

le prime sei colonne di DataFrame, quindi salta una riga di output e visualizza il file
colonne rimanenti. La \ a destra dell'intestazione della colonna "AveOccup" lo indica

ci sono più colonne visualizzate di seguito. Vedrai \ solo se la finestra in cui


IPython in esecuzione è troppo stretto per visualizzare tutte le colonne da sinistra a destra:
lecca qui per visualizzare l'immagine del codice

In [13]: california_df.head ()
Fuori [13]:
MedInc HouseAge AveRooms AveBedrms Population AveOccup \
0 8.3252 41.0 6.9841 1.0238 322.0 2.5556
1 8.3014 21.0 6.2381 0.9719 2401.0 2.1098
2 7.2574 52.0 8.2881 1.0734 496.0 2.8023
3 5.6431 52.0 5.8174 1.0731 558.0 2.5479
4 3.8462 52.0 6.2819 1.0811 565.0 2.1815

Latitudine Longitudine MedHouseValue


0 37,88 122,23 4.526
1 37,86 122,22 3.585
2 37,85 122,24 3.521
3 37,85 122,25 3.413
4 37,85 122,25 3.422

Diamo un'idea dei dati in ciascuna colonna calcolando il riepilogo di DataFrame


statistiche. Si noti che il reddito medio e i valori della casa (di nuovo, misurati in centinaia
di migliaia) sono del 1990 e oggi sono notevolmente superiori:

lecca qui per visualizzare l'immagine del codice

In [14]: california_df.describe ()
Fuori [14]:
MedInc HouseAge AveRooms AveBedrms Popolazione \
conteggio 20640.0000 20640.0000 20640.0000 20640.0000 20640.0000
media 3,8707 28,6395 5,4290 1,0967 1425,4767
std 1.8998 12.5856 2.4742 0.4739 1132.4621
min 0,4999 1,0000 0,8462 0,3333 3,0000
25% 2.5634 18.0000 4.4407 1.0061 787.0000
50% 3.5348 29.0000 5.2291 1.0488 1166.0000

75% 4.7432 37.0000 6.0524 1.0995 1725.0000 Pagina 635


max 15.0001 52.0000 141.9091 34.0667 35682.0000

AveOccup Latitude Longitude MedHouseValue


conteggio 20640.0000 20640.0000 20640.0000 20640.0000
media 3.0707 35.6319 119.5697 2.0686
std 10.3860 2.1360 2.0035 1.1540
min 0,6923 32,5400 124,3500 0,1500
25% 2.4297 33.9300 121.8000 1.1960
50% 2.8181 34.2600 118.4900 1.7970
75% 3.2823 37.7100 118.0100 2.6472
max 1243.3333 41.9500 114.3100 5.0000

14.5.3 Visualizzazione delle caratteristiche


È utile visualizzare i dati tracciando il valore target rispetto a ciascuna funzionalità, in formato
questo caso, per vedere come il valore mediano della casa si riferisce a ciascuna caratteristica. Per rendere il nostro
visualizzazioni più chiare, usiamo il campione del metodo DataFrame per selezionare in modo casuale il 10% di
i 20.640 campioni per scopi grafici:

lecca qui per visualizzare l'immagine del codice

In [15]: sample_df = california_df.sample (frac = 0.1 , random_state = 17 )

L'argomento della parola chiave frac specifica la frazione dei dati da selezionare (0,1 per il 10%),
e l'argomento della parola chiave random_state consente di inizializzare il numero casuale
Generatore. Il valore seed intero (17), che abbiamo scelto arbitrariamente, è cruciale

riproducibilità . Ogni volta che si utilizza lo stesso valore seed, il metodo sample seleziona il file
stesso sottoinsieme casuale delle righe del DataFrame. Quindi, quando rappresentiamo graficamente i dati, tu
dovrebbe ottenere gli stessi risultati.

Successivamente, utilizzeremo Matplotlib e Seaborn per visualizzare grafici a dispersione di ciascuno degli otto
Caratteristiche. Entrambe le librerie possono visualizzare grafici a dispersione. I Seaborn sono più attraenti e
richiedono meno codice, quindi useremo Seaborn per creare i seguenti grafici a dispersione. Primo, noi
importa entrambe le librerie e usa il set di funzioni Seaborn per ridimensionare i caratteri di ogni diagramma a due
volta la loro dimensione predefinita:

lecca qui per visualizzare l'immagine del codice

In [16]: importa matplotlib.pyplot come plt

In [17]: importa seaborn come sns

C
Pagina 636
In [18]: sns.set (font_scale = 2 )

In [19]: sns.set_style ( 'whitegrid' )

8
Il frammento di codice seguente mostra i grafici a dispersione . Ognuno mostra una caratteristica lungo la x
asse e il valore mediano della casa (california.target) lungo l' asse y , così possiamo

vedere come ogni caratteristica e i valori mediani della casa si relazionano tra loro. Mostriamo
ogni grafico a dispersione in una finestra separata. Le finestre vengono visualizzate nell'ordine
le caratteristiche sono state elencate nello snippet [6] con la finestra visualizzata più di recente nel file
primo piano:

8
Quando esegui questo codice in IPython, ogni finestra verrà visualizzata davanti al file
precedente. Quando li chiudi, vedrai quello dietro.

lecca qui per visualizzare l'immagine del codice

In [20]: per la funzione in california.feature_names:


...: plt.figure (figsize = ( 16 , 9 ))
...: sns.scatterplot (data = sample_df, x = feature,
...: y = 'MedHouseValue' , hue = 'MedHouseValue' ,
...: palette = 'cool' , legend = False )
...:

Per ogni nome di funzionalità, lo snippet crea prima una figura Matplotlib da 16 pollici per 9 pollici
—Stiamo tracciando molti punti dati, quindi abbiamo scelto di utilizzare una finestra più grande. Se questa finestra è
più grande dello schermo, Matplotlib adatta la figura allo schermo. Seaborn utilizza l'estensione
Figura corrente per visualizzare il grafico a dispersione. Se non crei prima una figura, Seaborn

ne creerà uno. Abbiamo creato prima la figura qui in modo da poter visualizzare una grande finestra
per un grafico a dispersione contenente oltre 2000 punti.

Successivamente, lo snippet crea un grafico a dispersione Seaborn in cui l' asse x mostra il file
caratteristica corrente, i y axis mostra i ( '' MedHouseValue valori mediani casa ),
e "MedHouseValue" determina i colori dei punti (tonalità). Alcune cose interessanti

da notare in questi grafici:

I grafici che mostrano la latitudine e la longitudine hanno ciascuno due aree di particolare
densità significativa. Se cerchi online i valori di latitudine e longitudine dove
compaiono quelle zone dense, vedrai che queste rappresentano la maggiore Los Angeles e
maggiori aree di San Francisco dove i prezzi delle case tendono ad essere più alti.

In ogni grafico è presente una linea orizzontale di punti in corrispondenza del valore 5 dell'asse y , che
C

e rappresenta il valore mediano della casa $ 500.000. Il valore della casa più alto che potrebbe essere Pagina 637
9
scelto nel modulo del censimento del 1990 era "$ 500.000 o più". Quindi qualsiasi gruppo di blocco
con un valore della casa mediano superiore a $ 500.000 è elencato nel set di dati come 5. Essere in grado di
caratteristiche spot come questa sono un motivo valido per eseguire l'esplorazione dei dati e
visualizzazione.

9
ttps: //www.census.gov/prod/1/90dec/cph4/appdxe.pdf .

Nel grafico HouseAge è presente una linea verticale di punti in corrispondenza del valore 52 dell'asse x
l'età domestica più alta che poteva essere scelta nel modulo del censimento del 1990 era 52, quindi qualsiasi
Il gruppo in blocco con un'età media della casa superiore a 52 è elencato nel set di dati come 52.

hr
Pagina 640
638
639
14.5.4 Suddivisione dei dati per addestramento e test
Ancora una volta, per prepararci all'addestramento e al test del modello, suddividiamo i dati in
set di addestramento e test utilizzando la funzione train_test_split, quindi controlla i loro
dimensioni:

lecca qui per visualizzare l'immagine del codice

In [21]: from sklearn.model_selection import train_test_split

In [22]: X_train, X_test, y_train, y_test = train_test_split (


...: california.data, california.target, random_state = 11 )

...: Pagina 641

In [23]: X_train.shape
Uscita [23]: (15480, 8)

In [24]: X_test.shape
Uscita [24]: (5160, 8)

Abbiamo usato l'argomento della parola chiave random_state di train_test_split per inizializzare il file
generatore di numeri casuali per la riproducibilità.

14.5.5 Addestramento del modello


Successivamente, addestreremo il modello. Per impostazione predefinita, uno stimatore LinearRegression utilizza tutti i
caratteristiche nell'array di dati del set di dati per eseguire una regressione lineare multipla. Un errore
si verifica se una delle caratteristiche è categoriale anziché numerica. Se un set di dati contiene
dati categoriali, è necessario preelaborare le caratteristiche categoriali in numeriche
quelli (cosa che farai nel prossimo capitolo) o devi escludere le caratteristiche categoriali da
il processo di formazione. Un vantaggio di lavorare con i set di dati in bundle di scikitlearn è questo
sono già nel formato corretto per l'apprendimento automatico utilizzando i modelli di scikitlearn.

Come hai visto nei due snippet precedenti, X_train e X_test contengono ciascuno 8 colonne
—Uno per caratteristica. Creiamo uno stimatore LinearRegression e invociamo il suo adattamento
metodo per addestrare lo stimatore utilizzando X_train e y_train:

lecca qui per visualizzare l'immagine del codice

In [25]: da sklearn.linear_model import LinearRegression


In [26]: linear_regression = LinearRegression ()

In [27]: linear_regression.fit (X = X_train, y = y_train)


Fuori [27]:
LinearRegression (copy_X = True, fit_intercept = True, n_jobs = Nessuno,
normalize = False)

La regressione lineare multipla produce coefficienti separati per ciascuna funzione (memorizzata in

coeff_) nel set di dati e un'intercetta (memorizzata in intercept_):

lecca qui per visualizzare l'immagine del codice

In [28]: for i, name in enumerate (california.feature_names):


...: print (f ' {name:> 10 } : {linear_regression.coef_ [i]} ' )
...:

MedInc: 0.4377030215382206 Pagina 642


Età della casa: 0,009216834565797713
AveRooms: 0.10732526637360985
AveBedrms: 0.611713307391811
Popolazione: 5.756822009298454e06
AveOccup: 0.0033845664657163703
Latitudine: 0,419481860964907
Longitudine: 0,4337713349874016

In [29]: linear_regression.intercept_
Uscita [29]: 36,88295065605547

Per i coefficienti positivi, il valore mediano della casa aumenta con il valore dell'elemento
aumenta . Per i coefficienti negativi, il valore mediano della casa diminuisce con l'elemento
il valore aumenta . Si noti che il coefficiente della popolazione ha un esponente negativo (e06),
quindi il valore del coefficiente è in realtà 0,000005756822009298454. Questo è vicino a
zero, quindi la popolazione di un gruppo di blocco apparentemente ha scarso effetto sul valore della casa mediana.

È possibile utilizzare questi valori con la seguente equazione per effettuare previsioni:

y = mx +1 1mx + ... mx
22+ b nn

dove

m ,1 m ,,2 m sono
n i coefficienti caratteristica,

b è l'intercetta,

x 1, x ,,2 x sono
n i valori delle caratteristiche (cioè, i valori delle variabili indipendenti),
e

y è il valore previsto (ovvero la variabile dipendente).

14.5.6 Test del modello


Ora, testiamo il modello chiamando il metodo di previsione dello stimatore con il test
campioni come argomento. Come abbiamo fatto in ciascuno degli esempi precedenti, archiviamo il file
matrice di previsioni in previsto e matrice di valori attesi in previsto:

lecca qui per visualizzare l'immagine del codice

In [30]: predicted = linear_regression.predict (X_test)


C

In [31]: previsto = y_test Pagina 643

Diamo un'occhiata alle prime cinque previsioni e ai corrispondenti valori attesi:

lecca qui per visualizzare l'immagine del codice

In [32]: predetto [: 5 ]
Uscita [32]: array ([1.25396876, 2.34693107, 2.03794745, 1.8701254, 2.536083 9])

n [33]: previsto [: 5 ]
Uscita [33]: array ([0.762, 1.732, 1.125, 1.37, 1.856])

Con la classificazione, abbiamo visto che le previsioni erano classi distinte che corrispondevano
classi esistenti nel set di dati. Con la regressione è difficile ottenere previsioni esatte,
perché hai uscite continue. Ogni possibile valore di x , x x nel calcolo 1 2n

y = mx +1 1mx + ... mx
22+ b nn

prevede un valore.

14.5.7 Visualizzazione dei prezzi attesi rispetto a quelli previsti


Diamo un'occhiata ai valori della casa mediana attesi rispetto a quelli previsti per i dati del test. Per prima cosa, andiamo
creare un DataFrame contenente colonne per i valori attesi e previsti:

lecca qui per visualizzare l'immagine del codice

In [34]: df = pd.DataFrame ()

In [35]: df [ 'Expected' ] = pd.Series (previsto)

In [36]: df [ 'Predicted' ] = pd.Series (predetto)

Ora tracciamo i dati come un grafico a dispersione con i prezzi previsti (target) lungo l' asse x
e i prezzi previsti lungo l' asse y :

lecca qui per visualizzare l'immagine del codice

In [37]: figure = plt.figure (figsize = (9 , 9 ))

In [38]: axes = sns.scatterplot (data = df, x ='Expected' , y = 'Predicted' ,


...: hue = 'Predicted' , palette = 'cool' , legend = False )

C
io

...: Pagina 644

Successivamente, è necessario impostare un X e Y limiti assi di utilizzare la stessa scala lungo due assi:

lecca qui per visualizzare l'immagine del codice

In [39]: inizio = min (previsto.min (), predicted.min ())

In [40]: end = max (expected.max (), predicted.max ())

In [41]: axes.set_xlim (inizio, fine)


Uscita [41]: (0.6830978604144491, 7.155719818496834)
In [42]: axes.set_ylim (inizio, fine)
Uscita [42]: (0.6830978604144491, 7.155719818496834)

Ora tracciamo una linea che rappresenta previsioni perfette (nota che questo non è un file
linea di regressione). Il frammento di codice seguente mostra una linea tra i punti che rappresentano
l'angolo inferiore sinistro del grafico (inizio, inizio) e l'angolo superiore destro del
grafico (fine, fine). Il terzo argomento ("k") indica lo stile della linea. La lettera k

rappresenta il colore nero e indica che il grafico deve disegnare una linea tratteggiata:

lecca qui per visualizzare l'immagine del codice

In [43]: line = plt.plot ([start, end], [start, end], 'k' )

Se ogni valore previsto dovesse corrispondere al valore atteso, allora tutti i punti lo sarebbero
tracciato lungo la linea tratteggiata. Nel diagramma seguente, sembra che come previsto
il valore mediano della casa aumenta, più dei valori previsti scende al di sotto della linea. Così la
il modello sembra prevedere valori di casa mediani inferiori come il valore di casa mediano atteso
aumenta.

C
Pagina 645

14.5.8 Metriche del modello di regressione


Scikitlearn fornisce molte funzioni di metrica per valutare quanto bene prevedono gli stimatori
risultati e per confrontare gli stimatori per scegliere i migliori per il tuo particolare
studia. Queste metriche variano in base al tipo di stimatore. Ad esempio, sklearn.metrics
funzioni confusion_matrix e classification_report utilizzate in Digits
Il caso di studio della classificazione dei set di dati sono due delle molte funzioni di metriche specifiche per
valutare stimatori di classificazione .

Tra le molte metriche per gli stimatori di regressione c'è il coefficiente del modello di
2 2
determinazione , che è anche chiamato il punteggio R . Per calcolare la R di uno stimatore
score, chiama la funzione r2_score del modulo sklearn.metrics con gli array
che rappresentano i risultati attesi e previsti:

lecca qui per visualizzare l'immagine del codice

In [44]: da sklearn import metrics

In [45]: metrics.r2_score (previsto, previsto)


Uscita [45]: 0.6008983115964333

2
2C

2 2 Pagina 646
I punteggi R vanno da 0,0 a 1,0 con 1,0 che è il migliore. Un punteggio R di 1.0 lo indica
lo stimatore predice perfettamente il valore della variabile dipendente, data l'indipendente
2
valore (i) delle variabili. Un punteggio R di 0,0 indica che il modello non può fare previsioni
con qualsiasi accuratezza, in base ai valori delle variabili indipendenti.

Un'altra metrica comune per i modelli di regressione è l' errore quadratico medio , che

calcola la differenza tra ogni valore atteso e previsto, viene chiamato


l' errore ,

piazza ogni differenza e

calcola la media dei valori al quadrato.

Per calcolare l'errore quadratico medio di uno stimatore, chiama la funzione mean_squared_error
(dal modulo sklearn.metrics) con gli array che rappresentano il previsto e
risultati previsti:

lecca qui per visualizzare l'immagine del codice

In [46]: metrics.mean_squared_error (previsto, previsto)


Uscita [46]: 0,5350149774449119

Quando si confrontano gli stimatori con la metrica dell'errore quadratico medio, quella con il valore
più vicino a 0 si adatta meglio ai tuoi dati. Nella sezione successiva, eseguiremo diverse regressioni
stimatori che utilizzano il set di dati California Housing. Per l'elenco delle metriche di scikitlearn
funzioni per categoria stimatore, vedere

ttps: //scikitlearn.org/stable/modules/model_evaluation.html

14.5.9 Scelta del modello migliore


Come abbiamo fatto nel caso di studio di classificazione, proviamo a determinare diversi stimatori
se qualcuno produce risultati migliori rispetto allo stimatore LinearRegression. In questo
esempio, useremo lo stimatore linear_regression che abbiamo già creato così come

Stimatori di regressione ElasticNet, Lasso e Ridge (tutti da


modulo sklearn.linear_model). Per informazioni su questi stimatori, vedere

ttps: //scikitlearn.org/stable/modules/linear_model.html
C
h

Pagina 647
lecca qui per visualizzare l'immagine del codice

In [47]: da sklearn.linear_model import ElasticNet, Lasso, Ridge

In [48]: estimatori = {
...: 'LinearRegression' : linear_regression,
...: "ElasticNet" : ElasticNet (),
...: 'Lazo' : Lazo (),
...: 'Ridge' : Ridge ()
...:}

Ancora una volta, eseguiremo gli stimatori usando kfold crossvalidation con un oggetto KFold
e la funzione cross_val_score. Qui passiamo a cross_val_score il file

punteggio aggiuntivo dell'argomento della parola chiave = 'r2', che indica che la funzione
2
dovrebbe riportare i punteggi R per ogni piega: di nuovo, 1.0 è il migliore, quindi sembra che

LinearRegression e Ridge sono i migliori modelli per questo set di dati:

lecca qui per visualizzare l'immagine del codice

In [49]: da sklearn.model_selection importa KFold, cross_val_score

In [50]: per estimator_name, estimator_object in estimators.items ():


...: kfold = KFold (n_splits = 10 , random_state = 11 , shuffle = True )
...: score = cross_val_score (estimator = estimator_object,
...: X = california.data, y = california.target, cv = kfold,
...: punteggio = 'r2' )
...: print (f ' {estimator_name:> 16 } :' +
...: f 'media dei punteggi r2 = {score.mean (): .3 f} ' )
...:
LinearRegression: media dei punteggi r2 = 0,599
ElasticNet: media dei punteggi r2 = 0,423
Lazo: media dei punteggi r2 = 0,285
Ridge: media dei punteggi r2 = 0,599

14.6 CASO DI STUDIO: MACCHINA NON SUPERVISIONATA


APPRENDIMENTO, PARTE 1 - RIDUZIONE DELLA DIMENSIONALITÀ
Nelle nostre presentazioni sulla scienza dei dati, ci siamo concentrati sulla conoscenza dei tuoi dati.
L'apprendimento automatico e la visualizzazione senza supervisione possono aiutarti a farlo trovando
modelli e relazioni tra campioni senza etichetta.

Per i set di dati come le serie temporali univariate che abbiamo utilizzato in precedenza in questo capitolo, la visualizzazione
i dati sono facili. In quel caso, avevamo due variabili - data e temperatura - quindi noi

ha tracciato i dati in due dimensioni con una variabile lungo ogni asse. Utilizzando Matplotlib, Pagina 648

Seaborn e altre librerie di visualizzazione, puoi anche tracciare set di dati con tre variabili
utilizzando visualizzazioni 3D. Ma come si visualizzano i dati con più di tre
dimensioni? Ad esempio, nel set di dati Digits, ogni campione ha 64 caratteristiche e un file
valore target. Nei big data, i campioni possono avere centinaia, migliaia o addirittura milioni di
Caratteristiche.

Per visualizzare un set di dati con molte funzionalità (ovvero molte dimensioni), prima ridurremo
i dati a due o tre dimensioni. Ciò richiede un apprendimento automatico non supervisionato
tecnica chiamata riduzione della dimensionalità . Quando si rappresenta graficamente il file
informazioni, potresti vedere schemi nei dati che ti aiuteranno a scegliere di più
algoritmi di apprendimento automatico appropriati da utilizzare. Ad esempio, se la visualizzazione
contiene gruppi di punti, potrebbe indicare che esistono classi distinte di
informazioni all'interno del set di dati. Quindi un algoritmo di classificazione potrebbe essere appropriato. Di
Ovviamente, devi prima determinare la classe dei campioni in ogni cluster. Questo potrebbe
richiedono lo studio dei campioni in un cluster per vedere cosa hanno in comune.

La riduzione della dimensionalità serve anche ad altri scopi. Stimatori di formazione sui big data
con un numero significativo di dimensioni può richiedere ore, giorni, settimane o più. È anche
difficile per gli esseri umani pensare a dati con un gran numero di dimensioni. Questo è
chiamata la maledizione della dimensionalità . Se i dati hanno caratteristiche strettamente correlate, alcuni
potrebbe essere eliminato tramite la riduzione della dimensionalità per migliorare le prestazioni di formazione.
Ciò, tuttavia, potrebbe ridurre la precisione del modello.

Ricorda che il set di dati Digits è già etichettato con 10 classi che rappresentano le cifre
0-9. Ignoriamo quelle etichette e usiamo la riduzione della dimensionalità per ridurre il set di dati
caratteristiche a due dimensioni, in modo da poter visualizzare i dati risultanti.

Caricamento del set di dati delle cifre

Avvia IPython con:

ipython matplotlib

quindi carica il set di dati:

lecca qui per visualizzare l'immagine del codice

In [1]: da sklearn.datasets importa load_digits

In [2]: digits = load_digits ()

C
Pagina 649

Creazione di uno stimatore TSNE per la riduzione della dimensionalità

Successivamente, useremo lo stimatore TSNE (dal modulo sklearn.manifold ) a


eseguire la riduzione della dimensionalità. Questo stimatore utilizza un algoritmo chiamato tdistributed
0
Stochastic Neighbor Embedding (tSNE) per analizzare le caratteristiche di un set di dati e ridurre
loro al numero di dimensioni specificato. Per prima cosa abbiamo provato il popolare PCA (principal
analisi dei componenti) stimatore ma non ci sono piaciuti i risultati che stavamo ottenendo, quindi abbiamo
passato a TSNE. Mostreremo la PCA più avanti in questo caso di studio.

0
I dettagli dell'algoritmo esulano dallo scopo di questo libro. Per ulteriori informazioni, vedere
TTP: //scikitlearn.org/stable/modules/manifold.html#tsne .

Creiamo un oggetto TSNE per ridurre le caratteristiche di un set di dati a due dimensioni, come
specificato dall'argomento della parola chiave n_components. Come con gli altri stimatori che abbiamo

presentato, abbiamo utilizzato l'argomento della parola chiave random_state per garantire il
riproducibilità della "sequenza di rendering" quando si visualizzano i cluster di cifre:

lecca qui per visualizzare l'immagine del codice

In [3]: da sklearn.manifold import TSNE

In [4]: ​tsne = TSNE (n_components = 2 , random_state = 11 )

Trasformare le caratteristiche del set di dati di cifre in due dimensioni


La riduzione della dimensionalità in scikitlearn richiede tipicamente due passaggi: la formazione del
stimatore con il set di dati, quindi utilizzando lo stimatore per trasformare i dati in
numero di dimensioni specificato. Questi passaggi possono essere eseguiti separatamente con

I metodi TSNE si adattano e si trasformano oppure possono essere eseguiti in un'unica istruzione utilizzando
1
il metodo fit_transform :

1
Ogni chiamata a fit_transform allena lo stimatore. Se intendi riutilizzare il file
stimatore per ridurre le dimensioni dei campioni più volte, utilizzare fit per addestrare una volta il file
stimatore, quindi utilizzare la trasformazione per eseguire le riduzioni. Useremo questa tecnica con

PCA più avanti in questo caso di studio.

lecca qui per visualizzare l'immagine del codice

In [5]: Reduced_data = tsne.fit_transform (digits.data)

C
1h

Pagina 650
Il metodo fit_transform di TSNE richiede del tempo per addestrare lo stimatore e poi eseguire
la riduzione. Sul nostro sistema, ci sono voluti circa 20 secondi. Quando il metodo è completo
il suo compito, restituisce un array con lo stesso numero di righe di digits.data, ma solo
due colonne. Puoi confermarlo controllando la forma ridotta_data:

lecca qui per visualizzare l'immagine del codice

In [6]: Reduced_data.shape
Fuori [6]: (1797, 2)

Visualizzazione dei dati ridotti

Ora che abbiamo ridotto il set di dati originale a solo due dimensioni, utilizziamo uno scatter
tracciare per visualizzare i dati. In questo caso, invece della funzione scatterplot di Seaborn,

useremo la funzione scatter di Matplotlib , perché restituisce una raccolta dei file tracciati
elementi. Utilizzeremo momentaneamente quella funzione in un secondo grafico a dispersione:

lecca qui per visualizzare l'immagine del codice

In [7]: importa matplotlib.pyplot come plt

In [8]: dots = plt.scatter (Reduced_data [:, 0 ], Reduced_data [:, 1 ],


...: c = 'nero' )
...:

I primi due argomenti della dispersione della funzione sono le colonne di ridotti_dati (0 e 1)

contenente i dati per il x ed y assi. L'argomento della parola chiave c = 'black' specifica
il colore dei punti. Non abbiamo etichettato gli assi, perché non corrispondono
caratteristiche specifiche del set di dati originale. Le nuove funzionalità prodotte da TSNE
estimator potrebbe essere molto diverso dalle caratteristiche originali del set di dati.

Il diagramma seguente mostra il grafico a dispersione risultante. Ci sono chiaramente gruppi di


punti di dati correlati, anche se sembrano esserci 11 cluster principali, anziché 10. Là
sono anche punti dati "sciolti" che non sembrano far parte di cluster specifici. Basato su
il nostro precedente studio sul set di dati Digits questo ha senso perché alcune cifre lo erano
difficile da classificare.
C
Pagina 651

Visualizzazione dei dati ridotti con colori diversi per ogni cifra

Sebbene il diagramma precedente mostri i cluster, non sappiamo se tutti gli elementi in
ogni cluster rappresenta la stessa cifra. In caso contrario, i cluster non sono utili.
Usiamo i target noti nel set di dati Digits per colorare tutti i punti in modo da poterli vedere
se questi cluster rappresentano effettivamente cifre specifiche:

lecca qui per visualizzare l'immagine del codice

In [9]: dots = plt.scatter (Red_data [:, 0 ], Red_Data [:, 1 ],


...: c = digits.target, cmap = plt.cm.get_cmap ( 'nipy_spectral_r' , 10 ))
...:
...:

In questo caso, l'argomento della parola chiave scatter c = digits.target specifica che il

i valori target determinano i colori dei punti. Abbiamo anche aggiunto l'argomento parola chiave

lecca qui per visualizzare l'immagine del codice

cmap = plt.cm.get_cmap ( 'nipy_spectral_r' , 10 )

C
Pagina 652
che specifica una mappa dei colori da utilizzare per colorare i punti. In questo caso, sappiamo di esserlo
colorando 10 cifre, quindi usiamo il metodo get_cmap dell'oggetto cm di Matplotlib (da module

matplotlib.pyplot) per caricare una mappa dei colori ('nipy_spectral_r') e selezionare 10


colori distinti dalla mappa dei colori.

La seguente dichiarazione aggiunge una chiave della barra dei colori a destra del diagramma in modo che tu possa vedere
quale cifra rappresenta ogni colore:

lecca qui per visualizzare l'immagine del codice

In [10]: colorbar = plt.colorbar (punti)


Ecco! Vediamo 10 cluster corrispondenti alle cifre 0–9. Di nuovo, ce ne sono alcuni più piccoli
gruppi di punti in piedi da soli. Sulla base di ciò, potremmo decidere che un file supervisionato
l'approccio di apprendimento come i vicini più simpatici funzionerebbe bene con questi dati. Come un
esperimento, potresti voler esaminare Axes3D di Matplotlib , che fornisce x , y ​

e gli assi z per tracciare in grafici tridimensionali.

14.7 CASO DI STUDIO: MACCHINA NON SUPERVISIONATA


APPRENDIMENTO, PARTE 2 - K-MEANS CLUSTERING
In questa sezione, presentiamo forse il più semplice machine learning senza supervisione
algoritmi - kmeans clustering . Questo algoritmo analizza i campioni senza etichetta e
tenta di inserirli in gruppi che sembrano essere correlati. La k in "kmeans"
rappresenta il numero di cluster che vorresti vedere imposti ai tuoi dati.

L'algoritmo organizza i campioni nel numero di cluster specificato in anticipo,


utilizzando calcoli di distanza simili all'algoritmo di clustering dei vicini più simpatici.

Ogni gruppo di campioni è raggruppato attorno a un centroide , il punto centrale del gruppo. Pagina 653

Inizialmente, l'algoritmo sceglie k centroidi a caso dai campioni del set di dati. Poi
i campioni rimanenti vengono posti nel cluster il cui baricentro è il più vicino. Il
i centroidi vengono ricalcolati in modo iterativo e i campioni riassegnati ai cluster fino a quando, per
tutti i cluster, le distanze da un dato centroide ai campioni nel suo cluster sono
minimizzato. I risultati dell'algoritmo sono:

una matrice unidimensionale di etichette che indica il cluster a cui appartiene ogni campione
appartiene e

una matrice bidimensionale di centroidi che rappresenta il centro di ogni ammasso.

Set di dati Iris


2
Lavoreremo con il popolare dataset Iris in bundle con scikitlearn, che è
comunemente analizzato sia con la classificazione che con il raggruppamento. Sebbene questo set di dati sia
etichettato, ignoreremo quelle etichette qui per dimostrare il clustering. Quindi, useremo il file
etichette per determinare quanto bene l'algoritmo kmeans ha raggruppato i campioni.

2
Fisher, RA, L'uso di più misurazioni in problemi tassonomici, Annuale
Eugenics, 7, Part II, 179188 (1936); anche in Contributions to Mathematical Statistics
(John Wiley, NY, 1950).

Il set di dati Iris è denominato "set di dati giocattolo" perché contiene solo 150 campioni e
quattro caratteristiche. Il set di dati descrive 50 campioni per ciascuna delle tre specie di fiori di Iris
- Iris setosa , Iris versicolor e Iris virginica . Le foto di questi sono mostrate di seguito. Ogni
le caratteristiche del campione sono la lunghezza del sepalo, la larghezza del sepalo, la lunghezza del petalo e la larghezza del petalo, tutte
misurata in centimetri. I sepali sono le parti esterne più grandi di ogni fiore che
proteggere i petali interni più piccoli prima che i boccioli fioriscano.

1E

Pagina 654

Iris setosa :
https://commons.wikimedia.org/wiki/File:Wild_iris_KEFJ_(9025144383).jpg.

Credito: per gentile concessione dei servizi di Nation Park.


Pagina 655

Iris versicolor : https://commons.wikimedia.org/wiki/Iris_versicolor#/media/

File: IrisVersicolorFoxRoostNewfoundland.jpg.

Credito: per gentile concessione di Jefficus,

https://commons.wikimedia.org/w/index.php?
title = Utente: Jefficus & action = edit & redlink = 1

Pagina 656
Iris virginica : https://commons.wikimedia.org/wiki/File:IMG_7911Iris_virginica.jpg.

Credito: Christer T Johansson.

14.7.1 Caricamento del set di dati Iris


Avvia IPython con ipython matplotlib, quindi usa sklearn.datasets
funzione load_iris del modulo per ottenere un Bunch contenente il set di dati:

lecca qui per visualizzare l'immagine del codice

In [1]: da sklearn.datasets importa load_iris

In [2]: iris = load_iris ()

L'attributo DESCR del mazzo indica che ci sono 150 campioni (numero di

Istanze), ciascuna con quattro funzioni (Numero di attributi). Non ci sono


valori mancanti in questo set di dati. Il set di dati classifica i campioni etichettandoli con
gli interi 0, 1 e 2, che rappresentano Iris setosa , Iris versicolor e Iris virginica ,
rispettivamente. Ci ignoriamo le etichette e lasciare che il Kmeans di clustering algoritmo di cercare di

C
Pagina 657
determinare le classi dei campioni. Mostriamo alcune informazioni chiave DESCR in grassetto:

lecca qui per visualizzare l'immagine del codice

n [3]: print (iris.DESCR)


.. _iris_dataset:

Set di dati delle piante di Iris

** Caratteristiche del set di dati: **

: Numero di istanze: 150 (50 in ciascuna delle tre classi)


: Numero di attributi: 4 attributi numerici e predittivi e la classe
: Informazioni sugli attributi:
lunghezza dei sepali in cm
larghezza del sepalo in cm
lunghezza petalo in cm
larghezza petalo in cm
classe:
IrisSetosa
IrisVersicolour
IrisVirginica

:Statistiche riassuntive:

============== ==== ==== ======= ===== ================ ====


Correlazione classe SD media min max
============== ==== ==== ======= ===== ================ ====
lunghezza del sepalo: 4,3 7,9 5,84 0,83 0,7826
larghezza del sepalo: 2,0 4,4 3,05 0,43 0,4194
lunghezza del petalo: 1,0 6,9 3,76 1,76 0,9490 (alto!)
larghezza petalo: 0,1 2,5 1,20 0,76 0,9565 (alto!)
============== ==== ==== ======= ===== ================ ====

: Valori attributo mancanti: Nessuno


: Distribuzione per classi: 33,3% per ciascuna delle 3 classi.
: Creatore: RA Fisher
: Donatore: Michael Marshall (MARSHALL%PLU@io.arc.nasa.gov)
: Data: luglio 1988

Il famoso database Iris, utilizzato per la prima volta da Sir RA Fisher.Il set di dati viene recuperato
l'UCI Machine Learning Repository, che ha due punti dati errati.

Questo è forse il database più conosciuto che si trova nel pattern


letteratura di riconoscimento. La carta di Fisher è un classico nel campo e
si fa spesso riferimento a questo giorno. (Vedi Duda & Hart, per esempio.) I dati
si riferisce a un tipo di pianta di iris. Una classe è separabile linearmente da
altri 2; questi ultimi NON sono separabili linearmente tra loro.

.. argomento :: Riferimenti

Fisher, RA "L'uso di più misurazioni in tassonomica Pagina 658


i problemi"
Annual Eugenics, 7, Part II, 179188 (1936); anche in "Contributions
a Mathematical Statistics "(John Wiley, NY, 1950).
Duda, RO, & Hart, PE (1973) Pattern Classification and Scene
Analisi.
(Q327.D83) John Wiley & Sons. ISBN 0471223611. Vedere pagina 218.
Dasarathy, BV (1980) "Nosing Around the Neighbourhood: A New System
Struttura e regola di classificazione per il riconoscimento in parte
Ambienti esposti ". Transazioni IEEE sull'analisi dei modelli e
Machine Intelligence, vol. PAMI2, n. 1, 6771.
Gates, GW (1972) "The Reduced Nearest Neighbor Rule". IEEE
Transactions on Information Theory, maggio 1972, 431433.
Vedi anche: 1988 MLC Proceedings, 5464. Cheeseman et al "s AUTOCLASS
II sistema di clustering concettuale trova 3 classi nei dati.
Molti, molti altri ...

controllo del numero di campioni, caratteristiche e obiettivi

È possibile confermare il numero di campioni e funzioni per campione tramite l'array di dati

forma e puoi confermare il numero di bersagli tramite la forma dell'array di destinazione:

lecca qui per visualizzare l'immagine del codice

In [4]: ​iris.data.shape
Uscita [4]: ​(150, 4)

In [5]: iris.target.shape
Uscita [5]: (150,)

L'array target_names contiene i nomi per le etichette numeriche dell'array di destinazione


—Dtype = '<U10' indica che gli elementi sono stringhe con un massimo di 10
personaggi:

lecca qui per visualizzare l'immagine del codice

In [6]: iris.target_names
Uscita [6]: array (['setosa', 'versicolor', 'virginica'], dtype = '<U10')

L'array feature_names contiene un elenco di nomi di stringhe per ogni colonna nei dati
Vettore:

lecca qui per visualizzare l'immagine del codice


C
C
Pagina 659
In [7]: iris.feature_names
Fuori [7]:
["lunghezza del sepalo (cm)",
'larghezza del sepalo (cm)',
'lunghezza petalo (cm)',
"larghezza petalo (cm)"]

14.7.2 Esplorazione del set di dati Iris: statistiche descrittive con i panda
Usiamo un DataFrame per esplorare il set di dati Iris. Come abbiamo fatto nel California Housing
caso di studio, impostiamo le opzioni panda per la formattazione degli output basati su colonne:

lecca qui per visualizzare l'immagine del codice

In [8]: importa i panda come pd

In [9]: pd.set_option ( 'max_columns' , 5 )

In [10]: pd.set_option ( 'display.width' , Nessuno )

Crea un DataFrame contenente il contenuto della matrice di dati, utilizzando il contenuto del file

feature_names array come nomi di colonna:

lecca qui per visualizzare l'immagine del codice

In [11]: iris_df = pd.DataFrame (iris.data, colonne = iris.feature_names)

Successivamente, aggiungi una colonna contenente il nome della specie di ciascun campione. La comprensione della lista in
il frammento di codice seguente utilizza ogni valore nella matrice di destinazione per cercare il corrispondente
nome della specie nell'array target_names:

lecca qui per visualizzare l'immagine del codice

In [12]: iris_df [ 'species' ] = [iris.target_names [i] for i in iris.targ t]

usa i panda per guardare alcuni campioni. Notate ancora una volta che i panda mostrano un \ a

la destra delle intestazioni di colonna per indicare che ci sono più colonne visualizzate di seguito:

lecca qui per visualizzare l'immagine del codice

L
C
Pagina 660
In [13]: iris_df.head ()
Fuori [13]:
lunghezza del sepalo (cm) larghezza del sepalo (cm) lunghezza del petalo (cm) \
0 5.1 3.5 1.4
1 4.9 3.0 1.4
2 4.7 3.2 1.3
3 4.6 3.1 1.5
4 5,0 3,6 1,4

specie di larghezza petalo (cm)


0 0,2 setosa
1 0,2 setosa
2 0.2 setosa
3 0.2 setosa
4 0.2 setosa

Calcoliamo alcune statistiche descrittive per le colonne numeriche:

lecca qui per visualizzare l'immagine del codice

In [14]: pd.set_option ( 'precision' , 2 )

In [15]: iris_df.describe ()
Fuori [15]:
lunghezza del sepalo (cm) larghezza del sepalo (cm) lunghezza del petalo (cm) \
contare 150,00 150,00 150,00
media 5,84 3,06 3,76
std 0,83 0,44 1,77
min 4,30 2,00 1,00
25% 5,10 2,80 1,60
50% 5,80 3,00 4,35
75% 6,40 3,30 5.10
max 7,90 4,40 6,90

larghezza petalo (cm)


contare 150.00
significa 1.20
std 0.76
min 0,10
25% 0,30
50% 1,30
75% 1,80
max 2,50

Chiamare il metodo di descrizione nella colonna "specie" conferma che contiene

tre valori unici. Qui, sappiamo prima di lavorare con questi dati che ci sono
tre classi a cui appartengono i campioni, sebbene questo non sia sempre il caso in
apprendimento automatico non supervisionato.

C
Pagina 661
lecca qui per visualizzare l'immagine del codice

In [16]: iris_df [ 'species' ] .describe ()


Fuori [16]:
contare 150
unico 3
top setosa
freq 50
Nome: specie, tipo: oggetto

14.7.3 Visualizzazione del set di dati con un pairplot Seaborn

Visualizziamo le caratteristiche in questo set di dati. Un modo per saperne di più sui tuoi dati è
vedere come le caratteristiche si relazionano tra loro. Il set di dati ha quattro caratteristiche. Non possiamo
graficare uno contro gli altri tre in un unico grafico. Tuttavia, possiamo tracciare coppie di file
caratteristiche l'una contro l'altra. Snippet [20] utilizza il pairplot della funzione Seaborn per creare
una griglia di grafici che traccia ogni caratteristica rispetto a se stessa e alle altre caratteristiche specificate:

lecca qui per visualizzare l'immagine del codice

In [17]: importa seaborn come sns

In [18]: sns.set (font_scale = 1.1 )

In [19]: sns.set_style ( 'whitegrid' )

In [20]: grid = sns.pairplot (data = iris_df, vars = iris_df.columns [0 : 4 ],


...: hue = 'specie' )
...:

Gli argomenti delle parole chiave sono:

3
data: DataFrame contenente i dati da tracciare.

3
Anche questo può essere un array o un elenco bidimensionale.

vars: una sequenza contenente i nomi delle variabili da tracciare. Per un DataFrame,
questi sono i nomi delle colonne da tracciare. Qui, usiamo i primi quattro DataFrame
colonne, che rappresentano la lunghezza del sepalo, la larghezza del sepalo, la lunghezza del petalo e la larghezza del petalo,
rispettivamente.

tonalità: la colonna DataFrame utilizzata per determinare i colori dei dati tracciati.
In questo caso, coloreremo i dati per specie di Iris .

1C

Pagina 662
La precedente chiamata a pairplot produce la seguente griglia di grafici 4by4:

I grafici lungo la diagonale in alto a sinistra in basso a destra mostrano la distribuzione di just
l'elemento tracciato in quella colonna, con l'intervallo di valori (lefttoright) e
numero di campioni con questi valori (dall'alto in basso). Considera la lunghezza sepall
distribuzioni:

L'area ombreggiata più alta indica che l'intervallo dei valori di lunghezza dei sepali (mostrato lungo il
x asse) per Iris setosa è di circa 4-6 centimetri e che la maggior parte setosa Iris
i campioni si trovano al centro di tale intervallo (circa 5 centimetri). Allo stesso modo, il
l'area ombreggiata più a destra indica che l'intervallo dei valori di lunghezza dei sepali per Iris virginica
è di circa 4-8,5 centimetri e che ha la maggior parte dei campioni di Iris virginica
valori di lunghezza dei sepali compresi tra 6 e 7 centimetri.

Gli altri grafici in una colonna mostrano grafici a dispersione delle altre caratteristiche rispetto a
caratteristica sull'asse x . Nella prima colonna, gli altri tre grafici tracciano la larghezza del sepalo,
lunghezza del petalo e larghezza del petalo, rispettivamente, lungo l' asse ye la lunghezza del sepalo lungo

T
Pagina 663
l' asse x .

Quando esegui questo codice, vedrai nell'output a colori che utilizza colori separati per
ogni specie di Iris mostra come le specie si relazionano tra loro su una caratteristica per caratteristica
base. È interessante notare che tutti i grafici a dispersione separano chiaramente i punti blu Iris setosa da
i punti arancioni e verdi delle altre specie, a indicare che Iris setosa è effettivamente in una “classe
da solo." Possiamo anche vedere che le altre due specie a volte possono essere confuse con
l'un l'altro, come indicato dai punti arancioni e verdi sovrapposti. Ad esempio, se tu
guarda il grafico a dispersione per la larghezza del sepalo rispetto alla lunghezza del sepalo, vedrai Iris versicolor e
I punti di Iris virginica sono mescolati. Ciò indica che sarebbe difficile distinguere
tra queste due specie se avessimo a nostra disposizione solo le misurazioni dei sepali.

Visualizzazione del pairplot in un colore

Se rimuovi l'argomento della parola chiave hue, la funzione pairplot utilizza solo un colore per
traccia tutti i dati perché non sa distinguere la specie:

lecca qui per visualizzare l'immagine del codice

In [21]: grid = sns.pairplot (data = iris_df, vars = iris_df.columns [0 : 4 ])

Come puoi vedere nel grafico a coppie risultante nella pagina successiva, in questo caso, i grafici lungo
le diagonali sono istogrammi che mostrano le distribuzioni di tutti i valori per quella caratteristica,
indipendentemente dalla specie. Mentre studi ogni grafico a dispersione, sembra che potrebbe esserci
solo due cluster distinti, anche se per questo set di dati sappiamo che ci sono tre specie.
Se non conosci in anticipo il numero di cluster, potresti chiedere a un esperto di dominio
che conosce a fondo i dati. Una persona simile potrebbe sapere che ce ne sono tre
specie nel set di dati, che sarebbe un'informazione preziosa mentre cerchiamo di eseguire
machine learning sui dati.

I diagrammi a coppie funzionano bene per un piccolo numero di funzionalità o un sottoinsieme di


caratteristiche in modo da avere un numero limitato di righe e colonne e per un relativamente
piccolo numero di campioni in modo da poter vedere i punti dati. Poiché il numero di funzioni e
i campioni aumentano, ogni grafico a dispersione diventa rapidamente troppo piccolo per essere letto. Per i più grandi
set di dati, puoi scegliere di tracciare un sottoinsieme delle caratteristiche e potenzialmente un file
sottoinsieme selezionato dei campioni per avere un'idea dei dati.

C
Pagina 664
14.7.4 Utilizzo di uno stimatore KMeans

In questa sezione, useremo il clustering di kmeans tramite lo stimatore KMeans di scikitlearn (da
il modulo sklearn.cluster ) per posizionare ogni campione nel set di dati Iris in un cluster.
Come con gli altri stimatori che hai usato, lo stimatore KMeans ti nasconde il file

complessi dettagli matematici dell'algoritmo, che lo rendono semplice da usare.

Creazione dello stimatore

Creiamo l'oggetto KMeans:

lecca qui per visualizzare l'immagine del codice

In [22]: da sklearn.cluster import KMeans

In [23]: kmeans = KMeans (n_clusters = 3 , random_state = 11 )

L'argomento della parola chiave n_clusters specifica l'algoritmo di clustering kmeans


iperparametro k , che KMeans richiede per calcolare i cluster ed etichettare ciascuno
campione. Quando addestri uno stimatore KMeans, l'algoritmo calcola per ogni cluster a
centroide che rappresenta il punto dati centrale del cluster.

Il valore predefinito per il parametro n_clusters è 8. Spesso ti baserai sul dominio Pagina 665

esperti informati sui dati per aiutare a scegliere un valore k appropriato . Però,
con l'ottimizzazione dell'iperparametro, puoi stimare il k appropriato , come faremo in seguito. Nel
in questo caso, sappiamo che ci sono tre specie, quindi useremo n_clusters = 3 per vedere quanto bene

KMeans lo fa nell'etichettare i campioni di Iris. Ancora una volta, abbiamo usato random_state
argomento della parola chiave per la riproducibilità.

Adattamento del modello

Successivamente, addestreremo lo stimatore chiamando il metodo di adattamento dell'oggetto KMeans. Questo passaggio
esegue l'algoritmo kmeans discusso in precedenza:

lecca qui per visualizzare l'immagine del codice

In [24]: kmeans.fit (iris.data)


Fuori [24]:
KMeans (algoritmo = 'auto', copy_x = True, init = 'kmeans ++', max_iter = 300,
n_clusters = 3, n_init = 10, n_jobs = Nessuno, precompute_distances = 'auto',
random_state = 11, tol = 0.0001, verbose = 0)

Come con gli altri stimatori, il metodo fit restituisce l'oggetto stimatore e IPython

mostra la sua rappresentazione di stringa. Puoi vedere gli argomenti predefiniti di KMeans in:

ttps: //scikitlearn.org/stable/modules/generated/sklearn.cluster.KMeans.h ml
Una volta completato l'addestramento, l'oggetto KMeans contiene:

Una matrice di label_ con valori da 0 a n_clusters 1 (in questo esempio, 0–2),
indicando i cluster a cui appartengono i campioni.

Un array cluster_centers_ in cui ogni riga rappresenta un centroide.

Confronto delle etichette del cluster di computer con la destinazione del set di dati Iris
Valori
Poiché il set di dati Iris è etichettato, possiamo esaminare i suoi valori di matrice di destinazione per avere un'idea
di quanto bene l'algoritmo kmeans ha raggruppato i campioni per le tre specie di Iris . Con
dati senza etichetta, dovremmo dipendere da un esperto di dominio per valutare se il file
le classi previste hanno un senso.

C
hW

In questo set di dati, i primi 50 campioni sono Iris setosa , i successivi 50 sono Iris versicolor e Pagina 666

gli ultimi 50 sono Iris virginica . L'array di destinazione del set di dati Iris li rappresenta con l'estensione
valori 0–2. Se lo stimatore di KMeans ha scelto perfettamente i cluster, allora ogni gruppo di 50
gli elementi nell'array label_ dello stimatore dovrebbero avere un'etichetta distinta. Mentre studi
dai risultati sotto, nota che lo stimatore KMeans usa i valori da 0 a k - 1 a
cluster di etichette, ma non sono correlati all'array di destinazione del set di dati Iris.

Usiamo l'affettatura per vedere come è stato raggruppato ciascun gruppo di 50 campioni di Iris. Il seguente
lo snippet mostra che i primi 50 campioni sono stati tutti inseriti nel cluster 1:

lecca qui per visualizzare l'immagine del codice

In [25]: print (kmeans.labels_ [ 0 : 50 ])


[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1]

I successivi 50 campioni dovrebbero essere inseriti in un secondo cluster. Il seguente frammento


mostra che la maggior parte è stata collocata nel cluster 0, ma due campioni sono stati inseriti nel cluster 2:

lecca qui per visualizzare l'immagine del codice

In [26]: print (kmeans.labels_ [ 50 : 100 ])


[0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0]

Allo stesso modo, gli ultimi 50 campioni dovrebbero essere inseriti in un terzo cluster. Il seguente
lo snippet mostra che molti di questi campioni sono stati inseriti nel cluster 2, ma 14 di
i campioni sono stati inseriti nel cluster 0, indicando che l'algoritmo pensava che appartenessero

a un cluster diverso:

lecca qui per visualizzare l'immagine del codice

In [27]: print (kmeans.labels_ [ 100 : 150 ])


[2 0 2 2 2 2 0 2 2 2 2 2 2 0 0 2 2 2 2 0 2 0 2 0 2 2 0 0 2 2 2 2 2 0 2
2 2 0 2 2 2 0 2 2 2 0 2 2 0]

I risultati di questi tre frammenti confermano ciò che abbiamo visto nei diagrammi a coppie
all'inizio di questa sezione — che Iris setosa è “in una classe a sé stante” e che ce n'è qualcuna

confusione tra Iris versicolor e Iris virginica . Pagina 667

14.7.5 Riduzione della dimensionalità con componente principale


Analisi
Successivamente, useremo lo stimatore PCA (dal modulo sklearn.decomposition ) a
eseguire la riduzione della dimensionalità. Questo stimatore utilizza un algoritmo chiamato principal
4
analisi dei componenti per analizzare le caratteristiche di un set di dati e ridurle a quanto specificato
numero di dimensioni. Per il set di dati Iris, abbiamo prima provato lo stimatore TSNE mostrato
prima ma non mi sono piaciuti i risultati che stavamo ottenendo. Quindi siamo passati a PCA per

seguente dimostrazione.

4
I dettagli dell'algoritmo esulano dallo scopo di questo libro. Per ulteriori informazioni, vedere
ttps: //scikitlearn.org/stable/modules/decomposition.html#pca .

Creazione dell'oggetto PCA

Come lo stimatore TSNE, uno stimatore PCA utilizza l'argomento parola chiave n_components

per specificare il numero di dimensioni:

lecca qui per visualizzare l'immagine del codice

In [28]: da sklearn.decomposition import PCA

In [29]: pca = PCA (n_components = 2 , random_state = 11 )

Trasformare le funzionalità del set di dati Iris in due dimensioni

Addestriamo lo stimatore e produciamo i dati ridotti chiamando lo stimatore PCA


metodi adattano e trasformano metodi:

lecca qui per visualizzare l'immagine del codice

In [30]: pca.fit (iris.data)


Fuori [30]:
PCA (copy = True, iterated_power = 'auto', n_components = 2, random_state = 11,
svd_solver = 'auto', tol = 0.0, whiten = False)

In [31]: iris_pca = pca.transform (iris.data)

Quando il metodo completa la sua attività, restituisce un array con lo stesso numero di righe
come iris.data, ma solo due colonne. Confermiamolo controllando iris_pca's

C
1h

Pagina 668
forma:

lecca qui per visualizzare l'immagine del codice

In [32]: iris_pca.shape
Uscita [32]: (150, 2)

Si noti che abbiamo chiamato separatamente i metodi di adattamento e trasformazione dello stimatore PCA,
piuttosto che fit_transform, che abbiamo usato con lo stimatore TSNE. In questo esempio,
stiamo andando a riutilizzare lo stimatore addestrato (prodotto con fit) per eseguire una seconda
trasformare per ridurre i centroidi del cluster da quattro dimensioni a due. Questo sarà
ci consentono di tracciare le posizioni del centroide su ciascun cluster.

Visualizzazione dei dati ridotti

Ora che abbiamo ridotto il set di dati originale a solo due dimensioni, utilizziamo uno scatter
tracciare per visualizzare i dati. In questo caso, useremo la funzione scatterplot di Seaborn. Primo,
trasformiamo i dati ridotti in un DataFrame e aggiungiamo una colonna di specie che faremo
utilizzare per determinare i colori dei punti:

lecca qui per visualizzare l'immagine del codice

In [33]: iris_pca_df = pd.DataFrame (iris_pca,


...: colonne = [ "Component1" , "Component2" ])
...:

In [34]: iris_pca_df [ 'species' ] = iris_df.species

Successivamente, tracciamo a dispersione i dati in Seaborn:

lecca qui per visualizzare l'immagine del codice

In [35]: axes = sns.scatterplot (data = iris_pca_df, x = 'Component1' ,


...: y = 'Component2' , hue = 'species' , legend = 'brief' ,
...: palette = 'cool' )
...:

Ogni centroide nell'array cluster_centers_ dell'oggetto KMeans ha lo stesso numero


di funzionalità come il set di dati originale (quattro in questo caso). Per tracciare i centroidi, dobbiamo
ridurne le dimensioni. Puoi pensare a un centroide come al campione "medio" nel suo
grappolo. Quindi ogni centroide dovrebbe essere trasformato usando lo stesso stimatore PCA che abbiamo usato

C
Pagina 669
per ridurre gli altri campioni in quel cluster:

lecca qui per visualizzare l'immagine del codice

In [36]: iris_centers = pca.transform (kmeans.cluster_centers_)

Ora tracceremo i centroidi dei tre cluster come punti neri più grandi. Piuttosto che
trasforma prima l'array iris_centers in un DataFrame, usiamo Matplotlib's

funzione scatter per tracciare i tre centroidi:

lecca qui per visualizzare l'immagine del codice

In [37]: importa matplotlib.pyplot come plt

In [38]: dots = plt.scatter (iris_centers [:, 0 ], iris_centers [:, 1 ],


...: s = 100 , c = 'k' )
...:

L'argomento della parola chiave s = 100 specifica la dimensione dei punti tracciati e la parola chiave
l'argomento c = 'k' specifica che i punti devono essere visualizzati in nero.
C 14.7.6 Scelta del miglior stimatore di clustering

14.7.6 Scelta del miglior stimatore di clustering Pagina 670

Come abbiamo fatto negli studi di casi di classificazione e regressione, eseguiamo più clustering
algoritmi e vedere quanto bene raggruppano le tre specie di fiori di Iris. Qui lo faremo
tentare di raggruppare i campioni del set di dati Iris utilizzando l'oggetto kmeans che abbiamo creato
5
prima e oggetti di DBSCAN, MeanShift, SpectralClustering di scikitlearn
e stimatori di Agglomerative Clustering. Come KMeans, specifichi il numero
di cluster in anticipo per SpectralClustering e

Stimatori di raggruppamento agglomerativo:

5
Stiamo eseguendo KMeans qui sul piccolo set di dati Iris. Se riscontri prestazioni
problemi con KMeans su set di dati più grandi, considera l'utilizzo di MiniBatchKMeans

estimatore. La documentazione di scikitlearn indica che MiniBatchKMeans è più veloce


su set di dati di grandi dimensioni ei risultati sono quasi altrettanto buoni.

lecca qui per visualizzare l'immagine del codice

In [39]: da sklearn.cluster import DBSCAN, MeanShift, \


...: SpectralClustering, AgglomerativeClustering

In [40]: estimators = {
...: "KMeans" : kmeans,
...: "DBSCAN" : DBSCAN (),
...: 'MeanShift' : MeanShift (),
...: 'SpectralClustering' : SpectralClustering (n_clusters = 3 ),
...: "AgglomerativeClustering" :
...: AgglomerativeClustering (n_clusters = 3 )
...:}

Ogni iterazione del ciclo seguente chiama il metodo di adattamento di uno stimatore con iris.data

come argomento, quindi utilizza la funzione unica di NumPy per ottenere le etichette del cluster e
conta per i tre gruppi di 50 campioni e visualizza i risultati. Ricordalo per il
Stimatori DBSCAN e MeanShift, non abbiamo specificato il numero di cluster in
progredire. È interessante notare che DBSCAN ha previsto correttamente tre cluster (etichettati 1, 0 e 1),
anche se ha collocato 84 dei 100 campioni di Iris virginica e Iris versicolor nello stesso
grappolo. Lo stimatore MeanShift, d'altra parte, ha previsto solo due cluster
(etichettato come 0 e 1) e ha posizionato 99 dei 100 campioni di Iris virginica e Iris versicolor

nello stesso cluster:

lecca qui per visualizzare l'immagine del codice


In [41]: importa numpy come np

1C

Pagina 671
n [42]: per nome, estimator in estimators.items ():
...: estimator.fit (iris.data)
...: print (f '\ n {name} :' )
...: per i in range ( 0 , 101 , 50 ):
...: etichette, conteggi = np.unique (
...: estimator.labels_ [i: i + 50 ], return_counts = True )
...: print (f ' {i} {i + 50 }: ' )
...: per etichetta, conta in zip (etichette, conteggi):
...: print (f 'label = {label} , count = {count} ' )
...:

KMeans:
050:
label = 1, count = 50
50100:
label = 0, count = 48
label = 2, count = 2
100150:
label = 0, count = 14
label = 2, count = 36

DBSCAN:
050:
label = 1, count = 1
label = 0, count = 49
50100:
label = 1, count = 6
label = 1, count = 44
100150:
label = 1, count = 10
label = 1, count = 40

MeanShift:
050:
label = 1, count = 50
50100:
label = 0, count = 49
label = 1, count = 1
100150:
label = 0, count = 50

SpectralClustering:
050:
label = 2, count = 50
50100:
label = 1, count = 50
100150:
label = 0, count = 35
label = 1, count = 15

Agglomerato Clustering:
050:
label = 1, count = 50

io

50100: Pagina 672


label = 0, count = 49
label = 2, count = 1
100150:
label = 0, count = 15
label = 2, count = 35

Sebbene questi algoritmi etichettino ogni campione, le etichette indicano semplicemente i cluster.
Cosa fai con le informazioni sul cluster una volta che le hai? Se il tuo obiettivo è utilizzare l'estensione
dati nell'apprendimento automatico supervisionato, in genere studieresti i campioni in ogni cluster
per cercare di determinare come sono correlati e di etichettarli di conseguenza. Come vedremo nel
capitolo successivo, l'apprendimento senza supervisione è comunemente usato nelle applicazioni di deeplearning.
Alcuni esempi di dati non etichettati elaborati con l'apprendimento non supervisionato includono i tweet
da Twitter, post di Facebook, video, foto, articoli di notizie, prodotti dei clienti
recensioni, recensioni di film degli spettatori e altro ancora.

14.8 WRAP-UP
In questo capitolo abbiamo iniziato il nostro studio sull'apprendimento automatico, utilizzando il popolare scikitlearn
biblioteca. Abbiamo visto che l'apprendimento automatico è diviso in due tipi. Macchina supervisionata
learning, che funziona con dati etichettati e machine learning non supervisionato che
funziona con dati senza etichetta. In questo capitolo abbiamo continuato a sottolineare
visualizzazioni che utilizzano Matplotlib e Seaborn, in particolare per conoscere i dati.

Abbiamo discusso di come scikitlearn impacchetta convenientemente algoritmi di apprendimento automatico come file
stimatori. Ognuno è incapsulato in modo da poter creare rapidamente i tuoi modelli con un piccolo
quantità di codice, anche se non conosci i dettagli intricati di come questi algoritmi
lavoro.

Abbiamo esaminato l'apprendimento automatico supervisionato con la classificazione, quindi la regressione. Abbiamo usato
uno degli algoritmi di classificazione più semplici, vicini più affezionati, per analizzare le cifre
set di dati in bundle con scikitlearn. Hai visto che gli algoritmi di classificazione prevedono il
classi a cui appartengono i campioni. La classificazione binaria utilizza due classi (come "spam"
o "non spam") e la multiclassificazione utilizza più di due classi (come la 10
classi nel set di dati Digits).

Abbiamo eseguito i passaggi di un tipico case study di machine learning, incluso il caricamento del file
dataset, esplorando i dati con panda e visualizzazioni, dividendo i dati per
formazione e test, creazione del modello, addestramento del modello e previsione.
Abbiamo discusso il motivo per cui dovresti suddividere i tuoi dati in un set di addestramento e un set di test.
Hai visto modi per valutare l'accuratezza di uno stimatore di classificazione tramite una matrice di confusione

trovare un rapporto di classificazione. Pagina 673

Abbiamo detto che è difficile sapere in anticipo quale modello avrà le migliori prestazioni
sui tuoi dati, quindi in genere provi molti modelli e scegli quello che funziona meglio. Noi
ha mostrato che è facile eseguire più stimatori. Abbiamo anche utilizzato l'ottimizzazione degli iperparametri
con kfold crossvalidation per scegliere il miglior valore di k per l'algoritmo kNN.

Abbiamo rivisitato le serie temporali e un semplice esempio di regressione lineare da APITOLO 10 s’


Introduzione alla sezione Data Science, questa volta implementandola utilizzando uno scikitlearn
Stimatore LinearRegression. Successivamente, abbiamo utilizzato uno stimatore LinearRegression per
eseguire la regressione lineare multipla con il set di dati California Housing in bundle
con scikitlearn. Hai visto che lo stimatore LinearRegression, per impostazione predefinita, usa all
le caratteristiche numeriche in un set di dati per fare previsioni più sofisticate di te
può con una semplice regressione lineare. Di nuovo, abbiamo eseguito più stimatori di scikitlearn su
confronta come si sono comportati e scegli il migliore.

Successivamente, abbiamo introdotto un machine learning non supervisionato e abbiamo detto che lo è
tipicamente realizzato con algoritmi di clustering. Abbiamo utilizzato la dimensionalità introdotta
riduzione (con lo stimatore TSNE di scikitlearn) e lo ha utilizzato per comprimere le cifre

64 funzioni del set di dati fino a due per scopi di visualizzazione. Questo ci ha permesso di vedere il file
raggruppamento dei dati delle cifre.

Abbiamo presentato uno dei più semplici algoritmi di apprendimento automatico non supervisionato, kmeans
clustering e il clustering dimostrato sul set di dati Iris che è anche in bundle con
scikitlearn. Abbiamo usato la riduzione della dimensionalità (con lo stimatore PCA di scikitlearn) a
comprimere le quattro funzionalità del set di dati Iris a due per scopi di visualizzazione per mostrare il file
clustering delle tre specie di Iris nel dataset e dei loro centroidi. Infine, siamo scappati
più stimatori di clustering per confrontare la loro capacità di etichettare i campioni del set di dati Iris
in tre gruppi.

Nel prossimo capitolo, continueremo il nostro studio sulle tecnologie di apprendimento automatico con
apprendimento approfondito. Affronteremo alcuni problemi affascinanti e impegnativi.

C
un'
Pagina 674

laylist

storia 15. Apprendimento profondo


Obiettivi
opiche

In questo capitolo potrai:


guadagnando Pat

Comprendi cos'è una rete neurale e come consente il deep learning.


ffers & Dea

Crea reti neurali Keras.


ighlights

Comprendere i livelli di Keras, le funzioni di attivazione, le funzioni di perdita e gli ottimizzatori.


ettings

Utilizzare una rete neurale convoluzionale (CNN) di Keras addestrata sul set di dati MNIST per
Supporto riconoscere le cifre scritte a mano.

Disconnessione Utilizzare una rete neurale ricorrente (RNN) di Keras addestrata sul set di dati IMDb per eseguire
classificazione binaria delle recensioni di film positive e negative.

Usa TensorBoard per visualizzare l'avanzamento della formazione delle reti di deeplearning.

Scopri quali reti neurali pre-addestrate vengono fornite con Keras.

Comprendi il valore dell'utilizzo di modelli pre-addestrati sull'enorme set di dati ImageNet per
app per visione artificiale.

Contorno

5.1 Introduzione

5.1.1 Applicazioni di deep learning

5.1.2 Demo di deep learning

5.1.3 Risorse Keras

5.2 Set di dati incorporati di Keras

5.3 Ambienti Anaconda personalizzati

5.4 Reti neurali

5.5 Tensori
5.6 Reti neurali convoluzionali per la visione; MultiClassificazione con il set di dati MNIST

5.6.1 Caricamento del set di dati MNIST Pagina 675

5.6.2 Esplorazione dei dati

5.6.3 Preparazione dei dati

5.6.4 Creazione della rete neurale

5.6.5 Formazione e valutazione del modello

5.6.6 Salvataggio e caricamento di un modello

5.7 Visualizzazione dell'addestramento alla rete neurale con TensorBoard

5.8 ConvnetJS: formazione e visualizzazione di DeepLearning basate su browser

5.9 Reti neurali ricorrenti per sequenze; ​analisi del sentiment con il set di dati IMDb

5.9.1 Caricamento del set di dati delle recensioni dei film di IMDb

5.9.2 Esplorazione dei dati

5.9.3 Preparazione dei dati

5.9.4 Creazione della rete neurale

5.9.5 Formazione e valutazione del modello

5.10 Ottimizzazione dei modelli di deep learning

5.11 Modelli Convnet pre-addestrati su ImageNet

5.12 WrapUp

15.1 INTRODUZIONE
Una delle aree più interessanti dell'IA è il deep learning , un potente sottoinsieme del machine learning
ha prodotto risultati impressionanti nella visione artificiale e in molte altre aree negli ultimi pochi
anni. La disponibilità di big data, una notevole potenza del processore, velocità Internet più elevate e
i progressi nell'hardware e nel software del calcolo parallelo stanno rendendo possibile di più
organizzazioni e individui per perseguire soluzioni di apprendimento profondo ad alta intensità di risorse.

Keras e TensorFlow

Nel capitolo precedente, Scikitlearn ti ha permesso di definire modelli di machine learning


comodamente con una sola dichiarazione. I modelli di deep learning richiedono configurazioni più sofisticate,
tipicamente connettono più oggetti, chiamati strati . Costruiremo i nostri modelli di deep learning
con Keras , che offre un'interfaccia amichevole a TensorFlow di Google , la più diffusa
1
libreria di deeplearning usata . François Chollet del team di Google Mind ha sviluppato Keras per
rendere le capacità di deeplearning più accessibili. Il suo libro Deep Learning with Python è un
2
devi leggere. Google ha migliaia di progetti TensorFlow e Keras in corso internamente

e quel numero sta crescendo rapidamente . ,


3 4 Pagina 676

1
Keras funge anche da interfaccia più amichevole per CNTK di Microsoft e per l'Université de
Montréal s Theano (che ha cessato lo sviluppo nel 2017). Altro popolare apprendimento profondo
framework includono Caffe ( ttp: //caffe.berkeleyvision.org/ ), Apache MXNet
( ttps: //mxnet.apache.org/ ) e PyTorch ( ttps: //pytorch.org/ ).

2
Chollet, François. Apprendimento profondo con Python . Shelter Island, NY: Manning Publications,
2018.

3
ttp: //theweek.com/speedreads/654463/googlemorethan1000

rtificialintelligenceprojectsworks .
4
ttps: //www.zdnet.com/article/googlesaysexponentialgrowthof

iischangingnatureofcompute / .

Modelli

I modelli di deep learning sono complessi e richiedono un ampio background matematico


comprendere i loro meccanismi interni. Come abbiamo fatto in tutto il libro, eviteremo il pesante
matematica qui, preferendo spiegazioni in inglese.

Keras sta all'apprendimento profondo come Scikitlearn sta all'apprendimento automatico.Ciascuno incapsula il file
matematica sofisticata, quindi gli sviluppatori devono solo definire, parametrizzare e manipolare
oggetti. Con Keras, a costruire il modello partendo dai preesistenti componenti e rapidamente
parametrizzare questi componenti in base alle proprie esigenze. Questo è quello che siamo stati
riferendosi alla programmazione basata su oggetti in tutto il libro.

Sperimenta con i tuoi modelli

L'apprendimento automatico e l'apprendimento profondo sono campi empirici piuttosto che teorici. Tu
sperimentare molti modelli, modificandoli in vari modi fino a trovare i modelli che
prestazioni migliori per le tue applicazioni. Keras facilita tale sperimentazione.

Dimensioni del set di dati

L'apprendimento profondo funziona bene quando si hanno molti dati, ma può essere efficace anche per i più piccoli
5,6
set di dati se combinati con tecniche come l'apprendimento del trasferimento e aumento dei dati
7,8
. Il trasferimento dell'apprendimento utilizza la conoscenza esistente da un modello precedentemente addestrato come
base per un nuovo modello. L'aumento dei dati aggiunge dati a un set di dati derivando nuovi dati
dai dati esistenti. Ad esempio, in un set di dati immagine, potresti ruotare le immagini a sinistra e
in modo che il modello possa apprendere oggetti in diversi orientamenti. In generale, però, il
più dati hai, meglio sarai in grado di addestrare un modello di deep learning.

5
ttps: //towardsdatascience.com/transferlearningfrompretrained
odelsf2393f124751 .

6
ttps: //medium.com/nanonets/nanonetshowtousedeeplearning
henyouhavelimiteddataf68c0b512cab .

7
ttps: //towardsdatascience.com/dataaugmentationandimages

un'
un'
m
hw

aca9bd0dbe8 .
Pagina 677

8
ttps: //medium.com/nanonets/howtousedeeplearningwhenyou
avelimiteddatapart2dataaugmentationc26971dc8ced .

Potere di trasformazione

L'apprendimento profondo può richiedere una potenza di elaborazione significativa. Modelli complessi addestrati su bigdata
L'addestramento dei set di dati può richiedere ore, giorni o anche di più.I modelli che presentiamo in questo capitolo
può essere addestrato in pochi minuti a poco meno di un'ora su computer con CPU convenzionali.
Avrai bisogno solo di un personal computer ragionevolmente aggiornato. Discuteremo dell'effetto speciale
hardware ad alte prestazioni chiamato GPU (Graphics Processing Units) e TPU (Tensor

Processing Units) sviluppate da NVIDIA e Google per far fronte all'elaborazione straordinaria
esigenze delle applicazioni di deeplearning edge ofpractice.

Set di dati in bundle

Keras viene fornito con alcuni set di dati popolari.Lavorerai con due di questi set di dati in formato
gli esempi del capitolo. Puoi trovare molti studi Keras online per ciascuno di questi set di dati,
compresi quelli che adottano approcci diversi.

Nel capitolo "Machine Learning" hai lavorato con il dataset Digits di Scikitlearn, che
conteneva 1797 immagini scritte a mano che furono selezionate dal MNIST molto più grande
9
set di dati (60.000 immagini di addestramento e 10.000 immagini di prova). In questo capitolo lavorerai con
il set di dati MNIST completo. Costruirai una rete neurale convoluzionale di Keras (CNN o convnet)
modello che raggiungerà prestazioni elevate riconoscendo le immagini delle cifre nel set di test.Convnet
sono particolarmente appropriati per attività di visione artificiale, come il riconoscimento di cifre scritte a mano
e personaggi o riconoscere oggetti (inclusi volti) in immagini e video. Lavorerai anche tu
con una rete neurale ricorrente di Keras . In questo esempio, eseguirai l'analisi del sentiment
utilizzando il set di dati delle recensioni dei film di IMDb, in cui le recensioni nei set di addestramento e test
sono etichettati come positivi o negativi.

9
Il database MNIST Database di cifre scritte a mano MNIST, Yann LeCun, Corinna Cortes
e Chris Burges. ttp: //yann.lecun.com/exdb/mnist/ .

Futuro del deep learning

Le nuove funzionalità di deep learning automatizzato semplificano ulteriormente la creazione di deep learning
0
soluzioni. Questi includono AutoKeras da Texas A & M Università dati di laboratorio, Baidu
1 2
EZDL e AutoML di Google.

0
ttps: //autokeras.com/ .

1
ttps: //ai.baidu.com/ezdl/ .

2
ttps: //cloud.google.com/automl/ .

15.1.1 Applicazioni di deep learning


Il deep learning viene utilizzato in un'ampia gamma di applicazioni, come:

P
1h
7

Gioco Pagina 678

Visione artificiale: riconoscimento di oggetti, riconoscimento di pattern, riconoscimento facciale

Auto a guida autonoma

Robotica

Migliorare le esperienze dei clienti

Chatbot

Diagnosi di condizioni mediche

Ricerca Google

Riconoscimento facciale

Sottotitoli automatici di immagini e sottotitoli video

Miglioramento della risoluzione dell'immagine

Riconoscimento vocale

Traduzione in lingua

Previsione dei risultati delle elezioni

Previsione dei terremoti e del tempo

Google Sunroof per determinare se è possibile installare pannelli solari sul tetto

Applicazioni generative: generazione di immagini originali, elaborazione di immagini esistenti per l'aspetto
come lo stile di un artista specificato, aggiungendo colore a immagini e video in bianco e nero, creando
musica, creazione di testi (libri, poesie) e molto altro ancora.

15.1.2 Demo di deep learning


Dai un'occhiata a queste quattro demo di deeplearning e cerca online molto altro, incluso
applicazioni pratiche come abbiamo accennato nella sezione precedente:

DeepArt.io: trasforma una foto in opera d'arte applicando uno stile artistico alla foto.
ttps: //deepart.io/ .

Demo DeepWarp: analizza la foto di una persona e fa muovere gli occhi della persona
direzioni diverse.

ttps: //sites.skoltech.ru/sites/compvision_wiki/static_pages/projects/dee ordito/

Demo ImagetoImage: traduce un disegno al tratto in un'immagine.


ttps: //affinelayer.com/pixsrv/ .

Google Translate Mobile App (scarica da un app store sul tuo smartphone) -

hp

traduci il testo di una foto in un'altra lingua (ad esempio, scatta una foto di un cartello o di un ristorante Pagina 679
menu in spagnolo e traduce il testo in inglese).

15.1.3 Risorse Keras


Ecco alcune risorse che potresti trovare utili mentre studi il deep learning:

Per ottenere risposte alle tue domande, vai al canale slack del team di Keras all'indirizzo

ttps: //kerasteam.slack.com .

Per articoli e tutorial, visita ttps: //blog.keras.io .

La documentazione di Keras si trova su ttp: //keras.io .

Se stai cercando progetti a termine, progetti di studio diretti, progetti di corsi capstone o
argomenti della tesi, visita arXiv (pronunciato "archivio", dove la X rappresenta la lettera greca
"Chi") in ttps: //arXiv.org . Le persone pubblicano qui i loro documenti di ricerca parallelamente a
passando attraverso la revisione tra pari per la pubblicazione formale, sperando in un rapido feedback.Quindi, questo sito
ti dà accesso a ricerche estremamente attuali.

15.2 SET DI DATI INTEGRATI KERAS


3
Ecco alcuni dei set di dati di Keras (dal modulo tensorflow.keras.datasets) per

praticare l'apprendimento profondo. Ne useremo un paio negli esempi del capitolo:

3
Nella libreria Keras standalone, i nomi dei moduli iniziano con keras anziché con

tensorflow.keras.

Database MNIST di cifre scritte a mano: utilizzato per classificare le cifre scritte a mano
immagini, questo set di dati contiene 28 per 28 immagini in scala di grigi etichettate da 0 a 9 con

60.000 immagini per la formazione e 10.000 per i test. Usiamo questo set di dati in ezione 15.6,
dove studiamo le reti neurali convoluzionali.

4
Il database MNIST Database di cifre scritte a mano MNIST, Yann LeCun, Corinna
Cortes e Chris Burges. ttp: //yann.lecun.com/exdb/mnist/ .

Database FashionMNIST di articoli di moda: utilizzato per classificare l'abbigliamento


immagini, questo set di dati contiene 28by28 immagini in scala di grigi di indumenti etichettati in 10
6
categorie con 60.000 per la formazione e 10.000 per i test. Una volta creato un modello per
usa con MNIST, puoi riutilizzare quel modello con FashionMNIST cambiandone alcuni

dichiarazioni.

7
Recensioni di film su IMDb —Utilizzato per l'analisi del sentiment, questo set di dati contiene recensioni
etichettato come sentiment positivo (1) o negativo (0) con 25.000 recensioni per formazione e
25.000 per i test. Usiamo questo set di dati in ection 15.9 , dove studiamo il neurale ricorrente
reti.

5
Han Xiao e Kashif Rasul e Roland Vollgraf, FashionMNIST: a Novel Image
Set di dati per il benchmarking degli algoritmi di machine learning, arXiv, cs.LG / 1708.07747.

T
S
11h

6
ttps: //keras.io/datasets/#fashionmnistdatabaseoffashion
Pagina 680

articoli .

7
Andrew L. Maas, Raymond E. Daly, Peter T. Pham, Dan Huang, Andrew Y. Ng e
Christopher Potts. (2011). Imparare i vettori di parole per l'analisi del sentiment. Il 49 °
Riunione annuale della Association for Computational Linguistics (ACL 2011).

8
Classificazione delle immagini piccole CIFAR10: utilizzata per la classificazione delle immagini piccole , questa
il set di dati contiene immagini a colori 32by32 etichettate in 10 categorie con 50.000 immagini per
formazione e 10.000 per i test.

8
ttps: //www.cs.toronto.edu/~kriz/cifar.html .
9

Classificazione delle immagini piccole CIFAR100 : utilizzata anche per la classificazione delle immagini piccole ,
questo set di dati contiene 32x32 immagini a colori etichettate in 100 categorie con 50.000 immagini
per la formazione e 10.000 per i test.

9
ttps: //www.cs.toronto.edu/~kriz/cifar.html .

15.3 AMBIENTI ANACONDA PERSONALIZZATI


Prima di eseguire gli esempi di questo capitolo, è necessario installare le librerie che utilizziamo.In questo
0
esempi del capitolo, useremo la versione della libreria di deeplearning TensorFlow di Keras. A
al momento della stesura di questo documento, TensorFlow non supporta ancora Python 3.7. Quindi, avrai bisogno di Python
3.6.x per eseguire gli esempi di questo capitolo. Ti mostreremo come configurare un ambiente personalizzato
per lavorare con Keras e TensorFlow.

0
C'è anche una versione standalone che ti consente di scegliere tra TensorFlow,
Microsoft s CNTK o l'Université de Montréal s Theano (che ha cessato lo sviluppo in
2017).

Ambienti in Anaconda

La distribuzione Anaconda Python semplifica la creazione di ambienti personalizzati . Questi sono


configurazioni separate in cui è possibile installare diverse librerie e diverse librerie
versioni. Questo può aiutare con la riproducibilità se il tuo codice dipende da Python o
1
versioni della libreria.

1
Nel prossimo capitolo introdurremo Docker come un altro meccanismo di riproducibilità e come file
modo conveniente per installare ambienti complessi da utilizzare sul computer locale.

L'ambiente predefinito in Anaconda è chiamato ambiente di base . Questo è stato creato per te
quando installi Anaconda. Tutte le librerie Python fornite con Anaconda sono installate
nell'ambiente di base e, a meno che non specifichi diversamente, qualsiasi libreria aggiuntiva
install sono posizionati anche lì. Gli ambienti personalizzati ti danno il controllo sulle librerie specifiche
che desideri installare per le tue attività specifiche.

Creazione di un ambiente Anaconda

Il comando conda create crea un ambiente. Creiamo un TensorFlow

211h
un'

ambiente e chiamalo tf_env (puoi chiamarlo come preferisci). Eseguire quanto segue Pagina 681
2, 3
comando nel tuo terminale, shell o prompt dei comandi di Anaconda:

2
Gli utenti Windows dovrebbero eseguire il prompt dei comandi di Anaconda come amministratore,

3
Se hai un computer con una GPU NVIDIA compatibile con TensorFlow, puoi farlo
sostituire la libreria tensorflow con tensorflowgpu per ottenere prestazioni migliori. Per più
informazioni, vedere ttps: //www.tensorflow.org/install/gpu . Anche alcune GPU AMD
può essere utilizzato con TensorFlow: ttp: //timdettmers.com/2018/11/05/whichgpu

ordeeplearning / .

lecca qui per visualizzare l'immagine del codice

conda create n tf_env tensorflow anaconda ipython jupyterlab scikitlearn matp otlib se

determinerà le dipendenze delle librerie elencate, quindi visualizzerà tutte le librerie che saranno
installato nel nuovo ambiente. Esistono molte dipendenze, quindi potrebbero essere necessarie alcune
minuti. Quando vedi il prompt:

Procedere ([y] / n)?

4
premere Invio per creare l'ambiente e installare le librerie.

4
Quando abbiamo creato il nostro ambiente personalizzato, conda ha installato Python 3.6.7, che era il file
la versione più recente di Python compatibile con la libreria tensorflow.

Attivazione di un ambiente Anaconda alternativo


Per utilizzare un ambiente personalizzato, eseguire il comando conda attivare :

conda attivare tf_env

Ciò riguarda solo il terminale, la shell o il prompt dei comandi di Anaconda correnti. Quando un'usanza
viene attivato l'ambiente e si installano più librerie, queste diventano parte dell'attivato
ambiente, non l'ambiente di base. Se apri Terminal, shell o Anaconda separati
Prompt dei comandi, useranno l'ambiente di base di Anaconda per impostazione predefinita.

Disattivazione di un ambiente Anaconda alternativo

Quando hai finito con un ambiente personalizzato, puoi tornare all'ambiente di base in
Terminale corrente, shell o prompt dei comandi di Anaconda eseguendo:

conda disattivare

Notebook Jupyter e JupyterLab

Gli esempi di questo capitolo sono forniti solo come Jupyter Notebook, il che renderà più facile per
di sperimentare con gli esempi. Puoi modificare le opzioni che presentiamo e rieseguire

T
2C
hf
lui quaderni. Per questo capitolo, dovresti avviare JupyterLab dagli esempi del capitolo 15 Pagina 682
cartella (come discusso in sezione 1.5.3 ).

15.4 RETI NEURALI


L'apprendimento profondo è una forma di apprendimento automatico che utilizza reti neurali artificiali per apprendere. Un
rete neurale artificiale (o semplicemente rete neurale) è un costrutto software che funziona
in modo simile a come gli scienziati credono che il nostro cervello funzioni. I nostri sistemi nervosi biologici lo sono
5
controllato tramite neuroni che comunicano tra loro lungo percorsi chiamati
6
sinapsi . Man mano che apprendiamo, i neuroni specifici che ci consentono di eseguire un determinato compito, come
camminare, comunicare tra loro in modo più efficiente. Questi neuroni si attivano ogni volta che noi
7
bisogno di camminare.

5
ttps: //en.wikipedia.org/wiki/Neuron .

6
ttps: //en.wikipedia.org/wiki/Synapse .

7
ttps: //www.sciencenewsforstudents.org/article/learningrewires

pioggia .

Neuroni artificiali

In una rete neurale, i neuroni artificiali interconnessi simulano il cervello umano

neuroni per aiutare la rete ad apprendere. Le connessioni tra neuroni specifici sono rafforzate
durante il processo di apprendimento con l'obiettivo di raggiungere un risultato specifico.In profondità sorvegliata
apprendimento - che useremo in questo capitolo - miriamo a prevedere le etichette target fornite
campioni di dati. Per fare ciò, addestreremo un modello di rete neurale generale che possiamo quindi utilizzare
8
fare previsioni su dati invisibili.

8
Come nel machine learning, puoi creare reti di deep learning senza supervisione , queste sono

oltre lo scopo di questo capitolo.

Diagramma di rete neurale artificiale

Il diagramma seguente mostra tre strati di rete neurale. Ogni cerchio rappresenta un neurone,
e le linee tra di loro simulano le sinapsi. L'output di un neurone diventa l'input
di un altro neurone, da cui il termine rete neurale.Questo particolare diagramma mostra un completo
rete connessa: ogni neurone in un dato livello è connesso a tutti i neuroni in
livello successivo:
thbS
2

Pagina 683

L'apprendimento è un processo iterativo

Quando eri un bambino, non hai imparato a camminare istantaneamente. Hai imparato quel processo

nel tempo con la ripetizione. Hai costruito le componenti più piccole dei movimenti che
ti ha permesso di camminare - imparare a stare in piedi, imparare a stare in equilibrio per rimanere in piedi, imparare a farlo
solleva il piede e spostalo in avanti, ecc. E hai ricevuto feedback dal tuo ambiente. quando
hai camminato con successo i tuoi genitori sorridevano e applaudivano.Quando sei caduto, potresti averlo fatto
ha sbattuto la testa e ha sentito dolore.

Allo stesso modo, addestriamo le reti neurali in modo iterativo nel tempo. Ogni iterazione è nota come

epoca ed elabora ogni campione nel set di dati di addestramento una volta.Non esiste un numero "corretto"
di epoche. Si tratta di un iperparametro che potrebbe richiedere l'ottimizzazione, in base ai dati di allenamento e
il tuo modello. Gli input alla rete sono le caratteristiche negli esempi di formazione. Alcuni strati
apprendere nuove funzionalità dagli output dei livelli precedenti e altri interpretano quelle funzionalità per creare
predizioni.

Come i neuroni artificiali decidono se attivare le sinapsi

Durante la fase di addestramento, la rete calcola valori chiamati pesi per ogni connessione
tra i neuroni in uno strato e quelli in quello successivo. Su base neurone per neurone, ciascuno di

i suoi input vengono moltiplicati per il peso di quella connessione, quindi la somma di quegli input ponderati è
passato alla funzione di attivazione del neurone . L'output di questa funzione determina quale
neuroni da attivare in base agli input, proprio come i neuroni nel cervello che passano
informazioni in giro in risposta agli input provenienti da occhi, naso, orecchie e altro ancora.Il
Il diagramma seguente mostra un neurone che riceve tre input (i punti neri) e produce un file
output (il cerchio vuoto) che sarebbe passato a tutti o ad alcuni dei neuroni nel livello successivo,
a seconda dei tipi di strati della rete neurale:

Pagina 684
I valori w, w e w 1sono2 pesi. In un3 nuovo modello che ti alleni da zero, questi
i valori vengono inizializzati in modo casuale dal modello. Mentre la rete si allena, cerca di ridurre al minimo i file

tasso di errore tra le etichette previste dalla rete e le etichette effettive dei campioni.L'errore
il tasso è noto come la perdita e il calcolo che determina la perdita è chiamato la perdita
funzione . Durante l'allenamento, la rete determina la quantità che ogni neurone
contribuisce alla perdita complessiva, quindi torna indietro attraverso gli strati e regola i pesi
uno sforzo per ridurre al minimo tale perdita. Questa tecnica è chiamata backpropagation . Ottimizzazione di questi
i pesi si verificano gradualmente, in genere tramite un processo chiamato discesa del gradiente .

15.5 TENSORI
I framework di deep learning generalmente manipolano i dati sotto forma di tensori . Un "tensore" è
fondamentalmente un array multidimensionale. Framework come TensorFlow raggruppano tutti i tuoi dati in uno solo
o più tensori, che usano per eseguire i calcoli matematici che abilitano il neurale
reti per imparare. Questi tensori possono diventare abbastanza grandi quanto il numero di dimensioni
aumenta e all'aumentare della ricchezza dei dati (ad esempio, immagini, audio e video
sono più ricchi del testo). Chollet discute i tipi di tensori tipicamente incontrati in profondità
9
apprendimento:

9
Chollet, François. Apprendimento profondo con Python . ezione 2.2 . Shelter Island, NY: Manning
Pubblicazioni, 2018.

Tensore 0D (0dimensionale): questo è un valore noto come scalare .

Tensore 1D: è simile a un array monodimensionale ed è noto come vettore . A 1D


tensore potrebbe rappresentare una sequenza, come letture di temperatura orarie da un sensore o
le parole di una recensione di un film.

Tensore 2D: è simile a un array bidimensionale ed è noto come matrice . Un 2D


tensore potrebbe rappresentare un'immagine in scala di grigi in cui le due dimensioni del tensore sono le
la larghezza e l'altezza dell'immagine in pixel e il valore in ogni elemento è l'intensità di ciò
pixel.

Tensore 3D: è simile a un array tridimensionale e potrebbe essere utilizzato per rappresentare a

2S

immagine olor. Le prime due dimensioni rappresenterebbero la larghezza e l'altezza dell'immagine Pagina 685
in pixel e la profondità in ciascuna posizione potrebbe rappresentare il rosso, il verde e il blu (RGB)
componenti del colore di un dato pixel.Un tensore 3D potrebbe anche rappresentare una raccolta di 2D
tensori contenenti immagini in scala di grigi.

Tensore 4D: un tensore 4D potrebbe essere utilizzato per rappresentare una raccolta di immagini a colori in 3D
tensori. Potrebbe anche essere usato per rappresentare un video. Ogni fotogramma di un video è essenzialmente un file
immagine a colori.

Tensore 5D: potrebbe essere utilizzato per rappresentare una raccolta di tensori 4D contenenti video.

La forma di un tensore è tipicamente rappresentata come una tupla di valori in cui il numero di elementi
specifica il numero di dimensioni del tensore e ogni valore nella tupla specifica la dimensione di
la dimensione corrispondente del tensore.

Supponiamo di creare una rete di apprendimento approfondito per identificare e tracciare oggetti in 4K (high
risoluzione) video con 30 frame per secondo. Ogni fotogramma in un video 4K è 3840by
2160 pixel. Supponiamo inoltre che i pixel siano presentati come componenti rosso, verde e blu di
un colore. Quindi ogni fotogramma sarebbe un tensore 3D contenente un totale di 24.883.200 elementi (3840
* 2160 * 3) e ogni video sarebbe un tensore 4D contenente la sequenza di fotogrammi. Se la
i video durano un minuto, avresti 44.789.760.000 elementi per tensore !

0
Ogni minuto vengono caricate su YouTube oltre 600 ore di video , quindi in un solo minuto
caricamenti, Google potrebbe avere un tensore contenente 1.612.431.360.000.000 di elementi da utilizzare
formazione di modelli di deeplearning: questi sono i big data . Come puoi vedere, i tensori possono diventare rapidamente
enorme , quindi manipolarli in modo efficiente è fondamentale. Questo è uno dei motivi principali per cui
la maggior parte dell'apprendimento profondo viene eseguito su GPU. Più recentemente Google ha creato TPU (Tensor
Processing Units) che sono specificamente progettate per eseguire manipolazioni tensoriali, eseguendo
più veloce delle GPU.
0
ttps: //www.inc.com/tompopomaronis/youtubeanalyzedtrillionsof
datapointsin2018revealing5eyeopeningbehavioral

tatistics.html .

Processori ad alte prestazioni

Sono necessari processori potenti per l'apprendimento profondo del mondo reale perché le dimensioni dei tensori possono farlo
essere enormi e le operazioni con sensori di grandi dimensioni possono imporre requisiti schiaccianti ai trasformatori.Il
i processori più comunemente usati per il deep learning sono:

GPU NVIDIA (unità di elaborazione grafica): sviluppate originariamente da aziende come


NVIDIA per i giochi per computer, le GPU sono molto più veloci delle CPU convenzionali
elaborare grandi quantità di dati, consentendo così agli sviluppatori di addestrare, convalidare e testare
modelli di deeplearning in modo più efficiente e quindi sperimentarne di più. GPU
sono ottimizzati per le operazioni di matrice matematica tipicamente eseguite sui tensori, un
aspetto essenziale del funzionamento del deep learning "sotto il cofano". Volta Tensor di NVIDIA
1, 2
I core sono progettati specificamente per il deep learning. Molte GPU NVIDIA sono compatibili
con TensorFlow, e quindi Keras, e può migliorare le prestazioni del tuo deep
3
modelli di apprendimento.
1

hc
3S

1
ttps: //www.nvidia.com/enus/datacenter/tensorcore/ .
Pagina 686

2
ttps: //devblogs.nvidia.com/tensorcoreaiperformance

ilestones / .

3
ttps: //www.tensorflow.org/install/gpu .

Google TPU (Tensor Processing Units): riconoscere che il deep learning è fondamentale per il proprio
futuro, Google ha sviluppato TPU (Tensor Processing Unit), che ora utilizzano nei loro file
Servizio Cloud TPU, che “può fornire fino a 11,5 petaflop di prestazioni in un unico
4
pod " ( ovvero 11,5 quadrilioni di operazioni in virgola mobile al secondo). Inoltre, le TPU lo sono

progettato per essere particolarmente efficiente dal punto di vista energetico. Questa è una preoccupazione fondamentale per aziende come Google
con cluster di elaborazione già enormi che stanno crescendo in modo esponenziale e consumano
grandi quantità di energia.

4
ttps: //cloud.google.com/tpu/ .

15.6 RETI NEURALI CONVOLUZIONALI PER LA VISIONE;


MULTI-CLASSIFICAZIONE CON IL DATASET MNIST
Nel capitolo "Machine Learning", abbiamo classificato le cifre scritte a mano utilizzando 8 x 8 pixel,

immagini a bassa risoluzione dal set di dati Digits in bundle con Scikitlearn.Quel set di dati è
basato su un sottoinsieme del dataset di cifre scritte a mano MNIST a risoluzione più alta. Qui, useremo
5
MNIST per esplorare il deep learning con una rete neurale convoluzionale (chiamato anche a
convnet o CNN ). Le convnet sono comuni nelle applicazioni di computervision, come
riconoscere cifre e caratteri scritti a mano e riconoscere oggetti in immagini e video.
Sono anche usati in applicazioni non visive, come l'elaborazione del linguaggio naturale e
sistemi di raccomandazione.

5
ttps: //en.wikipedia.org/wiki/Convolutional_neural_network .

Il set di dati Digits ha solo 1797 campioni, mentre MNIST ha 70.000 immagini di cifre etichettate
campioni: 60.000 per la formazione e 10.000 per i test. Ogni campione è un 28 per 28 in scala di grigi
immagine pixel (784 caratteristiche totali) rappresentata come un array NumPy. Ogni pixel è un valore compreso tra 0 e
255 che rappresenta l'intensità (o l'ombreggiatura) di quel pixel: il set di dati Digits utilizza meno granulare
ombreggiatura con valori da 0 a 16. Le etichette di MNIST sono valori interi nell'intervallo da 0 a 9,
indicando la cifra rappresentata da ciascuna immagine.

Il modello di machine learning utilizzato nel capitolo precedente ha prodotto come output una cifra
classe prevista dell'immagine: un numero intero compreso tra 0 e 9. Il modello convnet che costruiremo lo farà
6
eseguire la classificazione probabilistica . Per ogni immagine della cifra, il modello produrrà un file
matrice di 10 probabilità, ciascuna delle quali indica la probabilità che la cifra appartenga a un particolare
una delle classi da 0 a 9. La classe con la probabilità più alta è il valore previsto.

6
ttps: //en.wikipedia.org/wiki/Probabilistic_classification .
Riproducibilità in Keras e Deep Learning
Abbiamo discusso l'importanza della riproducibilità in tutto il libro. Nell'apprendimento profondo,
la riproducibilità è più difficile perché le librerie parallelizzano pesantemente le operazioni che

3h
m

eseguire calcoli in virgola mobile. Ogni volta che le operazioni vengono eseguite, possono essere eseguite in un file Pagina 687
ordine diverso. Questo può produrre differenze nei risultati. Ottenere risultati riproducibili in formato
Keras richiede una combinazione di impostazioni dell'ambiente e impostazioni del codice descritte in
le FAQ di Keras:

lecca qui per visualizzare l'immagine del codice

ttps: //keras.io/gettingstarted/faq/#howcaniobtainreproducibleresultsusi gkeras

asic Keras Neural Network

Una rete neurale Keras è costituita dai seguenti componenti:

Una rete (chiamata anche modello ): una sequenza di strati contenente i neuroni utilizzati per
impara dai campioni. I neuroni di ogni strato ricevono input, li elaborano (tramite un file
funzione di attivazione ) e produrre uscite. I dati vengono immessi nella rete tramite un ingresso
layer che specifica le dimensioni dei dati di esempio. Questo è seguito da nascosto
strati di neuroni che implementano l'apprendimento e uno strato di output che produce il
predizioni. Più strati impili , più profonda è la rete, da cui il termine profondo
apprendimento.

Una funzione di perdita: produce una misura di quanto bene la rete prevede l'obiettivo
valori. Valori di perdita inferiori indicano previsioni migliori.

Un ottimizzatore: tenta di ridurre al minimo i valori prodotti dalla funzione di perdita a


sintonizza la rete per fare previsioni migliori.

Avvia JupyterLab

Questa sezione presuppone che tu abbia attivato l'ambiente tf_env Anaconda in cui hai creato

ezione 15.3 e ha lanciato JupyterLab dalla cartella degli esempi ch15. Puoi aprire
il file MNIST_CNN.ipynb in JupyterLab ed eseguire il codice nelle celle che abbiamo fornito, oppure
puoi creare un nuovo taccuino e inserire il codice da solo. Se preferisci, puoi lavorare presso
la riga di comando in IPython, tuttavia, inserendo il codice in un notebook Jupyter lo fa
molto più facile per voi per rieseguire esempi di questo capitolo.

Come promemoria, puoi reimpostare un notebook Jupyter e rimuovere i suoi output selezionando
Riavvia il kernel e cancella tutti gli output dal menu Kernel di JupyterLab.Questo finisce
l'esecuzione del notebook e rimuove i suoi output. Potresti farlo se il tuo modello non lo è
performante e vuoi provare diversi iperparametri o eventualmente ristrutturare il tuo
7
rete neurale. È quindi possibile rieseguire il notebook una cella alla volta o eseguire il file
l'intero notebook selezionando Esegui tutto dal menu Esegui di JupyterLab.

7
Abbiamo scoperto che a volte dovevamo eseguire questa opzione di menu due volte per cancellare gli output.

15.6.1 Caricamento del set di dati MNIST


Importiamo il modulo tensorflow.keras.datasets.mnist in modo da poter caricare il file
set di dati:

B
3S
hC

lecca qui per visualizzare l'immagine del codice Pagina 688

[1]: da tensorflow.keras.datasets import mnist

Nota che poiché stiamo utilizzando la versione di Keras incorporata in TensorFlow, il modulo Keras
i nomi iniziano con "tensorflow.". Nella versione standalone di Keras, i nomi dei moduli
iniziare con "keras.", quindi sopra verrà utilizzato keras.datasets. Keras utilizza TensorFlow per

eseguire i modelli di deeplearning.

La funzione load_data del modulo mnist carica i set di addestramento e test MNIST:
lecca qui per visualizzare l'immagine del codice

[2]: (X_train, y_train), (X_test, y_test) = mnist.load_data ()

Quando chiami load_data, scaricherà i dati MNIST sul tuo sistema. La funzione
restituisce una tupla di due elementi contenenti i set di addestramento e test. Ogni elemento è se stesso
una tupla contenente rispettivamente i campioni e le etichette.

15.6.2 Esplorazione dei dati


Conosciamo i dati prima di lavorarci. Innanzitutto, controlliamo le dimensioni del file
immagini del set di allenamento (X_train), etichette del set di allenamento (y_train), immagini del set di test (X_test)

e testare le etichette del set (y_test):

[3]: X_train.shape
[3]: (60000, 28, 28)

[4]: y_train.shape
[4]: (60000,)

[5]: X_test.shape
[5]: (10000, 28, 28)

[6]: y_test.shape
[6]: (10000,)

Puoi vedere dalle forme di X_train e X_test che le immagini hanno una risoluzione maggiore di
quelli nel dataset Digits di Scikitlearn (che sono 8by8).

Visualizzazione di cifre

Visualizziamo alcune delle immagini delle cifre. Innanzitutto, abilita Matplotlib nel notebook, importa
Matplotlib e Seaborn e impostare la scala del carattere:

lecca qui per visualizzare l'immagine del codice

[7]:% matplotlib inline


[8]: importa matplotlib.pyplot come plt

[9]: importa seaborn come sns

C
[10]: sns.set (font_scale = 2 ) Pagina 689

La magia di IPython

% matplotlib inline

indica che la grafica con Matplotlibbas dovrebbe essere visualizzata nel notebook anziché in formato
finestre separate. Per ulteriori magie IPython, puoi usare in Jupyter Notebooks, vedi:

ttps: //ipython.readthedocs.io/en/stable/interactive/magics.html

Successivamente, visualizzeremo un set selezionato a caso di 24 immagini del set di addestramento MNIST.Richiama dal
Capitolo "ArrayOriented Programming with NumPy" che puoi passare una sequenza di indici
come pedice di un array NumPy per selezionare solo gli elementi dell'array in quegli indici. Lo useremo
possibilità qui di selezionare gli elementi agli stessi indici sia in X_train che in y_train

array. Ciò garantisce la visualizzazione dell'etichetta corretta per ciascuna immagine selezionata casualmente.

La funzione di scelta di NumPy (dal modulo numpy.random) seleziona casualmente il file


numero di elementi specificato nel secondo argomento (24) dall'array di valori nel primo

argomento (in questo caso, un array contenente la gamma di indici di X_train).La funzione ritorna
un array contenente i valori selezionati, che memorizziamo in index. Le espressioni

X_train [index] e y_train [index] usano index per ottenere gli elementi corrispondenti
da entrambi gli array. Il resto di questa cella è il codice di visualizzazione del capitolo precedente

Case study di cifre:

lecca qui per visualizzare l'immagine del codice


[11]: importa numpy come np
index = np.random.choice (np.arange (len (X_train)), 24 , sostituire = False )
figura, assi = plt.subplots (nrows = 4 , ncols = 6 , figsize = ( 16 , 9 ))

per l' elemento in zip (axes.ravel (), X_train [index], y_train [index]):
assi, immagine, destinazione = elemento
axes.imshow (image, cmap = plt.cm.gray_r )
axes.set_xticks ([]) # rimuove i segni di graduazione dell'asse x
axes.set_yticks ([]) # rimuove i segni di graduazione yaxis
axes.set_title (target)
plt.tight_layout ()

Puoi vedere nell'output qui sotto che le immagini delle cifre di MNIST hanno una risoluzione maggiore di quelle
nel set di dati Digits di Scikitlearn.

hC

Pagina 690

Guardando le cifre, puoi capire perché il riconoscimento delle cifre scritte a mano è una sfida:

Alcune persone scrivono 4 "aperti" (come quelli nella prima e nella terza riga), mentre altri scrivono

4 "chiusi" (come quello della seconda riga). Sebbene ogni 4 abbia alcune caratteristiche simili,
sono tutti diversi l'uno dall'altro.

Il 3 nella seconda riga sembra strano, più simile a un 6 e un 7. Confronta questo con il
molto più chiaro 3 nella quarta riga.

Il 5 della seconda fila potrebbe essere facilmente confuso con un 6.

Inoltre, le persone scrivono le loro cifre da diverse angolazioni, come puoi vedere con i quattro 6 in
terza e quarta fila: due sono in posizione verticale, una si inclina a sinistra e una a destra.

Se esegui più volte lo snippet precedente, puoi vederne altri selezionati casualmente
8
cifre . Probabilmente scoprirai che, se non fosse per le etichette visualizzate sopra ogni cifra, lo sarebbe
difficile per te identificare alcune delle cifre. Vedremo presto con quanta precisione il nostro primo convnet

predice le cifre nel set di test MNIST.

8
Se esegui la cella più volte, il numero dello snippet accanto alla cella aumenterà
ogni volta, come fa in IPython dalla riga di comando.

15.6.3 Preparazione dei dati


Ricorda dal capitolo "Machine Learning" che erano i set di dati in bundle di Scikitlearn
preelaborato nelle forme richieste dai suoi modelli. Negli studi sul mondo reale, generalmente avrai
per eseguire parte o tutta la preparazione dei dati. Il set di dati MNIST richiede una certa preparazione
utilizzare in un convnet Keras.

Rimodellare i dati dell'immagine


I convnet di Keras richiedono input array NumPy in cui ogni campione ha la forma:

( larghezza , altezza , canali )

Per MNIST, la larghezza e l' altezza di ciascuna immagine sono 28 pixel e ogni pixel ha un canale (il file Pagina 691
tonalità di grigio del pixel da 0 a 255), quindi la forma di ogni campione sarà:

(28, 28, 1)

Le immagini a colori con valori RGB (rosso / verde / blu) per ogni pixel, ne avrebbero tre
canali: un canale ciascuno per i componenti rosso, verde e blu di un colore.

Man mano che la rete neurale apprende dalle immagini, crea molti più canali.Piuttosto che
ombra o colore, i canali appresi rappresenteranno caratteristiche più complesse, come bordi, curve
e linee, che alla fine consentiranno alla rete di riconoscere le cifre in base a queste
funzionalità aggiuntive e come sono combinate.

Rimodelliamo le 60.000 immagini di training e 10.000 set di test nelle dimensioni corrette

per l'uso nel nostro convnet e confermare le loro nuove forme.Ricorda quel metodo array NumPy
reshape riceve una tupla che rappresenta la nuova forma dell'array:

lecca qui per visualizzare l'immagine del codice

[12]: X_train = X_train.reshape (( 60000 , 28 , 28 , 1 ))

[13]: X_train.shape
[13]: (60000, 28, 28, 1)

[14]: X_test = X_test.reshape (( 10000 , 28 , 28 , 1 ))

[15]: X_test.shape
[15]: (10000, 28, 28, 1)

Normalizzare i dati dell'immagine

Le caratteristiche numeriche negli esempi di dati possono avere intervalli di valori che variano notevolmente.Apprendimento approfondito
le reti hanno prestazioni migliori sui dati scalati nell'intervallo da 0,0 a 1,0 o in un intervallo
9
per cui la media dei dati è 0,0 e la sua deviazione standard è 1,0. Ottenere i tuoi dati in uno
di queste forme è noto come normalizzazione .

9
S. Ioffe e Szegedy, C .. Normalizzazione dei lotti: accelerazione della formazione in rete profonda di

Riduzione dello spostamento covariate interno. ttps: //arxiv.org/abs/1502.03167 .

In MNIST, ogni pixel è un numero intero compreso tra 0 e 255. Le seguenti istruzioni convertono il file

valori a numeri in virgola mobile a 32 bit (4 byte) utilizzando il metodo array NumPy astype,
quindi dividere ogni elemento nell'array risultante per 255, producendo valori normalizzati nel file
intervallo 0,0–1,0:

lecca qui per visualizzare l'immagine del codice

[16]: X_train = X_train.astype ( 'float32' ) / 255

[17]: X_test = X_test.astype ( 'float32' ) / 255

One-Hot Encoding: Conversione delle etichette da numeri interi a dati categoriali

C
3h

Come accennato, la previsione di convnet per ogni cifra sarà un array di 10 probabilità, Pagina 692
indicando la probabilità che la cifra appartenga a una particolare delle classi da 0 a 9.
Quando valutiamo l'accuratezza del modello, Keras confronta le previsioni del modello con il file

etichette. Per fare ciò, Keras richiede che entrambi abbiano la stessa forma.L'etichetta MNIST per ciascuno
digit, tuttavia, è un valore intero compreso tra 0 e 9. Quindi, dobbiamo trasformare le etichette in
dati categoriali , ovvero matrici di categorie che corrispondono al formato delle previsioni.Per
0
fare questo, useremo un processo chiamato codifica onehot , che converte i dati in array di file
1.0 se 0.0 in cui solo un elemento è 1.0 e il resto è 0.0 s.Per MNIST, il onehot
i valori codificati saranno array di 10 elementi che rappresentano le categorie da 0 a 9. Onehot
la codifica può essere applicata anche ad altri tipi di dati.
0
il suo termine deriva da certi circuiti digitali in cui un gruppo di bit può avere solo
un bit acceso (cioè per avere il valore 1). ttps: //en.wikipedia.org/wiki/One

ot .

Sappiamo esattamente a quale categoria appartiene ogni cifra, quindi la rappresentazione categoriale di a
l'etichetta della cifra sarà composta da un 1.0 all'indice di quella cifra e da 0.0s per tutti gli altri elementi (di nuovo,
Keras utilizza internamente numeri in virgola mobile). Quindi, la rappresentazione categorica di un 7 è:

lecca qui per visualizzare l'immagine del codice

[0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 1,0, 0,0, 0,0]

e la rappresentazione di un 3 è:

lecca qui per visualizzare l'immagine del codice

[0,0, 0,0, 0,0, 1,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0]

Il modulo tensorflow.keras.utils fornisce la funzione to_categorical da eseguire

codifica onehot. La funzione conta quindi le categorie univoche, per ogni articolo
codificato, crea un array di quella lunghezza con un 1.0 nella posizione corretta. Trasformiamo
y_train e y_test da array monodimensionali contenenti i valori 0–9 in due
matrici dimensionali di dati categoriali. Dopo averlo fatto, le righe di questi array appariranno
quelli mostrati sopra. Snippet [21] restituisce i dati categoriali di un campione per la cifra 5 (richiamo
che NumPy mostra il punto decimale, ma non gli 0 finali sui valori a virgola mobile):

lecca qui per visualizzare l'immagine del codice

18]: da tensorflow.keras.utils import to_categorical

[19]: y_train = to_categorical (y_train)

[20]: y_train.shape
[20]: (60000, 10)

[21]: y_train [ 0 ]
[21]: array ([0., 0., 0., 0., 0., 1., 0., 0., 0., 0.], dtype = float32)

[22]: y_test = to_categorical (y_test)

C
T
4h

[23]: y_test.shape Pagina 693


[23]: (10000, 10)

5.6.4 Creazione della rete neurale


Ora che abbiamo preparato i dati, configureremo una rete neurale convoluzionale. Noi iniziamo
con il modello Keras Sequential dal modulo tensorflow.keras.models :

lecca qui per visualizzare l'immagine del codice

[24]: da tensorflow.keras.models import Sequential

[25]: cnn = sequenziale ()

La rete risultante eseguirà i suoi livelli in sequenza: l'output di un livello diventa


l'ingresso al successivo. Questa è nota come rete feedforward . Come vedrai quando noi
discutere le reti neurali ricorrenti , non tutte le reti neurali funzionano in questo modo.

Aggiunta di livelli alla rete

Una tipica rete neurale convoluzionale è costituita da diversi livelli, un livello di input che riceve
i campioni di formazione, livelli nascosti che apprendono dai campioni e un livello di output che
produce le probabilità di previsione. Creeremo qui un convnet di base. Importiamo da

modulo tensorflow.keras.layers le classi layer che useremo in questo esempio:

lecca qui per visualizzare l'immagine del codice

[26]: da tensorflow.keras.layers importa Conv2D, Dense, Flatten,


MaxPooling2D

Discutiamo ciascuno di seguito.

Convoluzione

Inizieremo la nostra rete con uno strato di convoluzione , che utilizza le relazioni tra
pixel vicini l'uno all'altro per apprendere funzioni (o pattern) utili in piccole aree di
ogni campione. Queste funzionalità diventano input per i livelli successivi.

Le piccole aree da cui apprende la convoluzione sono chiamate kernel o patch . Esaminiamo
convoluzione su un'immagine 6by6. Considera il diagramma seguente in cui 3by3 è ombreggiato
quadrato rappresenta il kernel: i numeri sono semplicemente numeri di posizione che mostrano l'ordine in
quali sono i kernel visitati ed elaborati:

1C
Pagina 694

Le piccole aree da cui apprende la convoluzione sono chiamate kernel o patch . Esaminiamo
convoluzione su un'immagine 6by6. Considera il diagramma seguente in cui 3by3 è ombreggiato
quadrato rappresenta il kernel: i numeri sono semplicemente numeri di posizione che mostrano l'ordine in
quali sono i kernel visitati ed elaborati:

Puoi pensare al kernel come a una "finestra scorrevole" in cui il livello di convoluzione sposta di un pixel
alla volta a sinistra verso destra sull'immagine. Quando il kernel raggiunge il bordo destro, il file
Il livello di convoluzione sposta il kernel di un pixel verso il basso e ripete questo processo da sinistra a destra.
1
I kernel di solito sono 3by3 , anche se abbiamo trovato convnets che utilizzate 5by5 7by7 e per
immagini ad alta risoluzione. Kernelsize è un iperparametro sintonizzabile.

1
ttps: //www.quora.com/HowcanIdecidethekernelsizeoutputmaps
ndlayersofCNN .

Inizialmente, il kernel si trova nell'angolo in alto a sinistra dell'immagine originale - posizione kernel 1 (il file
quadrato ombreggiato) nel livello di input sopra. Il livello di convoluzione esegue operazioni matematiche
calcoli che utilizzano queste nove funzioni per "apprenderle", quindi invia una nuova funzione a
posizione 1 nell'output del livello. Osservando le caratteristiche vicine l'una all'altra, la rete inizia a
riconoscere caratteristiche come bordi, linee rette e curve.

Successivamente, il livello di convoluzione sposta il kernel di un pixel a destra (noto come passo ) verso
posizione 2 nel livello di input. Questa nuova posizione si sovrappone a due delle tre colonne in
posizione precedente, in modo che il livello di convoluzione possa imparare da tutte le caratteristiche che ne toccano una
un altro. Il livello apprende dalle nove funzionalità nella posizione 2 del kernel e ne genera una nuova
caratteristica nella posizione 2 dell'uscita, come in:
4h
un'
Pagina 695

Per un'immagine 6by6 e un kernel 3by3, il livello di convoluzione lo fa altre due volte a
produrre caratteristiche per le posizioni 3 e 4 dell'output del livello. Quindi, lo strato di convoluzione
sposta il kernel di un pixel verso il basso e ricomincia il processo da sinistra a destra per i successivi quattro
posizioni del kernel, producendo uscite nelle posizioni 5–8, poi 9–12 e infine 13–16. Il
il passaggio completo dell'immagine da sinistra a destra e dall'alto in basso è chiamato filtro . Per un 3by3

kernel, le dimensioni del filtro (4by4 nel nostro esempio sopra) saranno due in meno rispetto all'input
dimensioni (6by6). Per ogni immagine MNIST 28by28, il filtro sarà 26by26.

Il numero di filtri nello strato convoluzionale è comunemente 32 o 64 quando si elaborano piccoli


immagini come quelle in MNIST e ogni filtro produce risultati diversi. Il numero di filtri
dipende dalle dimensioni dell'immagine: le immagini ad alta risoluzione hanno più funzioni, quindi
richiedono più filtri. Se studi il codice che il team di Keras ha usato per produrre i loro preaddestrati
2
convnet, scoprirai che hanno utilizzato 64, 128 o anche 256 filtri nel loro primo convoluzionale
strati. Sulla base delle loro convnet e del fatto che le immagini MNIST sono piccole, ne useremo 64
filtri nel nostro primo strato convoluzionale. L'insieme di filtri prodotto da uno strato di convoluzione è
chiamata mappa delle caratteristiche .

2
ttps: //github.com/kerasteam/keras

pplications / tree / master / keras_applications .

I successivi livelli di convoluzione combinano le caratteristiche delle mappe delle caratteristiche precedenti per il riconoscimento
funzionalità più grandi e così via. Se stessimo facendo il riconoscimento facciale, i primi strati potrebbero riconoscerlo
linee, bordi e curve e gli strati successivi potrebbero iniziare a combinarli in uno più grande
caratteristiche come occhi, sopracciglia, nasi, orecchie e bocche. Una volta che la rete apprende una funzione,
a causa della convoluzione, può riconoscere quella caratteristica ovunque nell'immagine. Questo è uno dei
motivi per cui i convnet vengono utilizzati per il riconoscimento degli oggetti nelle immagini.

Aggiunta di uno strato di convoluzione

Aggiungiamo un livello di convoluzione Conv2D al nostro modello:

lecca qui per visualizzare l'immagine del codice

[27]: cnn.add (Conv2D (filters = 64 , kernel_size = ( 3 , 3 ), activation = 'relu' ,


input_shape = ( 28 , 28 , 1 )))

4C
h
un'
Il layer Conv2D è configurato con i seguenti argomenti: Pagina 696

filtri = 64 : il numero di filtri nella mappa delle caratteristiche risultante.

kernel_size = ( 3 , 3 ): la dimensione del kernel utilizzato in ogni filtro.

activation = 'relu' : la funzione di attivazione 'relu' (unità lineare rettificata) è


utilizzato per produrre l'output di questo livello. 'relu' è la funzione di attivazione più utilizzata in
3
reti di apprendimento profondo odierne ed è buono per le prestazioni perché è facile
4 5
calcolare . È comunemente consigliato per strati convoluzionali.
3
Chollet, François. Apprendimento profondo con Python . p. 72. Shelter Island, NY: Manning
Pubblicazioni, 2018.

4
ttps: //towardsdatascience.com/exploringactivationfunctionsfor

euralnetworks73498da59b02 .

5
ttps: //www.quora.com/HowshouldIchooseaproperactivation
unctionfortheneuralnetwork .

Poiché questo è il primo livello nel modello, passiamo anche input_shape = (28, 28,1)
argomento per specificare la forma di ogni campione. Questo crea automaticamente un livello di input per
caricare i campioni e passarli nel layer Conv2D, che in realtà è il primo nascosto
strato. In Keras, ogni livello successivo deduce la sua input_shape da quella del livello precedente
forma di output, rendendo facile impilare i livelli.

Dimensionalità dell'output del primo livello di convoluzione

Nello strato convoluzionale precedente, i campioni di input sono 28by28by1, ovvero 784
caratteristiche ciascuno. Abbiamo specificato 64 filtri e una dimensione del kernel 3by3 per il livello, quindi l'output per
ogni immagine è 26 per 26 per 64 per un totale di 43.264 elementi nella mappa delle caratteristiche: un valore significativo
aumento della dimensionalità e numero enorme rispetto al numero di caratteristiche
abbiamo elaborato nei modelli del capitolo "Machine Learning". Poiché ogni livello aggiunge più funzionalità,
la dimensionalità delle mappe delle caratteristiche risultanti diventa significativamente più grande. Questo è uno dei
motivi per cui gli studi di deep learning richiedono spesso un'enorme potenza di elaborazione.

Overfitting

Ricorda dal capitolo precedente, che l'overfitting può verificarsi quando il tuo modello è troppo complesso
rispetto a quello che sta modellando. Nel caso più estremo, un modello memorizza la sua formazione
dati. Quando fai previsioni con un modello overfit, saranno accurate se si tratta di nuovi dati
corrisponde ai dati di addestramento, ma il modello potrebbe funzionare male con dati che non ha mai visto.

L'overfitting tende a verificarsi nel deep learning man mano che diventa anche la dimensionalità degli strati
7
6 ,, 8
grande. Ciò fa sì che la rete apprenda caratteristiche specifiche delle immagini delle cifre del set di formazione,
piuttosto che apprendere le caratteristiche generali delle immagini digitali. Alcune tecniche per prevenire
l'overfitting include l'addestramento per un minor numero di epoche, l'aumento dei dati, l'abbandono e L1 o L2
9, 0
regolarizzazione. Discuteremo l'abbandono più avanti nel capitolo.

6
ttps: //cs231n.github.io/convolutionalnetworks/ .
7

T
hfn454
7
ttps: //medium.com/@cxu24/whydimensionalityreductionis Pagina 697
mportantdd60b5611543 .

8
ttps: //towardsdatascience.com/preventingdeepneuralnetworkfrom
verfitting953458db800a .

9
ttps: //towardsdatascience.com/deeplearning3moreoncnns

andlingoverfitting2bd5d99abe5d .

0
ttps: //www.kdnuggets.com/2015/04/preventingoverfittingneural

etworks.html .

Una dimensionalità più elevata aumenta anche (e talvolta esplode) il tempo di calcolo. Se tu sei
eseguendo il deep learning su CPU anziché GPU o TPU, la formazione potrebbe diventare
intollerabilmente lento.

Aggiunta di un livello di raggruppamento

Per ridurre l'overfitting e il tempo di calcolo, uno strato di convoluzione è spesso seguito da uno o
più livelli che riducono la dimensionalità dell'output del livello di convoluzione. Un pooling
layer comprime (o esegue il downsampling) dei risultati scartando le feature, il che aiuta a creare
il modello più generale. La tecnica di pooling più comune è chiamata max pooling , che
esamina un quadrato 2by2 di caratteristiche e mantiene solo la caratteristica massima. Capire
pooling, assumiamo ancora una volta un set di funzionalità 6by6.Nel diagramma seguente, il file

i valori numerici nel quadrato 6by6 rappresentano le caratteristiche che desideriamo comprimere e il file
Il quadrato blu 2by2 in posizione 1 rappresenta il pool iniziale di caratteristiche da esaminare:
Il livello max pooling prima guarda il pool nella posizione 1 sopra, quindi restituisce il massimo
caratteristica da quel pool — 9 nel nostro diagramma.A differenza della convoluzione, non c'è sovrapposizione tra
piscine. La piscina si sposta della sua larghezza: per una piscina 2by2, il passo è 2. Per la seconda piscina,
rappresentato dal quadrato arancione 2by2, il livello emette 7. Per il terzo pool, il livello
uscite 9. Una volta che la piscina raggiunge il bordo destro, lo strato di raggruppamento sposta la piscina verso il basso del suo
altezza - 2 righe - quindi continua da sinistra a destra. Perché ogni gruppo di quattro caratteristiche è
ridotto a uno, il raggruppamento 2by2 comprime il numero di funzioni del 75%.

hH
on45io
Aggiungiamo un livello MaxPooling2D al nostro modello: Pagina 698

lecca qui per visualizzare l'immagine del codice

[28]: cnn.add (MaxPooling2D (pool_size = ( 2 , 2 )))

1
Ciò riduce l'output del livello precedente da 26by26by64 a 13by13by64.

1
Un'altra tecnica per ridurre l'overfitting consiste nell'aggiungere strati Dropout.

Sebbene il pooling sia una tecnica comune per ridurre l'overfitting, alcune ricerche lo suggeriscono
strati convoluzionali aggiuntivi che utilizzano passi più grandi per i loro kernel possono ridurre
2
dimensionalità e overfitting senza scartare le caratteristiche.

2
Tobias, Jost, Dosovitskiy, Alexey, Brox, Thomas, Riedmiller e Martin. Impegnarsi per
Semplicità: The All Convolutional Net. 13 aprile 2015.
ttps: //arxiv.org/abs/1412.6806 .

Aggiunta di un altro livello convoluzionale e livello di raggruppamento

I convnet hanno spesso molti livelli di convoluzione e pooling.I convnet della squadra di Keras tendono a farlo
raddoppia il numero di filtri negli strati convoluzionali successivi per consentire al modello di apprendere
3
più relazioni tra le caratteristiche. Quindi, aggiungiamo un secondo livello di convoluzione con 128
filtri, seguito da un secondo livello di pooling per ridurre ancora una volta la dimensionalità del 75%:

3
ttps: //github.com/kerasteam/keras

pplications / tree / master / keras_applications .

lecca qui per visualizzare l'immagine del codice

[29]: cnn.add (Conv2D (filters = 128 , kernel_size = ( 3 , 3 ), activation = 'relu' ))

[30]: cnn.add (MaxPooling2D (pool_size = ( 2 , 2 )))

L'input per il secondo livello di convoluzione è l'output 13by13by64 del primo pool
strato. Quindi, l'output dello snippet [29] sarà 11by11by128. Per dimensioni dispari come 11by
11, i livelli di pooling di Keras arrotondano per difetto (in questo caso a 10by10), quindi questo pool
l'output del livello sarà 5by5by128.

Appiattimento dei risultati

A questo punto, l'output del livello precedente è tridimensionale (5by5by128), ma il finale


uscita del nostro modello sarà un monodimensionale array di 10 probabilità che classificano la
cifre. Per prepararci alle previsioni finali unidimensionali, dobbiamo prima appiattire il file
output tridimensionale del livello precedente. Un livello Keras Flatten rimodella il suo input in uno
dimensione. In questo caso, l'output del livello Flatten sarà 1by3200 (ovvero 5 * 5 *
128):

[31]: cnn.add (Flatten ())

uCn'
5h

Pagina 699

Aggiunta di uno strato denso per ridurre il numero di funzioni

I livelli prima del livello Appiattisci hanno appreso le caratteristiche delle cifre.Ora dobbiamo prendere tutti quelli

caratteristiche e imparare le relazioni tra di loro in modo che il nostro modello possa classificare quale cifra ciascuna
l'immagine rappresenta. Imparare le relazioni tra le caratteristiche e eseguire la classificazione è
realizzato con strati densi completamente connessi , come quelli mostrati nella rete neurale

diagramma all'inizio del capitolo. Il seguente strato denso crea 128 neuroni (unità) che
impara dalle 3200 uscite del livello precedente:

lecca qui per visualizzare l'immagine del codice

[32]: cnn.add (Dense (units = 128 , activation = 'relu' ))

Molti convnet contengono almeno uno strato Denso come quello sopra.Convnet orientate a più

set di dati di immagini complessi con immagini ad alta risoluzione come ImageNet, un set di dati di oltre 14
4
milioni di immagini — spesso hanno diversi strati densi, comunemente con 4096 neuroni. Puoi
5
vedere tali configurazioni in molti dei convnets IMAGEnet preaddestrato di Keras-abbiamo elencare queste
nel ezione 15.11.

4
ttp: //www.imagenet.org .

5
ttps: //github.com/kerasteam/keras
pplications / tree / master / keras_applications .

Aggiunta di un altro strato denso per produrre l'output finale

Il nostro livello finale è uno strato denso che classifica gli input in neuroni che rappresentano il file

classi da 0 a 9. La funzione di attivazione softmax converte i valori di questi


restanti 10 neuroni nelle probabilità di classificazione. Il neurone che produce il più alto
la probabilità rappresenta la previsione per un'immagine di una data cifra:

lecca qui per visualizzare l'immagine del codice

[33]: cnn.add (Dense (unità = 10 , attivazione = 'softmax' ))

Stampa del riepilogo del modello

Il metodo di riepilogo di un modello mostra i livelli del modello. Alcune cose interessanti da notare

sono le forme di output dei vari livelli e il numero di parametri.I parametri


6, 7
sono i pesi che la rete apprende durante l'allenamento. Questa è una rete relativamente piccola,
tuttavia dovrà imparare quasi 500.000 parametri! E questo è per immagini minuscole che hanno meno
di un quarto della risoluzione delle icone sulla maggior parte delle schermate home degli smartphone.Immaginare
quante funzioni una rete dovrebbe imparare per elaborare fotogrammi video 4K ad alta risoluzione
o le immagini ad altissima risoluzione prodotte dalle fotocamere digitali odierne.Nell'output

Shape, None significa semplicemente che il modello non sa in anticipo quanti allenamenti
campioni che fornirai: questo è noto solo quando inizi la formazione.

6
ttps: //hackernoon.com/everythingyouneedtoknowaboutneural

S
C
5h
un'
etworks8988c3ee4491 . Pagina 700

7
ttps: //www.kdnuggets.com/2018/06/deeplearningbestpractices

ottoinitialization.html .

lecca qui per visualizzare l'immagine del codice

[34]: cnn.summary ()
_________________________________________________________________
Livello (tipo) Parametro forma di output #
================================================== ===============
conv2d_1 (Conv2D) (Nessuno, 26, 26, 64) 640
_________________________________________________________________
max_pool2d_1 (MaxPooling2 (Nessuno, 13, 13, 64) 0
_________________________________________________________________
conv2d_2 (Conv2D) (Nessuno, 11, 11, 128) 73856
_________________________________________________________________
max_pool2d_2 (MaxPooling2 (Nessuno, 5, 5, 128) 0
_________________________________________________________________
flatten_1 (Flatten) (Nessuno, 3200) 0
_________________________________________________________________
dense_1 (Dense) (Nessuno, 128) 409728
_________________________________________________________________
dense_2 (Dense) (Nessuno, 10) 1290
================================================== ===============
Parametri totali: 485.514
Parametri addestrabili: 485,514
Parametri non addestrabili: 0
_________________________________________________________________

Inoltre, notare che non ci sono parametri "non allenabili". Per impostazione predefinita, Keras allena tutti
parametri, ma è possibile impedire l'addestramento per livelli specifici, che in genere viene eseguito
quando si sintonizzano le reti o si utilizzano i parametri appresi di un altro modello in un nuovo
8
modello (un processo chiamato transfer learning ).

8
ttps: //keras.io/gettingstarted/faq/#howcanifreezekeras
ayers .

Visualizzazione della struttura di un modello

È possibile visualizzare il riepilogo del modello utilizzando la funzione plot_model dal modulo

tensorflow.keras.utils:

lecca qui per visualizzare l'immagine del codice

[35]: da tensorflow.keras.utils import plot_model


da IPython.display importa immagine
plot_model (cnn, to_file = 'convnet.png' , show_shapes = True ,
show_layer_names = True )
Immagine (nome file = 'convnet.png' )

Dopo aver memorizzato la visualizzazione in convnet.png, usiamo il modulo di IPython.display Immagine


9
classe per mostrare l'immagine nel taccuino. Keras assegna i nomi dei livelli nell'immagine:

9
Il nodo con il valore intero grande 112430057960 nella parte superiore del diagramma sembra essere

5C
lnhw
un bug nella versione corrente di Keras. Questo nodo rappresenta il livello di input e dovrebbe dire Pagina 701
InputLayer.
Compilazione del modello

Dopo aver aggiunto tutti i livelli, completa il modello chiamando il suo metodo di compilazione :

lecca qui per visualizzare l'immagine del codice

C
Pagina 702
[36]: cnn.compile (optimizer = 'adam' ,
loss = 'categorical_crossentropy' ,
metriche = [ "accuratezza" ])

Gli argomenti sono:

optimizer = 'adam': l' ottimizzatore che questo modello utilizzerà per regolare i pesi
0
in tutta la rete neurale mentre apprende.Ci sono molti ottimizzatori - "adam"
1, 2
funziona bene su un'ampia varietà di modelli.

0
Per altri ottimizzatori Keras, vedere ttps: //keras.io/optimizers/ .

1
ttps: //medium.com/octavianai/whichoptimizerandlearning

ateshouldiusefordeeplearning5acb418f9b2 .

2
ttps: //towardsdatascience.com/typesofoptimizationalgorithms
utilizzato nelle reti neurali e sempre per ottimizzare il gradiente

5ae5d39529f .

loss = "categorical_crossentropy": questa è la funzione di perdita utilizzata dall'ottimizzatore


in reti multiclassificazione come il nostro convnet, che prevede 10 classi.Come la
rete neurale apprende, l'ottimizzatore tenta di ridurre al minimo i valori restituiti dalla perdita
funzione. Minore è la perdita, migliore è la rete neurale nel prevedere cosa ciascuno
l'immagine è. Per la classificazione binaria (che useremo più avanti in questo capitolo), Keras fornisce

"binary_crossentropy" e per la regressione "mean_squared_error". Per altro


funzioni di perdita, vederettps: //keras.io/losses/ .

metrics = ["accuratezza"] - Questo è un elenco delle metriche in base alle quali la rete produrrà
aiutarti a valutare il modello. La precisione è una metrica comunemente utilizzata nella classificazione
Modelli. In questo esempio, utilizzeremo la metrica di precisione per verificare la percentuale di correttezza

predizioni. Per un elenco di altre metriche, vedere ttps: //keras.io/metrics/ .

15.6.5 Formazione e valutazione del modello


Simile ai modelli di Scikitlearn, addestriamo un modello di Keras chiamando il suo metodo di adattamento :

Come in Scikitlearn, i primi due argomenti sono i dati di addestramento e l'obiettivo categoriale
etichette.

epochs specifica il numero di volte in cui il modello deve elaborare l'intera serie di addestramento
dati. Come accennato in precedenza, le reti neurali vengono addestrate in modo iterativo.

batch_size specifica il numero di campioni da elaborare in un momento durante ogni epoca.


La maggior parte dei modelli specifica una potenza di 2 da 32 a 512. Dimensioni di batch più grandi possono ridurre il modello
3
precisione. Abbiamo scelto 64. Puoi provare diversi valori per vedere come influenzano il modello
prestazione.

3
Keskar, Nitish Shirish, Dheevatsa Mudigere, Jorge Nocedal, Mikhail Smelyanskiy e
Ping Tak Peter Tang. On LargeBatch Training for Deep Learning: Generalization Gap

6h
r9
e Sharp Minima. CoRR abs / 1609.04836 (2016). Pagina 703
ttps: //arxiv.org/abs/1609.04836 .

In generale, alcuni campioni dovrebbero essere utilizzati per convalidare il modello. Se specifichi validation
dati, dopo ogni epoca, il modello li utilizzerà per fare previsioni e visualizzare il file
perdita e accuratezza della convalida . Puoi studiare questi valori per regolare i tuoi livelli e l'adattamento

gli iperparametri del metodo o eventualmente modificare la composizione dei livelli del modello. Qui,
abbiamo usato l' argomento validation_split per indicare che il modello dovrebbe riservare
4
l' ultimo 10% (0,1) dei campioni di addestramento per la convalida —In questo caso, 6000 campioni
verrà utilizzato per la convalida. Se disponi di dati di convalida separati, puoi utilizzare l'estensione

argomento validation_data (come vedrai in ezione 15.9) per specificare una tupla contenente
matrici di campioni ed etichette target. In generale, è meglio essere selezionati in modo casuale
dati di convalida . Puoi usare la funzione train_test_split di scikitlearn per questo scopo
(come faremo più avanti in questo capitolo), quindi passare i dati selezionati a caso con l'estensione

argomento validation_data.

4
ttps: //keras.io/gettingstarted/faq/#howisthevalidation
plitcomputed .

Nell'output seguente, abbiamo evidenziato l'accuratezza dell'addestramento (acc) e l'accuratezza della convalida
(val_acc) in grassetto:

lecca qui per visualizzare l'immagine del codice

[37]: cnn.fit (X_train, y_train, epochs = 5 , batch_size = 64 ,


validation_split = 0.1 )
Addestramento su 54000 campioni, convalida su 6000 campioni
Epoca 1/5
54000/54000 [==============================] 68 s 1 ms / perdita di passo: 0,1407 cc: 0,95
poch 2/5
54000/54000 [==============================] 64 s 1 ms / perdita di passo: 0,0426 cc: 0,98
poch 3/5
54000/54000 [==============================] 69 s 1 ms / perdita di passo: 0,0299 cc: 0,99
poch 4/5
54000/54000 [==============================] 70 s 1 ms / perdita di passo: 0,0197 cc: 0,99
poch 5/5
54000/54000 [==============================] 63 s 1 ms / perdita di passo: 0,0155 cc: 0,99
37]: <tensorflow.python.keras.callbacks.History su 0x7f105ba0ada0>

Nel sezione 15.7 , introdurremo TensorBoard, uno strumento TensorFlow per la visualizzazione dei dati da
i tuoi modelli di deeplearning. In particolare, vedremo grafici che mostrano come l'allenamento e
l'accuratezza della convalida ei valori di perdita cambiano nel corso delle epoche.Nel ezione 15.8, bene
dimostrare lo strumento ConvnetJS di Andrej Karpathy, che addestra le convnet nel tuo browser web
e visualizza dinamicamente gli output dei livelli, compreso ciò che ogni livello convoluzionale "vede"
mentre impara. Esegui anche i suoi modelli MNIST e CIFAR10. Questi ti aiuteranno a capire meglio

operazioni complesse delle reti neurali.

Man mano che la formazione procede, il metodo di adattamento fornisce informazioni che mostrano i progressi di

ogni epoca, quanto tempo ha impiegato per essere eseguita (in questo caso, ognuna ha impiegato 63-70 secondi), e
le metriche di valutazione per quel passaggio.Durante l'ultima epoca di questo modello, la precisione raggiunta

h[EC
6S

99,48% per i campioni di addestramento (acc) e 99,27% per i campioni di convalida (val_acc). Pagina 704
Sono numeri impressionanti, dato che non abbiamo ancora provato a mettere a punto gli iperparametri
o modificare il numero e il tipo dei livelli, il che potrebbe portare a risultati ancora migliori (o peggiori)
risultati. Come il machine learning, il deep learning è una scienza empirica che trae vantaggio da molti
sperimentazione.

Valutazione del modello

Ora possiamo verificare l'accuratezza del modello sui dati che il modello non ha ancora visto. Per farlo, noi
chiama il metodo di valutazione del modello del modello , che mostra come output il tempo impiegato
elaborare i campioni di prova (quattro secondi e 366 microsecondi in questo caso):

lecca qui per visualizzare l'immagine del codice

[38]: perdita, precisione = cnn.evaluate (X_test, y_test)


10000/10000 [==============================] 4s 366us / passo

[39]: perdita
[39]: 0,026809450998473768

[40]: accuratezza
[40]: 0,9917

Secondo l'output precedente, il nostro modello convnet è accurato al 99,17% quando prevede il
etichette per dati invisibili e, a questo punto, non abbiamo provato a mettere a punto il modello. Con un po '
ricerche online, puoi trovare modelli in grado di prevedere MNIST con una precisione quasi del 100%.Provare
sperimentare diversi numeri di livelli, tipi di livelli e parametri di livello e
osserva come questi cambiamenti influenzano i tuoi risultati.

Fare previsioni

Il metodo di previsione del modello prevede le classi delle immagini delle cifre nella sua matrice di argomenti

(X_test):

lecca qui per visualizzare l'immagine del codice

[41]: previsioni = cnn.predict (X_test)

Possiamo verificare quale dovrebbe essere la prima cifra di esempio guardando y_test [0]:

lecca qui per visualizzare l'immagine del codice

[42]: y_test [ 0 ]
[42]: array ([0., 0., 0., 0., 0., 0., 0., 1., 0., 0.], dtype = float32)

Secondo questo output, il primo campione è la cifra 7, perché la rappresentazione categoriale


dell'etichetta del campione di prova specifica un 1.0 all'indice 7 - ricorda che abbiamo creato questa rappresentazione
tramite la codifica onehot .

Controlliamo le probabilità restituite dal metodo di previsione per il primo campione di prova:

C
lecca qui per visualizzare l'immagine del codice Pagina 705

[43]: per indice, probabilità in enumerazione (previsioni [ 0 ]):


print (f ' {indice} : {probabilità: .10 %} ' )
0: 0,0000000201%
1: 0,0000001355%
2: 0,0000186951%
3: 0,0000015494%
4: 0,0000000003%
5: 0,0000000012%
6: 0,0000000000%
7: 99,9999761581%
8: 0,0000005577%
9: 0,0000011416%

Secondo l'output, le previsioni [0] indicano che il nostro modello ritiene che questa cifra sia un 7
con quasi il 100% di certezza. Non tutte le previsioni hanno questo livello di certezza.

Individuazione delle previsioni errate

Successivamente, vorremmo visualizzare alcune delle immagini previste in modo errato per avere un'idea di quelle nostre
il modello ha problemi con. Ad esempio, se è sempre una previsione errata degli 8, forse abbiamo bisogno di più
8s nei nostri dati di allenamento.

Prima di poter visualizzare previsioni errate, dobbiamo individuarle. Tener conto di

previsioni [0] sopra. Per determinare se la previsione era corretta, dobbiamo


confrontare l'indice della massima probabilità nelle previsioni [0] con l'indice dell'elemento

contenente 1.0 in y_test [0]. Se questi valori di indice sono gli stessi, la previsione era
corretto; in caso contrario, non era corretto. La funzione argmax di NumPy determina l'indice del file

elemento con il valore più alto nel suo argomento array. Usiamolo per individuare l'errato
predizioni. Nel frammento seguente, p è l'array del valore previsto ed e è l'atteso

array di valori (i valori attesi sono le etichette per le immagini di prova del set di dati):

lecca qui per visualizzare l'immagine del codice

[44]: images = X_test.reshape (( 10000 , 28 , 28 ))


previsioni_errate = []

for i, (p, e) in enumerate (zip (predictions, y_test)):


previsto, previsto = np.argmax (p), np.argmax (e)

se previsto! = previsto:
wrong_predictions.append (
(i, immagini [i], predetto, atteso))

In questo frammento, rimodelliamo prima i campioni dalla forma (28, 28, 1) che Keras
necessario per imparare a (28, 28), che Matplotlib richiede per visualizzare le immagini.
Successivamente, popoliamo l'elenco false_predictions utilizzando l'istruzione for. Comprimiamo il file
righe che rappresentano ogni campione nelle previsioni di array e y_test, quindi enumerate

quelli così possiamo catturare i loro indici. Se i risultati di argmax per p ed e sono diversi, allora
la previsione non era corretta e aggiungiamo una tupla a wrong_predictions
contenente l'indice, l'immagine, il valore previsto e il valore atteso di quel campione.Noi

C
può confermare il numero totale di previsioni errate (su 10.000 immagini nel set di test) Pagina 706
con:

[45]: len (wrong_predictions)


[45]: 83

Visualizzazione di previsioni errate

Lo snippet seguente mostra 24 delle immagini errate etichettate con l'indice di ciascuna immagine,
valore previsto (p) e valore atteso (e):

lecca qui per visualizzare l'immagine del codice

[46]: figura, assi = plt.subplots (nrows = 4 , ncols = 6 , figsize = ( 16 , 12 ))

per gli assi, elemento in zip (axes.ravel (), wrong_predictions):


indice, immagine, previsto, previsto = elemento
axes.imshow (image, cmap = plt.cm.gray_r)
axes.set_xticks ([]) # rimuove i segni di graduazione dell'asse x
axes.set_yticks ([]) # rimuove i segni di graduazione yaxis
axes.set_title (
f 'indice: {indice} \ np: {predetto} ; e: {atteso} ' )
plt.tight_layout ()

Prima di leggere i valori attesi, guarda ogni cifra e scrivi quale cifra pensi che sia
è. Questa è una parte importante per conoscere i tuoi dati:
Visualizzazione delle probabilità per diverse previsioni errate

Diamo un'occhiata alle probabilità di alcune previsioni errate. Viene visualizzata la seguente funzione
le probabilità per l'array di previsione specificato:

lecca qui per visualizzare l'immagine del codice Pagina 707

[47]: def display_probabilities (predizione):


per indice, probabilità di enumerare (predizione):
print (f ' {indice} : {probabilità: .10 %} ' )

Sebbene l'8 (all'indice 495) nella prima riga dell'output dell'immagine assomigli a un 8, il nostro modello

ha avuto problemi con esso. Come puoi vedere nel seguente output, il modello ha previsto questa immagine come
uno 0, ma pensavo anche che ci fosse il 16% di possibilità che fosse un 6 e il 23% di possibilità che fosse un 8:

lecca qui per visualizzare l'immagine del codice

[48]: display_probabilities (previsioni [495])


0: 59,7235262394%
1: 0,0000015465%
2: 0,8047289215%
3: 0.0001740813%
4: 0,0016636326%
5: 0,0030567855%
6: 16,1390662193%
7: 0,0000001781%
8: 23,3022540808%
9: 0,0255270657%

Il 2 (all'indice 583) nella prima riga era previsto essere un 7 con una certezza del 62,7%, ma il
il modello ha anche pensato che ci fosse una probabilità del 36,4% che fosse un 2:

lecca qui per visualizzare l'immagine del codice

[49]: display_probabilities (previsioni [583])


0: 0,0000003016%
1: 0,0000005715%
2: 36,4056706429%
3: 0,0176281916%
4: 0,0000561930%
5: 0,0000000003%
6: 0,0000000019%
7: 62,7455413342%
8: 0,8310816251%
9: 0,0000114385%

Il 6 (all'indice 625) all'inizio della seconda riga era previsto per essere un 4, sebbene quello

era tutt'altro che certo. In questo caso, la probabilità di un 4 (51,6%) era solo leggermente superiore a
la probabilità di un 6 (48,38%):

lecca qui per visualizzare l'immagine del codice

[50]: display_probabilities (previsioni [625])


0: 0.0008245181%
1: 0,0000041209%
2: 0,0012774357%
3: 0,0000000009%
4: 51,6223073006%
5: 0,0000001779%
6: 48,3754962683%

C
7: 0,0000000085% Pagina 708
8: 0,0000048182%
9: 0,0000785786%

15.6.6 Salvataggio e caricamento di un modello


I modelli di rete neurale possono richiedere un tempo di formazione significativo.Una volta che hai progettato e
testato un modello che si adatta alle tue esigenze, puoi salvare il suo stato. Ciò ti consente di caricarlo in un secondo momento
fare più previsioni. A volte i modelli vengono caricati e ulteriormente addestrati per nuovi problemi.
Ad esempio, i livelli nel nostro modello sanno già come riconoscere caratteristiche come linee e
curve, che potrebbero essere utili nel riconoscimento dei caratteri scritti a mano (come in EMNIST
set di dati). Quindi potresti potenzialmente caricare il modello esistente e usarlo come base per un file
5, 6
modello più robusto. Questo processo è chiamato transfer learning —Si trasferisce un esistente
conoscenza del modello in un nuovo modello. Il metodo di salvataggio di un modello Keras memorizza i dati del modello
architettura e informazioni sullo stato in un formato chiamato Hierarchical Data Format (HDF5) .
Tali file utilizzano l'estensione file .h5 per impostazione predefinita:

5
ttps: //towardsdatascience.com/transferlearningfrompretrained
odelsf2393f124751 .

6
ttps: //medium.com/nanonets/nanonetshowtousedeeplearningwhen
ouhavelimiteddataf68c0b512cab .

[51]: cnn.save ( 'mnist_cnn.h5' )

È possibile caricare un modello salvato con la funzione load_model dal file

modulo tensorflow.keras.models:

lecca qui per visualizzare l'immagine del codice

da tensorflow.keras.models importa load_model


cnn = load_model ( 'mnist_cnn.h5' )

È quindi possibile richiamare i suoi metodi. Ad esempio, se hai acquisito più dati, puoi chiamare
prevedere per fare ulteriori previsioni su nuovi dati, oppure chiamare idoneo per iniziare l'addestramento
con i dati aggiuntivi.

Keras fornisce diverse funzioni aggiuntive che ti consentono di salvare e caricare vari aspetti
dei tuoi modelli. Per ulteriori informazioni, vedere

ttps: //keras.io/gettingstarted/faq/#howcanisaveakerasmodel

15.7 VISUALIZZAZIONE DELLA FORMAZIONE DELLA RETE NEURALE CON


TENSIONE
Con le reti di deep learning, c'è così tanta complessità e così tanto da fare internamente
ti è nascosto che è difficile conoscere e comprendere appieno tutti i dettagli. Questo
crea sfide nel test, debug e aggiornamento di modelli e algoritmi. Apprendimento approfondito

6yhC
hm
impara le caratteristiche, ma potrebbero essercene un numero enorme e potrebbero non esserlo Pagina 709
evidente per te.

7 8
Google fornisce il TensorBoard, strumento per la visualizzazione di reti neurali implementato in
TensorFlow e Keras. Proprio come il cruscotto di un'auto visualizza i dati dai sensori dell'auto, ad esempio
come velocità, temperatura del motore e quantità di gas rimanente, un TensorBoard
dashboard visualizza i dati da un modello di deep learning che può fornire informazioni dettagliate su come
beh, il tuo modello sta imparando e potenzialmente ti aiuta a mettere a punto i suoi iperparametri.Ecco, lo faremo
introdurre TensorBoard.

7
ttps: //github.com/tensorflow/tensorboard/blob/master/README.md .

8
ttps: //www.tensorflow.org/guide/summaries_and_tensorboard .

Esecuzione di TensorBoard

TensorBoard monitora una cartella sul tuo sistema alla ricerca di file contenenti i dati che conterrà
visualizzare in un browser web. Qui creerai quella cartella, eseguirai il server TensorBoard,
quindi accedervi tramite un browser web. Eseguire le seguenti operazioni:

1. Passare alla cartella ch15 nel terminale, nella shell o nel prompt dei comandi di Anaconda.

2. Assicurati che il tuo ambiente Anaconda personalizzato tf_env sia attivato:

conda attivare tf_env

3. Esegui il seguente comando per creare una sottocartella denominata log in cui il tuo deep
i modelli di apprendimento scriveranno le informazioni che TensorBoard visualizzerà:

registri di mkdir

4. Eseguire TensorBoard

tensorboard logdir = logs

5. Ora puoi accedere a TensorBoard nel tuo browser web all'indirizzo

http: // localhost: 6006

Se ti connetti a TensorBoard prima di eseguire qualsiasi modello, inizialmente verrà visualizzata una pagina
9
che indica "Nessun dashboard attivo per il set di dati corrente".

9
TensorBoard attualmente non funziona con il browser Microsoft Edge.

Il dashboard di TensorBoard

TensorBoard monitora la cartella specificata cercando i file emessi dal modello durante
formazione. Quando TensorBoard vede gli aggiornamenti, carica i dati nella dashboard:

6h

Pagina 710

È possibile visualizzare i dati durante l'allenamento o al termine dell'allenamento. La dashboard sopra mostra
la scheda SCALARI di TensorBoard, che visualizza i grafici per i singoli valori che cambiano
tempo, come l'accuratezza dell'allenamento (acc) e la perdita (perdita) dell'allenamento mostrate nella prima riga, e

l'accuratezza della validazione (val_acc) e validation_loss (val_loss) mostrate nel secondo

riga. I diagrammi visualizzano un'esecuzione a 10epoch del nostro convnet MNIST, che abbiamo fornito nel file
notebook MNIST_CNN_TensorBoard.ipynb. Le epoche vengono visualizzate lungo gli assi x

a partire da 0 per la prima epoca. I valori di precisione e perdita vengono visualizzati sugli assi y .
Guardando le accuratezze di addestramento e convalida, puoi vedere nelle prime 5 epoche simili
risultati al fiveepoch eseguito nella sezione precedente.

Per la corsa 10epoch, la precisione dell'allenamento ha continuato a migliorare durante la nona epoca,
poi è leggermente diminuito. Questo potrebbe essere il punto in cui stiamo iniziando a sovradimensionare, ma noi
potrebbe essere necessario allenarsi più a lungo per scoprirlo. Per l'accuratezza della convalida, puoi vedere che è saltato
rapidamente, poi è stato relativamente piatto per cinque epoche prima di saltare e poi diminuire. Per il

perdita di allenamento, puoi vedere che diminuisce rapidamente, quindi diminuisce continuamente fino al nono
epoca, prima di un leggero aumento. La perdita di convalida è diminuita rapidamente, quindi è rimbalzata. Noi
potrebbe eseguire questo modello per più epoche per vedere se i risultati migliorano, ma sulla base di questi
diagrammi, sembra che intorno alla sesta epoca otteniamo una bella combinazione di allenamento e
accuratezza della convalida con una perdita minima di convalida.

Normalmente questi diagrammi sono impilati verticalmente nel cruscotto. Abbiamo utilizzato il campo di ricerca

(sopra i diagrammi) per mostrare quelli che avevano il nome "mnist" nel nome della cartella: faremo
configuralo in un attimo. TensorBoard può caricare dati da più modelli contemporaneamente e
puoi scegliere quale visualizzare. Ciò semplifica il confronto tra diversi modelli o
più esecuzioni dello stesso modello.

Copia il taccuino di MNIST Convnet


Per creare il nuovo blocco note per questo esempio:

1. Fare clic con il pulsante destro del mouse sul blocco appunti MNIST_CNN.ipynb nella scheda Browser di file di JupyterLab e
selezionare Duplica per creare una copia del blocco note.

2. Fare clic con il pulsante destro del mouse sul nuovo blocco note denominato MNIST_CNNCopy1.ipynb, quindi selezionare Rinomina, Pagina 711
inserisci il nome MNIST_CNN_TensorBoard.ipynb e premi Invio .

Apri il taccuino facendo doppio clic sul suo nome.

Configurazione di Keras per scrivere i file di registro di TensorBoard

Per utilizzare TensorBoard, prima di adattare il modello, è necessario configurare un TensorBoard

oggetto (modulo tensorflow.keras.callbacks), che il modello utilizzerà per scrivere i dati


in una cartella specificata monitorata da TensorBoard. Questo oggetto è noto come callback in
Keras. Nel taccuino, fai clic a sinistra dello snippet che chiama il metodo di adattamento del modello, quindi
digitare a, che è la scorciatoia per aggiungere una nuova cella di codice sopra la cella corrente (utilizzare b per

sotto ). Nella nuova cella, inserisci il seguente codice per creare l'oggetto TensorBoard:

lecca qui per visualizzare l'immagine del codice

da tensorflow.keras.callbacks importa TensorBoard


tempo di importazione

tensorboard_callback = TensorBoard (log_dir = f './logs/mnist {time.time ()} ' ,


histogram_freq = 1 , write_graph = True )

Gli argomenti sono:

log_dir: il nome della cartella in cui verranno scritti i file di registro di questo modello.Il
la notazione "./logs/" indica che stiamo creando una nuova cartella all'interno della cartella dei log
creato in precedenza, e lo seguiamo con "mnist" e l'ora corrente. Questo assicura
che ogni nuova esecuzione del notebook avrà la propria cartella di registro.Questo ti consentirà
per confrontare più esecuzioni in TensorBoard.

histogram_freq: la frequenza in epoche che Keras produrrà nel registro del modello
File. In questo caso, scriveremo i dati nei log per ogni epoca.

write_graph: quando questo è vero, verrà generato un grafico del modello. Puoi visualizzare il file
grafico nella scheda GRAFICI in TensorBoard.

Aggiornare la nostra chiamata per adattarla

Infine, dobbiamo modificare la chiamata al metodo fit originale nello snippet 37. Per questo esempio, impostiamo
il numero di epoch a 10 e abbiamo aggiunto l'argomento callbacks, che è un elenco di
0
oggetti di richiamata :

0
Puoi visualizzare gli altri callback di Keras su ttps: //keras.io/callbacks/ .

lecca qui per visualizzare l'immagine del codice

cnn.fit (X_train, y_train, epochs = 10 , batch_size = 64 ,


validation_split = 0.1 , callback = [tensorboard_callback])

È ora possibile rieseguire il notebook selezionando Kernel> Riavvia Kernel ed Esegui tutto

C
7h

Celle in JupyterLab. Al termine della prima epoca, inizierai a vedere i dati in TensorBoard. Pagina 712

15.8 CONVNETJS: APPRENDIMENTO PROFONDO BASATO SU BROWSER


FORMAZIONE E VISUALIZZAZIONE
In questa sezione, faremo una panoramica dello strumento ConvnetJS basato su JavaScript di Andrej Karpathy per
1
formazione e visualizzazione di reti neurali convoluzionali nel tuo browser web:

1
Puoi anche scaricare ConvnetJS da GitHub all'indirizzo
ttps: //github.com/karpathy/convnetjs .
lecca qui per visualizzare l'immagine del codice

ttps: //cs.stanford.edu/people/karpathy/convnetjs/

È possibile eseguire le reti neurali convoluzionali di esempio ConvnetJS o crearne di proprie.Noi abbiamo
ha utilizzato lo strumento su diversi browser desktop, tablet e telefoni.

La demo ConvnetJS MNIST addestra una rete neurale convoluzionale utilizzando il set di dati MNIST
abbiamo presentato in ezione 15.6. La demo presenta una dashboard scorrevole che si aggiorna
dinamicamente mentre il modello si allena e contiene diverse sezioni.

Statistiche di allenamento

Questa sezione contiene un pulsante Pausa che consente di interrompere l'apprendimento e "congelare" il file

visualizzazioni del dashboard corrente. Dopo aver messo in pausa la demo, il testo del pulsante cambia in
curriculum vitae. Facendo nuovamente clic sul pulsante si continua l'allenamento. Questa sezione presenta anche la formazione
statistiche, compresa la precisione dell'addestramento e della convalida e un grafico della perdita di addestramento.

Istanziare una rete e un trainer

In questa sezione troverai il codice JavaScript che crea la rete neurale convoluzionale.
La rete predefinita ha livelli simili a convnet in ezione 15.6. Il ConvnetJS
2
la documentazione mostra i tipi di layer supportati e come configurarli. Puoi
sperimentare con diverse configurazioni di livelli nella casella di testo fornita e iniziare ad addestrare un file
rete aggiornata facendo clic sul pulsante cambia rete.

2
ttps: //cs.stanford.edu/people/karpathy/convnetjs/docs.html .

Visualizzazione di rete

Questa sezione chiave mostra un'immagine di formazione alla volta e come la rete la elabora
immagine attraverso ogni strato. Fare clic sul pulsante Pausa per ispezionare gli output di tutti i livelli per un dato
digit per avere un'idea di ciò che la rete "vede" mentre apprende.L'ultimo strato della rete produce
le classificazioni probabilistiche. Mostra 10 quadrati, 9 neri e 1 bianco, che indicano il
classe prevista dell'immagine della cifra corrente.

Previsioni di esempio sul set di prova

La sezione finale mostra una selezione casuale delle immagini del set di prova e le prime tre possibili

classi per ogni cifra. Quello con la probabilità più alta è mostrato su una barra verde e il

ShC
7h

altri due vengono visualizzati su barre rosse. La lunghezza di ogni barra è un'indicazione visiva di quella classe Pagina 713
probabilità.

15.9 RETI NEURALI RICORRENTI PER SEQUENZE;


ANALISI DEL SENTIMENT CON IL DATASET IMDB
Nella rete MNIST CNN, ci siamo concentrati su strati sovrapposti che sono stati applicati in sequenza .
Sono possibili modelli non sequenziali, come vedrai qui con le reti neurali ricorrenti . Nel
in questa sezione, utilizziamo le recensioni dei film IMDb (Internet Movie Database) in bundle di Keras
3
set di dati per eseguire la classificazione binaria , prevedendo se il sentiment di una determinata recensione
è positivo o negativo.

3
Maas, Andrew L. e Daly, Raymond E. e Pham, Peter T. e Huang, Dan e Ng,
Andrew Y. e Potts, Christopher, "Learning Word Vectors for Sentiment Analysis",
Atti della 49a riunione annuale dell'Associazione per la linguistica computazionale:
Human Language Technologies , giugno 2011. Portland, Oregon, USA.Associazione per
Linguistica computazionale, pagg.142 150. ttp: //www.aclweb.org/anthology/P11
015 .

Useremo una rete neurale ricorrente (RNN) , che elabora sequenze di dati, come
serie temporali o testo nelle frasi. Il termine "ricorrente" deriva dal fatto che il neurale
rete contiene cicli in cui l'output di un dato livello diventa l'input di quello stesso
strato nel passaggio successivo . In una serie temporale, una fase temporale è il momento successivo. In un testo
sequenza, un "passo temporale" sarebbe la parola successiva in una sequenza di parole.

Il looping negli RNN consente loro di apprendere e ricordare le relazioni tra i dati in
la sequenza. Ad esempio, considera le seguenti frasi che abbiamo usato nel " aturale
capitolo Elaborazione anguage ”. La frase

Il cibo non è buono.

ha chiaramente un sentimento negativo. Allo stesso modo, la frase

Il film era buono.

ha un sentimento positivo, anche se non così positivo come

Il film è stato eccellente!

Nella prima frase, la parola "buono" da sola ha un sentimento positivo.Tuttavia, quando


preceduto da "no", che appare in precedenza nella sequenza, il sentimento diventa negativo.
Gli RNN tengono conto delle relazioni tra la parte precedente e quella successiva di una sequenza.

Nell'esempio precedente, le parole che determinano il sentimento erano adiacenti.Però,


quando si determina il significato del testo ci possono essere molte parole da considerare e un arbitrario
numero di parole tra di loro. In questa sezione, useremo una memoria Long ShortTerm
(LSTM) , che rende ricorrente la rete neurale ed è ottimizzato per gestire

LhN
17
imparare da sequenze come quelle che abbiamo descritto sopra. Pagina 714

5 6
4,,
Gli RNN sono stati utilizzati per molte attività, tra cui:

4
ttps: //www.analyticsindiamag.com/overviewofrecurrentneural
etworksandtheirapplications / .

5
ttps: //en.wikipedia.org/wiki/Recurrent_neural_network#Applications .

6
ttp: //karpathy.github.io/2015/05/21/rnneffectiveness/ .

metodo di scrittura intuitivo: visualizzazione delle possibili parole successive durante la digitazione,

analisi del sentiment,

rispondere alle domande con le migliori risposte previste da un corpus,

traduzione interlingua e

sottotitoli automatici nei video.

15.9.1 Caricamento del set di dati delle recensioni dei film di IMDb
Il set di dati delle recensioni dei film di IMDb incluso con Keras contiene 25.000 campioni di formazione e
25.000 campioni di test, ciascuno etichettato con il proprio sentimento positivo (1) o negativo (0).Facciamo
importa il modulo tensorflow.keras.datasets.imdb in modo da poter caricare il set di dati:

lecca qui per visualizzare l'immagine del codice

[1]: da tensorflow.keras.datasets import imdb

La funzione load_data del modulo imdb restituisce i set di addestramento e test IMDb. Là

sono oltre 88.000 parole uniche nel set di dati. La funzione load_data consente di specificare
il numero di parole univoche da importare come parte dei dati di addestramento e test.In questo caso, noi
ha caricato solo le prime 10.000 parole che si verificano più di frequente a causa dei limiti di memoria di
il nostro sistema e il fatto che ci stiamo allenando (intenzionalmente) su una CPU piuttosto che su una GPU
(perché la maggior parte dei nostri lettori non avrà accesso a sistemi con GPU e TPU). Più
dati caricati, più lungo sarà l'addestramento, ma più dati possono aiutare a produrre modelli migliori:

lecca qui per visualizzare l'immagine del codice

[2]: number_of_words = 10000

[3]: (X_train, y_train), (X_test, y_test) = imdb.load_data (


num_words = numero_di_parole)
La funzione load_data restituisce una tupla di due elementi contenenti l'addestramento e il test

imposta. Ogni elemento è esso stesso una tupla contenente rispettivamente i campioni e le etichette.In un dato
review, load_data sostituisce tutte le parole al di fuori delle prime 10.000 con un valore segnaposto,
di cui parleremo a breve.

5.9.2 Esplorazione dei dati


n771
hC
15.9.2 Data Explorat n Pagina 715

Controlliamo le dimensioni dei campioni del training set (X_train), le etichette del training set
(y_train), campioni di set di test (X_test) ed etichette di set di test (y_test):

lecca qui per visualizzare l'immagine del codice

[4]: X_train.shape
[4]: (25000,)

[5]: y_train.shape
[5]: (25000,)

[6]: X_test.shape
[6]: (25000,)

[7]: y_test.shape
[7]: (25000,)

Gli array y_train e y_test sono array monodimensionali contenenti 1 e 0,

indicando se ogni recensione è positiva o negativa. Sulla base degli output precedenti,

Anche X_train e X_test sembrano essere unidimensionali. Tuttavia, i loro elementi in realtà
7
sono elenchi di numeri interi, ciascuno dei quali rappresenta il contenuto di una recensione, come mostrato nello snippet [9]:

7
Qui abbiamo usato la magia% pprint per disattivare la stampa carina, quindi il seguente frammento s

l'output potrebbe essere visualizzato in orizzontale anziché in verticale per risparmiare spazio.Puoi voltarti
stampare abbastanza di nuovo eseguendo nuovamente la magia% pprint.

lecca qui per visualizzare l'immagine del codice

[8]:% pprint
[8]: La stampa graziosa è stata disattivata

[9]: X_train [ 123 ]


[9]: [1, 307, 5, 1301, 20, 1026, 2511, 87, 2775, 52, 116, 5, 31, 7, 4, 91, 12 0, 102,

ere i modelli di deep learning richiedono dati numerici , quindi il team di Keras ha preelaborato l'IMDb
set di dati per te.

Codifiche di recensioni di film

Poiché le recensioni dei film sono codificate numericamente, per visualizzare il loro testo originale, è necessario
conoscere la parola a cui corrisponde ogni numero. Il set di dati IMDb di Keras fornisce un file
dizionario che mappa le parole nei loro indici. Il valore corrispondente di ogni parola è il suo
classifica di frequenza tra tutte le parole dell'intero set di recensioni.Quindi la parola con il
il ranking 1 è la parola che ricorre più di frequente (calcolata dal team di Keras dal

dataset), la parola con posizione 2 è la seconda parola che ricorre più di frequente e così via.

Sebbene i valori del dizionario inizino con 1 come parola che ricorre più frequentemente, in ciascuno
revisione codificata (come X_train [123] mostrato in precedenza), i valori della classifica sono compensati di 3 .
Pertanto, qualsiasi recensione contenente la parola che ricorre più frequentemente avrà il valore 4 ovunque
quella parola appare nella recensione. Keras si riserva i valori 0, 1 e 2 in ciascuna recensione codificata

io
C
7K

per i seguenti scopi: Pagina 716

Il valore 0 in una recensione rappresenta il riempimento . Gli algoritmi di deep learning di Keras si aspettano tutti i file
campioni di addestramento per avere le stesse dimensioni, quindi potrebbe essere necessario ampliare alcune revisioni
a una data lunghezza e alcuni accorciati a quella lunghezza. Recensioni che devono essere ampliate
sono imbottiti con 0.

Il valore 1 rappresenta un token che Keras utilizza internamente per indicare l'inizio di un testo
sequenza per scopi di apprendimento.
Il valore 2 in una recensione rappresenta una parola sconosciuta, in genere una parola che non lo era
caricato perché hai chiamato load_data con l'argomento num_words. In questo caso, any
recensione che conteneva parole con classifiche di frequenza maggiori di num_words
fai sostituire i valori numerici di quelle parole con 2. Tutto questo viene gestito da Keras quando tu
caricare i dati.

Poiché i valori numerici di ciascuna recensione sono compensati da 3, dovremo tenerne conto quando lo faremo
decodificare la recensione.

Decodificare una recensione di un film

Decodifichiamo una recensione. Per prima cosa, ottieni il dizionario wordtoindex chiamando la funzione
get_word_index dal modulo tensorflow.keras.datasets.imdb:

lecca qui per visualizzare l'immagine del codice

[10]: word_to_index = imdb.get_word_index ()

La parola "fantastico" potrebbe apparire in una recensione positiva del film, quindi vediamo se è nel file

dizionario:

lecca qui per visualizzare l'immagine del codice

[11]: word_to_index [ "great" ]


[11]: 84

Secondo l'output, "ottimo" è l'84a parola più frequente del set di dati. Se cerchi un file
parola che non è nel dizionario, otterrai un'eccezione.

Per trasformare le valutazioni di frequenza in parole, invertiamo prima word_to_index


mappatura del dizionario, in modo da poter cercare ogni parola in base alla sua frequenza.Il seguente
la comprensione del dizionario inverte la mappatura:

lecca qui per visualizzare l'immagine del codice

[12]: index_to_word = \
{index: word for (word, index) in word_to_index.items ()}

Ricorda che il metodo degli elementi di un dizionario ci consente di iterare attraverso tuple di valore-chiave

coppie. Spacchettiamo ogni tupla nelle variabili parola e indice, quindi creiamo una voce nel file Pagina 717
nuovo dizionario con l'espressione index: word.

Il seguente elenco di comprensione ottiene le prime 50 parole dal nuovo dizionario: ricordalo
la parola più frequente ha valore 1:

lecca qui per visualizzare l'immagine del codice

[13]: [index_to_word [i] for i in range ( 1 , 51 )]


[13]: ['the', 'and', 'a', 'of', 'to', 'is', 'br', 'in', 'it', 'i', 'this', ' t a ',' wa

ota che la maggior parte di queste sono parole non significative . A seconda dell'applicazione, potresti volerlo
rimuovere o mantenere le parole chiave. Ad esempio, se stavi creando un testo predittivo
applicazione che suggerisce la parola successiva in una frase che l'utente sta digitando, che vorresti mantenere
le parole di arresto in modo che possano essere visualizzate come previsioni.

Ora possiamo decodificare una recensione. Usiamo i due argomenti del dizionario index_to_word

metodo get anziché l'operatore [] per ottenere il valore per ogni chiave. Se un valore non è nel file
dizionario, il metodo get restituisce il suo secondo argomento, invece di sollevare un'eccezione.
L'argomento i 3 rappresenta l'offset nelle revisioni codificate di ciascuna recensione

valutazioni di frequenza. Quando i valori riservati di Keras 0–2 vengono visualizzati in una recensione, ottieni i ritorni "?";

altrimenti, get restituisce la parola con la chiave i 3 nel dizionario index_to_word:

lecca qui per visualizzare l'immagine del codice


[14]: '' .join ([index_to_word.get (i 3 , '?' ), Per i in X_train [ 123 ]])
[14]: '? film bello e commovente colori ricchi ottime impostazioni buone
recitazione e uno dei film più affascinanti che abbia visto da un po 'di tempo io
non ho mai visto un ambiente così interessante quando ero in Cina mia moglie
le è piaciuto così tanto che me lo ha chiesto? e valutalo in modo che lo farebbe altri
divertiti anche tu '

Possiamo vedere dall'array y_train che questa recensione è classificata come positiva:

[15]: y_train [ 123 ]


[15]: 1

15.9.3 Preparazione dei dati


Il numero di parole per recensione varia, ma Keras richiede che tutti i campioni abbiano lo stesso
dimensioni. Quindi, dobbiamo eseguire una preparazione dei dati. In questo caso, dobbiamo limitare
ogni recensione con lo stesso numero di parole. Alcune recensioni dovranno essere riempite con
i dati aggiuntivi e altri dovranno essere troncati . La funzione di utilità pad_sequences
(module tensorflow.keras.preprocessing.sequence ) rimodella i campioni di X_train

(ovvero, le sue righe) al numero di caratteristiche specificate dall'argomento maxlen (200) e

restituisce un array bidimensionale:

lecca qui per visualizzare l'immagine del codice

N
C

[16]: words_per_review = 200


Pagina 718

[17]: da tensorflow.keras.preprocessing.sequence import pad_sequences

[18]: X_train = pad_sequences (X_train, maxlen = words_per_review)

Se un campione ha più funzioni, pad_sequences lo tronca alla lunghezza specificata. Se una


sample ha meno funzioni, pad_sequences aggiunge 0 all'inizio della sequenza al pad

alla lunghezza specificata. Confermiamo la nuova forma di X_train:

[19]: X_train.shape
[19]: (25000, 200)

Dobbiamo anche rimodellare X_test per più avanti in questo esempio quando valutiamo il modello:

lecca qui per visualizzare l'immagine del codice

[20]: X_test = pad_sequences (X_test, maxlen = words_per_review)

[21]: X_test.shape
[21]: (25000, 200)

Suddivisione dei dati del test in dati di convalida e di test

Nel nostro convnet, abbiamo utilizzato l'argomento validation_split del metodo fit per indicarlo
Il 10% dei nostri dati di addestramento dovrebbe essere messo da parte per convalidare il modello durante l'addestramento.Per questo
Ad esempio, suddivideremo manualmente i 25.000 campioni di test in 20.000 campioni di test e 5.000
campioni di convalida. Passeremo quindi i 5.000 campioni di convalida al metodo di adattamento del modello
tramite l'argomento validation_data . Usiamo la funzione train_test_split di Scikitlearn

dal capitolo precedente per dividere il set di test:

lecca qui per visualizzare l'immagine del codice

[22]: da sklearn.model_selection importa train_test_split


X_test, X_val, y_test, y_val = train_test_split (
X_test, y_test, random_state = 11 , test_size = 0.20 )

Confermiamo anche la divisione controllando le forme di X_test e X_val:

[23]: X_test.shape
[23]: (20000, 200)

[24]: X_val.shape
[24]: (5000, 200)
15.9.4 Creazione della rete neurale
Successivamente, configureremo l'RNN. Ancora una volta, iniziamo con un modello sequenziale al quale
aggiungeremo i livelli che compongono la nostra rete:

C
lecca qui per visualizzare l'immagine del codice Pagina 719

[25]: da tensorflow.keras.models import Sequential

[26]: rnn = sequenziale ()

Quindi, importiamo i livelli che useremo in questo modello:

lecca qui per visualizzare l'immagine del codice

[27]: da tensorflow.keras.layers importa Dense, LSTM

[28]: da tensorflow.keras.layers.embeddings import Embedding

Aggiunta di un livello di incorporamento

In precedenza, abbiamo utilizzato la codifica onehot per convertire le etichette intere del set di dati MNIST in
dati categorici . Il risultato per ogni etichetta era un vettore in cui tutti gli elementi tranne uno erano 0.

Potremmo farlo per i valori di indice che rappresentano le nostre parole. Tuttavia, questo esempio
elabora 10.000 parole uniche. Ciò significa che avremmo bisogno di un array 10.000 per 10.000
rappresentano tutte le parole. Sono 100.000.000 di elementi e quasi tutti gli elementi dell'array
sarebbe 0. Questo non è un modo efficiente per codificare i dati. Se dovessimo elaborare tutti gli 88.000+
parole uniche nel set di dati, avremmo bisogno di un array di quasi otto miliardi di elementi!

Per ridurre la dimensionalità , gli RNN che elaborano le sequenze di testo iniziano tipicamente con un

livello di incorporamento che codifica ogni parola in una rappresentazione densevector più compatta .
I vettori prodotti dal livello di incorporamento catturano anche il contesto della parola, ovvero come a
la parola data si riferisce alle parole che la circondano. Quindi il livello di incorporamento consente all'RNN di apprendere
relazioni tra le parole tra i dati di addestramento.

Ci sono anche incorporamenti di parole predefiniti , come Word2Vec e GloVe . Puoi


caricali nelle reti neurali per risparmiare tempo di addestramento.A volte sono anche usati per aggiungere

relazioni di parole di base con un modello quando sono disponibili quantità minori di dati di addestramento.Questo
può migliorare la precisione del modello permettendogli di costruire su parole apprese in precedenza
relazioni, piuttosto che cercare di imparare quelle relazioni con quantità insufficienti di
dati.

Creiamo un livello di incorporamento (modulo tensorflow.keras.layers ):

lecca qui per visualizzare l'immagine del codice

[29]: rnn.add (Embedding (input_dim = number_of_words, output_dim = 128 ,


input_length = words_per_review))

Gli argomenti sono:

input_dim: il numero di parole univoche.

8
output_dim: la dimensione di ciascuna parola incorporata. Se carichi incorporamenti preesistenti

7C

come Word2Vec e GloVe , è necessario impostarlo in modo che corrisponda alle dimensioni delle parole incorporate Pagina 720
si carica.

8
ttps: //blog.keras.io/usingpretrainedwordembeddingsina
erasmodel.html .

input_length = words_per_review: il numero di parole in ogni campione di input.

Aggiunta di un livello LSTM


Successivamente, aggiungeremo un livello LSTM:

lecca qui per visualizzare l'immagine del codice

[30]: rnn.add (LSTM (unità = 128 , dropout = 0.2 , recurrent_dropout = 0.2 ))

Gli argomenti sono:

unità: il numero di neuroni nel livello. Più neuroni può fare di più la rete
ricorda. Come linea guida, puoi iniziare con un valore compreso tra la lunghezza delle sequenze
stai elaborando (200 in questo esempio) e il numero di classi che stai cercando di prevedere
9

(2 in questo esempio).

9
ttps: //towardsdatascience.com/choosingtheright
yperparametersforasimplelstmusingkerasf8e9ed76f046 .

dropout: la percentuale di neuroni da disabilitare in modo casuale durante l'elaborazione del livello
ingresso e uscita. Come i livelli di pooling nel nostro convnet, il dropout è comprovato
0, 1
tecnica che riduce l'overfitting. Keras fornisce un livello di esclusione che puoi aggiungere
ai tuoi modelli.

0
Yarin, Ghahramani e Zoubin. Un'applicazione teoricamente fondata di Dropout in
Reti neurali ricorrenti.5 ottobre 2016.
ttps: //arxiv.org/abs/1512.05287 .

1
Srivastava, Nitish, Geoffrey Hinton, Alex Krizhevsky, Ilya Sutskever e Ruslan
Salakhutdinov. Dropout: un modo semplice per impedire l'overfitting delle reti neurali.
Journal of Machine Learning Research 15 (14 giugno 2014): 19291958.

ttp: //jmlr.org/papers/volume15/srivastava14a/srivastava14a.pdf .

recurrent_dropout: la percentuale di neuroni da disabilitare in modo casuale quando il livello è


l'output viene reinserito nuovamente nel livello per consentire alla rete di apprendere da ciò che ha visto
in precedenza.

I meccanismi di come il livello LSTM svolge il suo compito esulano dallo scopo di questo libro.
Chollet dice: “non è necessario capire nulla dell'architettura specifica di un file
Cellula LSTM; come essere umano, non dovrebbe essere il tuo lavoro capirlo. Tieni a mente ciò che il file
2
La cella LSTM ha lo scopo di: consentire la reiniezione delle informazioni passate in un secondo momento. "

87C
7h
K
Chollet, François. Apprendimento profondo con Python . p. 204. Shelter Island, NY: Manning Pagina 721
Pubblicazioni, 2018.

Aggiunta di un livello di output denso

Infine, dobbiamo prendere l'output del livello LSTM e ridurlo a un risultato che indica
se una recensione è positiva o negativa, quindi il valore 1 per l'argomento unità. Qui noi
3
utilizzare la funzione di attivazione "sigmoide" , preferita per la classificazione binaria. It

riduce i valori arbitrari nell'intervallo 0,0–1,0, producendo una probabilità:

3
Chollet, François. Apprendimento profondo con Python . p.114. Shelter Island, NY: Manning
Pubblicazioni, 2018.

lecca qui per visualizzare l'immagine del codice

[31]: rnn.add (Dense (unità = 1 , attivazione = 'sigmoid' ))

Compilazione del modello e visualizzazione del riepilogo

Successivamente, compiliamo il modello. In questo caso, ci sono solo due possibili uscite, quindi usiamo il
funzione di perdita binary_crossentropy :

lecca qui per visualizzare l'immagine del codice

[32]: rnn.compile (optimizer = 'adam' ,


loss = 'binary_crossentropy' ,
metriche = [ "accuratezza" ])
Quello che segue è il riepilogo del nostro modello. Nota che anche se abbiamo meno livelli

rispetto al nostro convnet, l'RNN ha quasi il triplo di parametri addestrabili (il


i pesi della rete) in quanto convnet e più parametri significano più tempo di formazione.Il grande
numero di parametri deriva principalmente dal numero di parole nel vocabolario (we
caricato 10.000) volte il numero di neuroni nell'output del livello di incorporamento (128):

lecca qui per visualizzare l'immagine del codice

[33]: rnn.summary ()
_________________________________________________________________
Livello (tipo) Parametro forma di output #
================================================== ===============
embedding_1 (Embedding) (Nessuno, 200, 128) 1280000
_________________________________________________________________
lstm_1 (LSTM) (Nessuno, 128) 131584
_________________________________________________________________
dense_1 (Dense) (Nessuno, 1) 129
================================================== ===============
Parametri totali: 1.411.713
Parametri addestrabili: 1.411.713
Parametri non addestrabili: 0

15.9.5 Formazione e valutazione del modello

8C
828

4
Addestriamo il nostro modello. Nota per ogni epoca in cui il modello impiega molto più tempo Pagina 722
treno rispetto al nostro convnet. Ciò è dovuto al maggior numero di parametri (pesi) nostri
Il modello RNN deve imparare. Abbiamo evidenziato l'accuratezza (acc) e l'accuratezza della convalida
(val_acc) valori per la leggibilità: rappresentano la percentuale di campioni di addestramento e l'estensione
percentuale di campioni validation_data che il modello prevede correttamente.

4
Al momento della stesura di questo documento, TensorFlow ha visualizzato un avviso quando lo abbiamo eseguito
dichiarazione. Questo è un problema noto di TensorFlow e, secondo i forum, puoi tranquillamente
ignorare l'avvertimento.

lecca qui per visualizzare l'immagine del codice

[34]: rnn.fit (X_train, y_train, epochs = 10 , batch_size = 32 ,


validation_data = (X_test, y_test))
Addestramento su 25000 campioni, convalida su 5000 campioni
Epoca 1/5
25000/25000 [==============================] 299 s 12 ms / perdita di passo: 0,6574
poch 2/5
25000/25000 [==============================] 298 s 12 ms / perdita di passo: 0,4577
poch 3/5
25000/25000 [==============================] 296 s 12 ms / perdita di passo: 0,3277
poch 4/5
25000/25000 [==============================] 307 s 12 ms / perdita di passo: 0,2675
poch 5/5
25000/25000 [==============================] 310 s 12 ms / perdita di passo: 0,2217
34]: <oggetto tensorflow.python.keras.callbacks.History su 0xb3ba882e8>

Infine, possiamo valutare i risultati utilizzando i dati del test. La funzione valuta restituisce la perdita
e valori di precisione. In questo caso, il modello era preciso all'85,99%:

lecca qui per visualizzare l'immagine del codice

[35]: risultati = rnn.evaluate (X_test, y_test)


20000/20000 [==============================] 42 s 2 ms / passo

[36]: risultati
[36]: [0,3415240607559681, 0,8599]

Si noti che l'accuratezza di questo modello sembra bassa rispetto ai risultati del nostro convnet MNIST,
ma questo è un problema molto più difficile. Se cerchi online altri sentimenti IMDb
analisi binaryclassification studi, troverai molti risultati negli anni '80. Così abbiamo fatto

abbastanza bene con la nostra piccola rete neurale ricorrente di soli tre strati. Tu potresti volere
studiare alcuni modelli online e cercare di produrre un modello migliore.

15.10 MESSA A PUNTO DEI MODELLI DI APPRENDIMENTO PROFONDO


Nel sezione 15.9.5 , si noti nell'output del metodo di adattamento che sia l'accuratezza del test (85,99%)
e l'accuratezza della convalida (87,04%) erano significativamente inferiori alla precisione dell'addestramento del 90,83%.
Tali disparità sono solitamente il risultato di un overfitting, quindi c'è molto spazio per
5, 6
miglioramento nel nostro modello. Se guardi l'output di ogni epoca, noterai sia il file
la precisione della formazione e della convalida continua ad aumentare.Ricorda quella formazione per troppi

C
8S
[
E

i poch possono portare a overfitting, ma è possibile che non ci siamo ancora addestrati abbastanza. Forse uno Pagina 723
L'opzione di ottimizzazione degli iperparametri per questo modello consiste nell'aumentare il numero di epoche.

5
ttps: //towardsdatascience.com/deeplearningoverfitting

46bf5b35e24 .

6
ttps: //hackernoon.com/memorizingisnotlearning6tricksto

reventoverfittinginmachinelearning820b091dc42 .

Alcune variabili che influenzano le prestazioni dei tuoi modelli includono:

avere più o meno dati con cui allenarsi

avere più o meno con cui testare

avere più o meno con cui convalidare

avere più o meno strati

i tipi di strati che usi

l'ordine degli strati

Nel nostro esempio IMDb RNN, alcune cose che potremmo mettere a punto includono:

provando quantità diverse di dati di addestramento: abbiamo utilizzato solo le prime 10.000 parole

numero diverso di parole per recensione: ne abbiamo usati solo 200,

diversi numeri di neuroni nei nostri strati,

più strati o

possibilmente caricare vettori di parole preaddestrati piuttosto che far apprendere il nostro livello di incorporamento
da zero.

Il tempo di elaborazione richiesto per addestrare i modelli più volte è significativo, quindi, nel deep learning,
generalmente non si regolano gli iperparametri con tecniche come la convalida incrociata kfold o
7 8 9 0 1
ricerca sulla griglia . Esistono varie tecniche di accordatura,,,, ma una particolarmente promettente
2
l'area è l'apprendimento automatico automatico (AutoML). Ad esempio, la libreria AutoKeras è
specificatamente orientato alla scelta automatica delle migliori configurazioni per i tuoi modelli Keras.
Cloud AutoML di Google e EZDL di Baidu sono tra le varie altre macchine automatizzate
sforzi di apprendimento.

7
ttps: //www.quora.com/Iscrossvalidationheavilyusedindeep

earningorisittooexpensivetobeused .

8
ttps: //towardsdatascience.com/whatarehyperparametersandhowto
unethehyperparametersinadeepneuralnetworkd0604917584a .

lp8e
89th

9
ttps: //medium.com/machinelearningbites/deeplearningseriesdeep Pagina 724
euralnetworkstuningandoptimization39250ff7786d .

0
ttps: //flyyufelix.github.io/2016/10/03/finetuninginkeras
art1.html e ttps: //flyyufelix.github.io/2016/10/08/finetuningin
eraspart2.html .

1
ttps: //towardsdatascience.com/acomprehensiveguideonhowto
finetunedeepneuralnetworksusingkerasongooglecolabfree
aaaa0aced8f .

2
ttps: //autokeras.com/ .

5.11 MODELLI CONVNET PRETRAINATI SU IMAGENET


Con il deep learning, invece di iniziare da zero ogni progetto con costose formazioni, convalidare
e test, puoi utilizzare modelli di reti neurali profonde pre-addestrati per:

fare nuove previsioni,

continuare ad addestrarli ulteriormente con nuovi dati o

trasferire i pesi appresi da un modello per un problema simile in un nuovo modello: questo è
chiamato transfer learning .

Modelli Convnet pre-addestrati di Keras


3
Keras viene fornito in bundle con i seguenti modelli di convnet pre-addestrati, ciascuno pre-addestrato
4
ImageNet: un set di dati in crescita di oltre 14 milioni di immagini:

3
ttps: //keras.io/applications/ .

4
ttp: //www.imagenet.org .

Xception

VGG16

VGG19

ResNet50

Inception v3

InceptionResNet v2

MobileNet v1

DenseNet

NASNet

1
98h
d
npK
MobileNet v2 Pagina 725

Riutilizzo di modelli pre-addestrati

ImageNet è troppo grande per una formazione efficiente sulla maggior parte dei computer, quindi la maggior parte delle persone è interessata
usandolo inizia con uno dei modelli più piccoli pre-addestrati.

Puoi riutilizzare solo l'architettura di ogni modello e addestrarla con nuovi dati, oppure puoi riutilizzarla
i pesi pre-addestrati. Per alcuni semplici esempi, vedere:

ttps: //keras.io/applications/

ImageNet Challenge

Nei progetti endofchapter, ricercherete e utilizzerete alcuni di questi modelli in bundle. Tu


indagare anche sulla sfida del riconoscimento visivo su larga scala ImageNet per la valutazione
5
modelli di rilevamento di oggetti e di riconoscimento delle immagini . Questa competizione si è svolta dal 2010 fino al

2017. ImageNet ha ora una sfida continua sul sito della competizione Kaggle
6
chiamato ImageNet Object Localization Challenge . L'obiettivo è identificare “tutti gli oggetti
all'interno di un'immagine, in modo che tali immagini possano essere classificate e annotate. " Rilasci di ImageNet
la classifica dei partecipanti attuali una volta al trimestre.

5
ttp: //www.imagenet.org/challenges/LSVRC/ .

6
TTP: //www.kaggle.com/c/imagenetobjectlocalizationchallenge .

Molto di ciò che hai visto nei capitoli di machine learning e deep learning è ciò che il
Il sito web della competizione Kaggle è tutto. Non esiste una soluzione ottimale ovvia per molti
attività di machine learning e deep learning. La creatività delle persone è davvero l'unico limite. Sopra
Kaggle, aziende e organizzazioni finanziano concorsi in cui incoraggiano le persone
in tutto il mondo per sviluppare soluzioni dalle prestazioni migliori di quelle che sono stati in grado di fare per qualcosa
questo è importante per la loro azienda o organizzazione. A volte le aziende offrono premi in denaro,
che è stato di $ 1.000.000 sul famoso concorso Netflix. Netflix voleva
ottenere un miglioramento del 10% o superiore nel proprio modello per determinare se alle persone piacerà un
7
film, in base a come hanno valutato i precedenti. Hanno usato i risultati per contribuire a migliorare
raccomandazioni ai membri. Anche se non vinci una competizione Kaggle, è un ottimo modo
acquisire esperienza lavorando su problemi di interesse attuale.

7
ttps: //netflixprize.com/rules.html .

15.12 WRAP-UP
Nel nel capitolo 16 , hai sbirciato nel futuro dell'IA. Il deep learning ha catturato l'immaginazione
delle comunità di informatica e scienza dei dati. Questa potrebbe essere l'IA più importante
capitolo del libro.

Abbiamo menzionato le principali piattaforme di deeplearning, indicando che TensorFlow di Google è il


più ampiamente utilizzato. Abbiamo discusso perché Keras, che presenta un'interfaccia amichevole per

TensorFlow, è diventato così popolare.

9C
hh
abbiamo impostato un ambiente Anaconda personalizzato per TensorFlow, Keras e JupyterLab, quindi utilizzato Pagina 726
l'ambiente per implementare gli esempi di Keras.

Abbiamo spiegato cosa sono i tensori e perché sono fondamentali per l'apprendimento profondo. Abbiamo discusso di
nozioni di base sui neuroni e sulle reti neurali multistrato per costruire il deeplearning di Keras
Modelli. Abbiamo considerato alcuni tipi popolari di livelli e come ordinarli.

Abbiamo introdotto reti neurali convoluzionali (convnet) e abbiamo indicato che sono particolarmente
adatto per applicazioni di computervision. Abbiamo quindi costruito, formato, convalidato e testato un file
convnet utilizzando il database MNIST di cifre scritte a mano per il quale abbiamo raggiunto il 99,17%
accuratezza della previsione. Questo è notevole, dato che ci siamo riusciti lavorando con un solo a
modello base e senza eseguire alcuna regolazione degli iperparametri. Puoi provare più sofisticato
modelli e sintonizzare gli iperparametri per cercare di ottenere prestazioni migliori. Abbiamo elencato un file

varietà di attività di visione artificiale intriganti.

Abbiamo introdotto TensorBoard per visualizzare l'addestramento alla rete neurale di TensorFlow e Keras
e convalida. Abbiamo anche discusso di ConvnetJS, una formazione convnet basata su browser e
strumento di visualizzazione, che consente di sbirciare all'interno del processo di formazione.

Successivamente, abbiamo presentato reti neurali ricorrenti (RNN) per l'elaborazione di sequenze di dati, come

come serie temporali o testo in frasi. Abbiamo utilizzato un RNN con il set di dati delle recensioni dei film di IMDb per
eseguire la classificazione binaria, prevedendo se il sentiment di ciascuna recensione era positivo o
negativo. Abbiamo anche discusso dell'ottimizzazione dei modelli di deep learning e delle prestazioni elevate
hardware, come le GPU di NVIDIA e le TPU di Google, lo stanno rendendo possibile a più persone
affrontare studi più approfonditi sull'apprendimento approfondito.

Considerato quanto sia costoso e dispendioso in termini di tempo addestrare modelli di deeplearning, abbiamo spiegato il

strategia di utilizzo di modelli pre-addestrati. Abbiamo elencato vari processi di elaborazione delle immagini Convnet di Keras
modelli che sono stati addestrati sull'enorme set di dati ImageNet e hanno discusso come trasferire
l'apprendimento consente di utilizzare questi modelli per crearne di nuovi in ​modo rapido ed efficace.In profondità
l'apprendimento è un argomento ampio e complesso. Ci siamo concentrati sulle basi nel capitolo.

Nel prossimo capitolo, presentiamo l'infrastruttura di big data che supporta i tipi di AI
tecnologie di cui abbiamo discusso hapters 12 attraverso 5 . Considereremo Hadoop e Spark

piattaforme per l'elaborazione in batch di big data e applicazioni di streaming in tempo reale.Vedremo
database relazionali e il linguaggio SQL per interrogarli: questi hanno dominato il
campo del database per molti decenni. Discuteremo di come i big data presentano sfide che
i database relazionali non si gestiscono bene e considera come sono progettati i database NoSQL
gestire queste sfide. Concluderemo il libro con una discussione sull'Internet of Things
(IoT), che sarà sicuramente la più grande fonte di bigdata al mondo e ne presenterà molti
opportunità per gli imprenditori di sviluppare attività all'avanguardia che faranno davvero a

differenza nella vita delle persone.


https://avxhm.se/blogs/hill0

1
C
W
Pagina 727

le liste

tory
16. Big Data: Hadoop, Spark, NoSQL e IoT
foto
Obiettivi

In questo capitolo potrai:


rning Pat

Comprendi cosa sono i big data e quanto velocemente si stanno ingrandendo.


ers & Dea

Manipola un database relazionale SQLite utilizzando SQL (Structured Query Language).


hlights

Comprendi i quattro principali tipi di database NoSQL.


cose

Archivia i tweet in un database di documenti JSON NoSQL di MongoDB e visualizzali su un file


Supporto Mappa di Folium.

Disconnessione Comprendere Apache Hadoop e come viene utilizzato nelle applicazioni di elaborazione batch di bigdata.

Crea un'applicazione Hadoop MapReduce sul servizio cloud Azure HDInsight di Microsoft.

Comprendi Apache Spark e come viene utilizzato nei bigdata in tempo reale e ad alte prestazioni
applicazioni.

Usa Spark streaming per elaborare i dati in minibatch.

Comprendere l'Internet of Things (IoT) e il modello di pubblicazione / sottoscrizione.

Pubblica messaggi da un dispositivo connesso a Internet simulato e visualizza i suoi messaggi in formato
un cruscotto.

Iscriviti agli stream live su Twitter e IoT di PubNub e visualizza i dati.

contorno

6.1 Introduzione

6.2 Database relazionali e SQL (Structured Query Language)

6.3.1 Un database di libri

6.3.2 SELEZIONA query

6.3.3 Clausola WHERE

6.3.4 Clausola ORDER BY

6.3.5 Unione di dati da più tabelle: INNER JOIN

6.3.6 Istruzione INSERT INTO Pagina 728

16.3.7 Istruzione UPDATE

16.3.8 Istruzione DELETE FROM

6.3 Database NoSQL e NewSQL BigData: una breve panoramica

6.3.1 Database valori-chiave NoSQL


6.3.2 Database di documenti NoSQL

6.3.3 Database a colonne NoSQL

6.3.4 Database grafici NoSQL

6.3.5 Database NewSQL

6.4 Case Study: un database di documenti JSON MongoDB

6.4.1 Creazione del MongoDB Atlas Cluster

6.4.2 Streaming di tweet in MongoDB

6.5 Hadoop

6.5.1 Panoramica di Hadoop

6.6.2 Riassumere le lunghezze delle parole in Romeo e Giulietta tramite MapReduce

6.5.3 Creazione di un cluster Apache Hadoop in Microsoft Azure HDInsight

6.5.4 Streaming Hadoop

6.5.5 Implementazione del Mapper

6.5.6 Implementazione del riduttore

6.5.7 Preparazione per eseguire l'esempio di MapReduce

6.5.8 Esecuzione del lavoro MapReduce

6.6 Spark

6.6.1 Panoramica di Spark

6.6.2 Docker e gli stack Docker di Jupyter

6.6.3 Conteggio parole con Spark

6.6.4 Conteggio parole Spark su Microsoft Azure

6.7 Spark Streaming: conteggio hashtag Twitter utilizzando il Docker pysparknotebook


virata

1
S

6.7.1 Streaming di tweet su un socket Pagina 729

6.7.2 Riepilogo degli hashtag dei Tweet; Presentazione di Spark SQL

6.8 Internet delle cose e dashboard

6.8.1 Pubblica e Sottoscrivi

6.8.2 Visualizzazione di un live streaming di esempio PubNub con un dashboard di Freeboard

6.8.3 Simulare un termostato connesso a Internet in Python

6.8.4 Creazione del dashboard con Freeboard.io

6.8.5 Creazione di un abbonato a Python PubNub

6.9 WrapUp

16.1 INTRODUZIONE
Nel sezione 1.7 , abbiamo introdotto i big data. In questo capitolo fondamentale, discuteremo dell'hardware popolare
e infrastruttura software per lavorare con i big data e sviluppiamo applicazioni complete
su diverse piattaforme bigdata desktop e basate su cloud.

Banche dati
I database sono un'infrastruttura bigdata fondamentale per l'archiviazione e la manipolazione dell'enorme
quantità di dati che stiamo creando. Sono anche fondamentali per la sicurezza e la riservatezza
mantenere tali dati, soprattutto nel contesto di leggi sulla privacy sempre più restrittive come l' HIPAA
(Health Insurance Portability and Accountability Act) negli Stati Uniti e
GDPR (General Data Protection Regulation) per l'Unione Europea.

Innanzitutto, presenteremo i database relazionali , che memorizzano i dati strutturati in tabelle con estensione
numero fisso di colonne per riga. Manipolerai i database relazionali tramite
SQL (Structured Query Language) .

La maggior parte dei dati prodotti oggi sono dati non strutturati , come il contenuto dei post di Facebook e
Tweet di Twitter o dati semistrutturati come documenti JSON e XML. Processi di Twitter
il contenuto di ogni tweet in un documento JSON semistrutturato con molti metadati , come te
visto nel capitolo "Data mining Twitter". I database relazionali non sono adatti a
dati non strutturati e semistrutturati in applicazioni bigdata. Quindi, con l'evoluzione dei big data, nuovi
sono stati creati tipi di database per gestire tali dati in modo efficiente. Discuteremo i quattro principali
tipi di questi database NoSQL: database chiave-valore, documenti, colonne e grafici.
Inoltre, faremo una panoramica dei database NewSQL , che uniscono i vantaggi di relazionale e NoSQL
banche dati. Molti fornitori di NoSQL e NewSQL rendono facile iniziare con i loro prodotti
tramite livelli gratuiti e prove gratuite e in genere in ambienti basati su cloud che richiedono
installazione e configurazione minime. Ciò rende pratico acquisire esperienza con bigdata
prima di "tuffarsi".

Apache Hadoop

La maggior parte dei dati odierni è così grande da non poter essere contenuta in un unico sistema.Man mano che i big data crescevano, avevamo bisogno

1S

capacità di archiviazione dati e di elaborazione parallela distribuite per elaborare maggiormente i dati
Pagina 730
in modo efficiente. Ciò ha portato a tecnologie complesse come Apache Hadoop per i dati distribuiti
elaborazione con enorme parallelismo tra i cluster di computer in cui i dettagli intricati
vengono gestiti automaticamente e correttamente. Discuteremo di Hadoop, la sua architettura e
come viene utilizzato nelle applicazioni bigdata. Ti guideremo nella configurazione di un multinode
Cluster Hadoop usando il servizio cloud Microsoft Azure HDInsight, quindi usalo per eseguire un file
Processo Hadoop MapReduce che implementerai in Python. Sebbene HDInsight non sia gratuito,
Microsoft ti offre un generoso credito newaccount che dovrebbe consentirti di eseguire il file
esempi di codice del capitolo senza incorrere in costi aggiuntivi.

Apache Spark

Man mano che le esigenze di elaborazione dei bigdata crescono, la comunità della tecnologia dell'informazione è continuamente
alla ricerca di modi per aumentare le prestazioni. Hadoop esegue le attività suddividendole in file
componenti che eseguono molte operazioni di I / O del disco su molti computer.Spark è stato sviluppato come un modo per
eseguire alcune attività bigdata in memoria per prestazioni migliori.

Discuteremo di Apache Spark, della sua architettura e di come viene utilizzato ad alte prestazioni, in tempo reale
applicazioni bigdata. Implementerai un'applicazione Spark usando lo stile funzionale
filtrare / mappare / ridurre le capacità di programmazione. Per prima cosa, costruirai questo esempio usando un Jupyter
Stack Docker che viene eseguito localmente sul tuo computer desktop, quindi lo implementerai utilizzando un file
cluster Spark multinodo Microsoft Azure HDInsight basato su cloud.

Introdurremo lo streaming Spark per l'elaborazione di dati in streaming in minibatch.Scintilla


lo streaming raccoglie i dati per un breve intervallo di tempo specificato, quindi ti fornisce quel batch di dati
processare. Implementerai un'applicazione di streaming Spark che elabora i tweet.In ciò
ad esempio, utilizzerai Spark SQL per eseguire query sui dati archiviati in un DataFrame Spark che, a differenza di
pandas DataFrames, può contenere dati distribuiti su molti computer in un cluster.

Internet delle cose

Concluderemo con un'introduzione all'Internet of Things (IoT): miliardi di dispositivi che


producono continuamente dati in tutto il mondo. Introdurremo il modello di pubblicazione / sottoscrizione
che l'IoT e altri tipi di applicazioni utilizzano per connettere gli utenti di dati con i fornitori di dati.Primo,
senza scrivere alcun codice, costruirai una dashboard basata sul web usando Freeboard.io e un file
esempio di live streaming dal servizio di messaggistica PubNub.Successivamente, simulerai un Internet
termostato connesso che pubblica messaggi al servizio di messaggistica gratuito Dweet.io utilizzando
il modulo Python Dweepy, quindi crea una visualizzazione dashboard dei dati con
Freeboard.io. Infine, creerai un client Python che si abbona a un live streaming di esempio da
il servizio PubNub e visualizza dinamicamente il flusso con Seaborn e un Matplotlib
FuncAnimation.

Prova il software per big data cloud e desktop

I fornitori di cloud si concentrano sulla tecnologia SOA (Service Oriented Architecture) in cui operano
fornire funzionalità "asaService" a cui le applicazioni si connettono e utilizzano nel cloud. Comune
1
i servizi forniti dai fornitori di cloud includono:

1
Per ulteriori acronimi asaService, vedere

ttps: //en.wikipedia.org/wiki/Cloud_computing e
ttps: //en.wikipedia.org/wiki/As_a_service .

dh
Pagina 731
Acronimi "AsaService" (tieni presente che diversi sono uguali)

Big Data as a Service (BDaaS) Platform as a Service (PaaS)

Hadoop as a Service (HaaS) Software as a Service (SaaS)

Hardware as a Service (HaaS) Storage as a Service (SaaS)

Infrastructure as a Service (IaaS) Spark as a Service (SaaS)

In questo capitolo acquisirai esperienza pratica con diversi strumenti basati su cloud. In questo
esempi del capitolo, utilizzerai le seguenti piattaforme:

Un cluster MongoDB Atlas basato su cloud gratuito .

Un cluster Hadoop multinodo in esecuzione su Azure HDInsight basato su cloud di Microsoft


servizio: per questo utilizzerai il credito fornito con un nuovo account Azure.

Un "cluster" Spark singlenode gratuito in esecuzione sul tuo computer desktop, utilizzando un Jupyter
Contenitore Dockerstack.

Un cluster Spark multinodo, anch'esso in esecuzione su Azure HDInsight di Microsoft, per questo lo farai
continuare a utilizzare il credito del nuovo account Azure .

Sono disponibili molte altre opzioni, inclusi i servizi basati su cloud di Amazon Web Services,
Google Cloud e IBM Watson e le versioni desktop gratuite di Hortonworks e
Piattaforme Cloudera (esistono anche versioni a pagamento basate su cloud di queste). Puoi anche provare un file
cluster Spark singlenode in esecuzione sulla Databricks Community Edition gratuita basata su cloud.
I creatori di Spark hanno fondato Databricks.

Controlla sempre i termini e le condizioni più recenti di ogni servizio che utilizzi.Alcuni
richiedono di abilitare la fatturazione con carta di credito per utilizzare i loro cluster. Attenzione: una volta che tu
allocare cluster Microsoft Azure HDInsight (o cluster di altri fornitori), essi
sostenere dei costi. Quando completi i casi di studio utilizzando servizi come
Microsoft Azure, assicurati di eliminare i tuoi cluster e le loro altre risorse (come
Conservazione). Ciò contribuirà a prolungare la durata del credito del tuo nuovo account Azure.

L'installazione e le configurazioni variano a seconda delle piattaforme e nel tempo. Segui sempre quello di ogni venditore
ultimi passaggi. In caso di domande, le migliori fonti di aiuto sono il supporto del fornitore
capacità e forum. Inoltre, controlla siti come stackoverflow.com, altri potrebbero farlo
hanno posto domande su problemi simili e ricevuto risposte dallo sviluppatore
Comunità.

Algoritmi e dati
Algoritmi e dati sono il cuore della programmazione Python. I primi capitoli di questo libro
riguardavano principalmente algoritmi. Abbiamo introdotto le istruzioni di controllo e discusso l'algoritmo
sviluppo. I dati erano piccoli, principalmente singoli interi, float e stringhe. hapters 5 -

C
Pagina 732
ha enfatizzato la strutturazione dei dati in elenchi, tuple, dizionari, set, array e file.

Il significato di Data
Ma che dire del significato dei dati? Possiamo utilizzare i dati per ottenere informazioni migliori
diagnosticare i tumori? Salvare vite? Migliorare la qualità della vita dei pazienti? Ridurre l'inquinamento? Conserva
acqua? Aumentare i raccolti? Ridurre i danni da tempeste e incendi devastanti? Sviluppare
regimi di trattamento migliori? Creare posti di lavoro? Migliorare la redditività aziendale?
Gli studi di casi di datascience di hapters 11 - 5 tutti incentrati sull'intelligenza artificiale. In questo capitolo ci concentriamo su
l'infrastruttura bigdata che supporta le soluzioni AI. Poiché i dati utilizzati con questi
le tecnologie continuano a crescere in modo esponenziale, vogliamo imparare da quei dati e farlo a
velocità incredibile. Raggiungeremo questi obiettivi con una combinazione di sofisticati algoritmi,
hardware, software e progetti di rete. Abbiamo presentato vari machinelearning
tecnologie, visto che ci sono davvero grandi intuizioni da estrarre dai dati.Con più
dati, e soprattutto con i big data, l'apprendimento automatico può essere ancora più efficace.

Fonti di Big Data


I seguenti articoli e siti forniscono collegamenti a centinaia di origini di Big Data gratuite:

Fonti igdata

"AwesomePublicDatasets", GitHub.com,
TTP: //github.com/caesar0301/awesomepublicdatasets .

" Set di dati pubblici AWS", ttps: //aws.amazon.com/publicdatasets/ .

"Big Data and AI: 30 stupefacenti (e gratuite) fonti di dati pubblici per il 2018", di B. Marr,
ttps: //www.forbes.com/sites/bernardmarr/2018/02/26/bigdataandai30
mazingandfreepubblicofonti di dati per il 2018 / .

"Set di dati per il data mining e la scienza dei dati",


ttp: //www.kdnuggets.com/datasets/index.html .

"Exploring Open Data Sets", ttps: //datascience.berkeley.edu/opendata

ets / .

"Free Big Data Sources", Datamics, ttp: //datamics.com/freebigdatasources/

Hadoop Illuminated , capitolo 16 . Big Data Set disponibili pubblicamente,


ttp: //hadoopilluminated.com/hadoop_illuminated/Public_Bigdata_Sets.html

9
1C
Pagina 733

Elenco delle origini dati pubbliche adatte al machine learning "


ttps: //blog.bigml.com/listofpublicdatasourcesfitformachine
guadagnare / .

"Open Data", Wikipedia, ttps: //en.wikipedia.org/wiki/Open_data .

"Open Data 500 Companies", ttp: //www.opendata500.com/us/list/ .

"Altre risorse interessanti / Big Data e analisi delle risorse educative e


Research ", B. Marr, ttp: //computing.derby.ac.uk/bigdatares/? Page_id = 223

"6 fantastiche fonti di dati per la pratica",


ttps: //www.jigsawacademy.com/6amazingsourcesofpracticedatasets/

"20 archivi di Big Data da controllare", M. Krivanek,


ttp: //www.datasciencecentral.com/profiles/blogs/20freebigdata
ourceseveryoneshouldcheckout .
"Oltre 70 siti web per ottenere gratuitamente archivi di dati di grandi dimensioni"

ttp: //bigdatamadesimple.com/70websitestogetlargedata
epositoryforfree / .

"Ten Sources of Free Big Data on Internet", A. Brown,


ttps: //www.linkedin.com/pulse/tensourcesfreebigdatainternetalan
rown .

"Prime 20 origini dati aperte",


ttps: //www.linkedin.com/pulse/top20opendatasourceszygimantas

acikevicius .

"Stiamo impostando dati, codice e API liberi", NASA, ttps: //open.nasa.gov/open

ata / .

"Dove posso trovare grandi set di dati aperti al pubblico?"Quora,


ttps: //www.quora.com/WherecanIfindlargedatasetsopentothepublic

Pagina 734

6.2 DATABASE RELAZIONALI E QUERY STRUTTURATA


LINGUA (SQL)
I database sono fondamentali, soprattutto per i big data. Nel nel capitolo 9 , abbiamo dimostrato il testo sequenziale
elaborazione di file, utilizzo di dati da file CSV e utilizzo di JSON.Entrambi sono utili
quando la maggior parte o tutti i dati di un file devono essere elaborati. D'altra parte, nella transazione
elaborazione abbiamo bisogno di individuare e, possibilmente, aggiornare rapidamente un singolo elemento di dati.

Un database è una raccolta integrata di dati. Un sistema di gestione del database


(DBMS) fornisce meccanismi per l'archiviazione e l'organizzazione dei dati in modo coerente con
il formato del database. I sistemi di gestione del database consentono un accesso conveniente e
archiviazione dei dati senza preoccupazione per la rappresentazione interna delle banche dati.

I sistemi di gestione dei database relazionali ( RDBMS ) archiviano i dati in tabelle e li definiscono
rapporti tra i tavoli. Il linguaggio SQL (Structured Query Language) è utilizzato quasi universalmente
con sistemi di database relazionali per manipolare i dati ed eseguire query , che richiedono
2
informazioni che soddisfano determinati criteri.

2
La scrittura in questo capitolo presume che SQL sia pronunciato come seequel. Alcuni preferiscono ess
que el.

Popolari opensource RDBMS includono SQLite, PostgreSQL, MariaDB e MySQL. Questi possono
essere scaricato e utilizzato liberamente da chiunque. Tutti hanno il supporto per Python. Useremo SQLite,
che è in bundle con Python. Alcuni RDBMS proprietari popolari includono Microsoft SQL
Server, Oracle, Sybase e IBM Db2.

Tabelle, righe e colonne


Un database relazionale è una rappresentazione dei dati basata su una tabella logica che consente ai dati di essere
accessibile senza considerare la sua struttura fisica.Il diagramma seguente mostra un file
tabella Employee di esempio che potrebbe essere utilizzata in un sistema del personale:

Lo scopo principale della tabella è memorizzare gli attributi dei dipendenti. Le tabelle sono composte da righe ,
ognuno descrive una singola entità. Ogni riga rappresenta un dipendente. Le righe sono composte
di colonne contenenti singoli valori di attributo.La tabella sopra ha sei righe. Il
La colonna Numero rappresenta la chiave primaria: una colonna (o gruppo di colonne) con un valore
è unico per ogni riga. Ciò garantisce che ogni riga possa essere identificata dalla sua chiave primaria.
Esempi di chiavi primarie sono i numeri di previdenza sociale, i numeri ID dei dipendenti e la parte
numeri in un sistema di inventario: i valori in ciascuno di questi sono garantiti come univoci.In questo
caso, le righe sono elencate in ordine crescente in base alla chiave primaria, ma potrebbero essere elencate in

1C
ordine discendente o nessun ordine particolare. Pagina 735

Ogni colonna rappresenta un diverso attributo di dati. Le righe sono univoche (per chiave primaria) all'interno di un file
tabella, ma valori di colonna particolari possono essere duplicati tra le righe.Ad esempio, tre
righe diverse nella colonna Reparto della tabella Employee contengono il numero 413.

Selezione di sottoinsiemi di dati

Utenti di database diversi sono spesso interessati a dati e relazioni diverse


tra i dati. La maggior parte degli utenti richiede solo sottoinsiemi di righe e colonne. Le query specificano
quali sottoinsiemi di dati selezionare da una tabella. Si utilizza SQL (Structured Query Language) per
definire le query. Ad esempio, potresti selezionare i dati dalla tabella Employee per creare un risultato
che mostra dove si trova ogni reparto, presentando i dati ordinati in ordine crescente
per numero di reparto. Questo risultato è mostrato di seguito. Discuteremo brevemente di SQL.

lecca qui per visualizzare l'immagine del codice

Ubicazione del dipartimento


413 New Jersey
611 Orlando
642 Los Angeles

SQLite
Gli esempi di codice nel resto di Sezione 16.2 utilizzare il database SQLite opensource
sistema di gestione incluso in Python, ma i sistemi di database più diffusi lo hanno
Supporto per Python. Ciascuno fornisce tipicamente un modulo che aderisce al database di Python
Application Programming Interface (DBAPI) , che specifica l'oggetto comune e
nomi di metodi per manipolare qualsiasi database.

16.2.1 Un database di libri

In questa sezione presenteremo un database di libri contenente informazioni su molti dei nostri
libri. Configureremo il database in SQLite tramite sqlite3 della libreria standard Python
module , utilizzando uno script fornito nella sottocartella sql della cartella dell'esempio ch16.Quindi, lo faremo
introdurre le tabelle del database. Useremo questo database in una sessione IPython per introdurre
vari concetti di database, comprese le operazioni che creano , leggono , aggiornano e cancellano i dati
—Le cosiddette operazioni CRUD . Quando introduciamo le tabelle, useremo SQL e panda

DataFrames per mostrare i contenuti di ogni tabella. Quindi, nelle prossime sezioni, lo faremo
discutere le funzionalità SQL aggiuntive.

Creazione del database dei libri

Nel tuo Anaconda Command Prompt, Terminal o shell, passa agli esempi ch16
sottocartella sql della cartella. Il seguente comando sqlite3 crea un database SQLite denominato

books.db ed esegue lo script SQL books.sql, che definisce come creare il file
tabelle del database e le popola con i dati:

sqlite3 books.db <books.sql

La notazione <indica che books.sql viene immesso nel comando sqlite3. Quando il

C
S

comando completo, il database è pronto per l'uso. Inizia una nuova sessione IPython.
Pagina 736

Connessione al database in Python

Per lavorare con il database in Python, prima chiama la funzione di connessione di sqlite3 a cui connetterti
il database e ottenere un oggetto Connection :

lecca qui per visualizzare l'immagine del codice


In [1]: importa sqlite3

In [2]: connection = sqlite3.connect ( 'books.db' )

Tabella degli autori


Il database ha tre tabelle: autori, author_ISBN e titoli. La tabella degli autori
memorizza tutti gli autori e ha tre colonne:

id: il numero ID univoco dell'autore. Questa colonna intera è definita come


autoincrementato: per ogni riga inserita nella tabella, SQLite aumenta il valore id di
1 per garantire che ogni riga abbia un valore univoco. Questa colonna è la chiave primaria della tabella.

first: il nome dell'autore (una stringa).

last: il cognome dell'autore (una stringa).

Visualizzazione dei contenuti della tabella degli autori

Usiamo una query SQL e panda per visualizzare il contenuto della tabella degli autori:

lecca qui per visualizzare l'immagine del codice

In [3]: importa i panda come pd

In [4]: ​pd.options.display.max_columns = 10

In [5]: pd.read_sql ( 'SELECT * FROM autori' , connessione,


...: index_col = [ 'id' ])
...:
Fuori [5]:
primo ultimo
id
1 Paul Deitel
2 Harvey Deitel
3 Abbey Deitel
4 Dan Quirk
5 Alexander Wald

La funzione Pandas read_sql esegue una query SQL e restituisce un DataFrame contenente l'estensione
risultati della query. Gli argomenti della funzione sono:

una stringa che rappresenta la query SQL da eseguire,

l'oggetto Connection del database SQLite e, in questo caso

un argomento della parola chiave index_col che indica quale colonna deve essere utilizzata come Pagina 737

Indici di riga di DataFrame (i valori id dell'autore in questo caso).

Come vedrai tra poco, quando index_col non viene passato, i valori di indice iniziano da 0
appaiono a sinistra delle righe del DataFrame.

Una query SQL SELECT ottiene righe e colonne da una o più tabelle in un database. Nel
domanda:

SELEZIONA * DA autori

l' asterisco (*) è un carattere jolly che indica che la query deve ottenere tutte le colonne dal file

tabella autori. Discuteremo a breve le query SELECT in modo più dettagliato.

Tabella dei titoli


La tabella dei titoli memorizza tutti i libri e ha quattro colonne:

isbn: l'ISBN del libro (una stringa) è la chiave primaria di questa tabella. ISBN è un'abbreviazione di
"International Standard Book Number", uno schema di numerazione utilizzato dagli editori
per assegnare a ogni libro un numero di identificazione univoco.

titolo: il titolo del libro (una stringa).

edizione: il numero di edizione del libro (un numero intero).


copyright: l'anno del copyright del libro (una stringa).

Usiamo SQL e panda per visualizzare il contenuto della tabella dei titoli:

lecca qui per visualizzare l'immagine del codice

In [6]: pd.read_sql ( "SELEZIONA * DA titoli" , connessione)


Fuori [6]:
copyright dell'edizione del titolo isbn
0 0135404673 Introduzione a Python per CS e DS 1 2020
1 0132151006 Come programmare Internet e WWW 5 2012
2 0134743350 Java How to Program 11 2018
3 0133976890 C Come programmare 8 2016
4 0133406954 Visual Basic 2012 Come programmare 6 2014
5 0134601548 Visual C # How to Program 6 2017
6 0136151574 Visual C ++ How to Program 2 2008
7 0134448235 C ++ Come programmare 10 2017
8 0134444302 Come programmare Android 3 2017
9 0134289366 Android 6 per programmatori 3 2016

tabella author_ISBN
La tabella author_ISBN utilizza le seguenti colonne per associare gli autori degli autori
tabella con i loro libri nella tabella dei titoli:

id: l'ID di un autore (un numero intero).

isbn: l'ISBN del libro (una stringa).


Pagina 738

La colonna id è una chiave esterna , che è una colonna in questa tabella che corrisponde a una chiave primaria
in un'altra tabella, in particolare, la colonna id della tabella autori.La colonna isbn
è anche una chiave esterna: corrisponde alla colonna isbn primarykey della tabella dei titoli.Un database
potrebbe avere molte tabelle. Un obiettivo durante la progettazione di un database è ridurre al minimo la duplicazione dei dati
tra i tavoli. A tale scopo, ogni tabella rappresenta un'entità specifica e il collegamento alla guida delle chiavi esterne
i dati in più tabelle. Le chiavi primarie e le chiavi esterne vengono designate quando si
creare le tabelle del database (nel nostro caso, nello script books.sql).

Insieme, le colonne id e isbn in questa tabella formano una chiave primaria composta . Ogni riga
questa tabella abbina in modo univoco un autore all'ISBN di un libro. Questa tabella contiene molte voci,
quindi usiamo SQL e panda per visualizzare solo le prime cinque righe:

lecca qui per visualizzare l'immagine del codice

In [7]: df = pd.read_sql ( 'SELECT * FROM author_ISBN' , connessione)

In [8]: df.head ()
Fuori [8]:
id isbn
0 1 0134289366
1 2 0134289366
2 5 0134289366
3 1 0135404673
4 2 0135404673

Ogni valore di foreignkey deve apparire come valore di primarykey in una riga di un'altra tabella, quindi il
DBMS può garantire che il valore della chiave esterna sia valido.Questo è noto come la regola del
Integrità referenziale . Ad esempio, il DBMS garantisce che il valore id per un determinato file

La riga author_ISBN è valida controllando che sia presente una riga nella tabella autori con quell'ID
come chiave primaria.

Le chiavi esterne permettono anche relativi dati in più tabelle da scelti da quei tavoli e
combinato: questo è noto come unione dei dati. C'è una sola relazione
tra una chiave primaria e una chiave esterna corrispondente: un autore può scrivere molti libri,
e allo stesso modo un libro può essere scritto da molti autori. Quindi una chiave esterna può apparire molte
volte nella sua tabella ma solo una volta (come chiave primaria) in un'altra tabella. Ad esempio, in
database di libri, l'ISBN 0134289366 appare in diverse righe author_ISBN perché questo
il libro ha diversi autori, ma appare solo una volta come chiave primaria nei titoli.

Diagramma entità-relazione (ER)


Il seguente entityrelationship ( ER ) schema per gli spettacoli di database libri
le tabelle del database e le relazioni tra loro:
C

Il primo scomparto di ogni scatola contiene il nome del tavolo e il rimanente


Pagina 739
i compartimenti contengono le colonne della tabella. I nomi in corsivo sono le chiavi primarie. Un tavolo
la chiave primaria identifica in modo univoco ogni riga della tabella. Ogni riga deve avere una chiave primaria
valore e tale valore deve essere univoco nella tabella. Questo è noto come la regola di entità
Integrità . Di nuovo, per la tabella author_ISBN, la chiave primaria è la combinazione di entrambi
colonne: questa è nota come chiave primaria composita.

Le linee che collegano le tabelle rappresentano le relazioni tra le tabelle. Considera il


linea tra autori e author_ISBN. Alla fine dell'autore c'è un 1 e sul

author_ISBN alla fine c'è un simbolo di infinito (¥).Ciò indica una relazione unica .
Per ogni autore nella tabella degli autori, può esserci un numero arbitrario di codici ISBN per i libri
scritto da quell'autore nella tabella author_ISBN, ovvero un autore può scrivere qualsiasi numero
di libri, quindi l'ID di un autore può apparire in più righe della tabella author_ISBN. Il
la riga di relazione collega la colonna id nella tabella autori (dove id è la chiave primaria) a
la colonna id nella tabella author_ISBN (dove id è una chiave esterna).La linea tra il
tabelle collega la chiave primaria alla chiave esterna corrispondente.

La linea tra i titoli e le tabelle author_ISBN illustra una moltitudine


relazione: un libro può essere scritto da molti autori. La linea collega la chiave primaria isbn
nei titoli delle tabelle alla chiave esterna corrispondente nella tabella author_ISBN. Le relazioni
nel diagramma entityrelationship illustrare che l'unico scopo della tabella author_ISBN
è quello di fornire una relazione molte-persone tra gli autori e le tabelle dei titoli: un
l'autore può scrivere molti libri e un libro può avere molti autori.

Parole chiave SQL


Le seguenti sottosezioni continuano la nostra presentazione SQL nel contesto dei nostri libri
database, dimostrando query e istruzioni SQL utilizzando le parole chiave SQL in
tabella seguente. Altre parole chiave SQL vanno oltre lo scopo di questo testo:

SQL
Descrizione
parola chiave

Recupera i dati da una o più tabelle.


SELEZIONARE

Tabelle coinvolte nella query. Richiesto in ogni SELECT.


A PARTIRE DAL

Criteri di selezione che determinano le righe da recuperare, eliminare o


DOVE
aggiornato. Facoltativo in un'istruzione SQL.

GRUPPO
Criteri per il raggruppamento delle righe. Facoltativo in una query SELECT.
DI

ORDINE

DI Criteri per ordinare le righe. Facoltativo in una query SELECT. Pagina 740

INTERNO
Unisci righe da più tabelle.
ADERIRE
INSERIRE Inserisci righe in una tabella specificata.

Aggiorna le righe in una tabella specificata.


AGGIORNARE

ELIMINA Elimina righe da una tabella specificata.

16.2.2 SELEZIONA query

La sezione precedente utilizzava le istruzioni SELECT e il carattere jolly * per ottenere tutti i file
colonne da una tabella. In genere, è necessario solo un sottoinsieme delle colonne, soprattutto nei big data
dove potresti avere dozzine, centinaia, migliaia o più colonne. Solo per recuperare
colonne specifiche, specificare un elenco di nomi di colonne separati da virgole.Ad esempio, recuperiamo
solo la prima e l'ultima colonna della tabella autori:

lecca qui per visualizzare l'immagine del codice

In [9]: pd.read_sql ( 'SELECT first, last FROM autori' , connessione)


Fuori [9]:
primo ultimo
0 Paul Deitel
1 Harvey Deitel
2 Abbey Deitel
3 Dan Quirk
4 Alexander Wald

16.2.3 Clausola WHERE

Spesso selezionerai righe in un database che soddisfano determinati criteri di selezione , specialmente in big
dati in cui un database potrebbe contenere milioni o miliardi di righe. Solo le righe che soddisfano il
criteri di selezione (formalmente chiamati predicati ) vengono selezionati. La clausola WHERE di SQL specifica un file
criteri di selezione della query. Selezioniamo titolo, edizione e copyright per tutti i libri con
anni di copyright maggiori del 2016. I valori stringa nelle query SQL sono delimitati da un singolo (')
virgolette, come in "2016":

lecca qui per visualizzare l'immagine del codice

In [10]: pd.read_sql ( "" "SELEZIONA titolo, edizione, copyright


...: FROM titoli
...: WHERE copyright> '2016' "" " , connessione)
Fuori [10]:

C
copyright dell'edizione del titolo Pagina 741
0 Introduzione a Python per CS e DS 1 2020
1 Come programmare Java 11 2018
2 Visual C # Come programmare 6 2017
3 C ++ Come programmare 10 2017
4 Come programmare Android 3 2017

Corrispondenza pattern: zero o più caratteri


La clausola WHERE può contenere gli operatori <,>, <=,> =, =, <> (non uguale) e LIKE.
L'operatore LIKE viene utilizzato per la corrispondenza dei modelli, ovvero la ricerca di stringhe che corrispondono a un dato
modello. Un modello che contiene il carattere jolly percentuale ( % ) cerca le stringhe
avere zero o più caratteri nella posizione del carattere percentuale nel modello. Per esempio,
individuiamo tutti gli autori il cui cognome inizia con la lettera D:

lecca qui per visualizzare l'immagine del codice

In [11]: pd.read_sql ( "" "SELECT id, first, last


...: DA autori
...: WHERE last LIKE 'D%' "" ",
...: connessione, index_col = [ 'id' ])
...:
Fuori [11]:
primo ultimo
id
1 Paul Deitel
2 Harvey Deitel
3 Abbey Deitel
Corrispondenza del modello: qualsiasi carattere
Un carattere di sottolineatura ( _ ) nella stringa del modello indica un singolo carattere jolly
posizione. Selezioniamo le righe di tutti gli autori i cui cognomi iniziano con qualsiasi carattere,
seguito dalla lettera b, seguita da qualsiasi numero di caratteri aggiuntivi (specificato da%):

lecca qui per visualizzare l'immagine del codice

In [12]: pd.read_sql ( "" "SELECT id, first, last


...: DA autori
...: WHERE prima LIKE '_b%' "" " ,
...: connessione, index_col = [ 'id' ])
...:
Fuori [12]:
primo ultimo
id
3 Abbey Deitel

16.2.4 Clausola ORDER BY

La clausola ORDER BY ordina i risultati di una query in ordine crescente (dal più basso al più alto) o
ordine discendente (dal più alto al più basso), specificato rispettivamente con ASC e DESC.Il predefinito
l'ordinamento è crescente, quindi ASC è facoltativo. Ordiniamo i titoli in ordine crescente:

lecca qui per visualizzare l'immagine del codice

In [13]: pd.read_sql ( 'SELEZIONA titolo DA titoli ORDINA PER titolo ASC' ,

...: connessione) Pagina 742


Fuori [13]:
titolo
0 Android 6 per programmatori
1 Android Come programmare
2 C Come programmare
3 C ++ Come programmare
4 Internet e WWW Come programmare
5 Introduzione a Python per CS e DS
6 Java Come programmare
7 Visual Basic 2012 Come programmare
8 Visual C # Come programmare
9 Visual C ++ Come programmare

Ordinamento per più colonne


Per ordinare in base a più colonne, specificare un elenco di nomi di colonne separati da virgole dopo
ORDINA PER parole chiave. Ordiniamo i nomi degli autori per cognome, quindi per nome per qualsiasi
autori che hanno lo stesso cognome:

lecca qui per visualizzare l'immagine del codice

In [14]: pd.read_sql ( "" "SELECT id, first, last


...: DA autori
...: ORDINA PER ultimo, primo "" " ,
...: connessione, index_col = [ 'id' ])
...:
Fuori [14]:
primo ultimo
id
3 Abbey Deitel
2 Harvey Deitel
1 Paul Deitel
4 Dan Quirk
5 Alexander Wald

L'ordinamento può variare in base alla colonna. Ordiniamo gli autori in ordine decrescente in base al cognome
e in ordine crescente per nome per tutti gli autori che hanno lo stesso cognome:

lecca qui per visualizzare l'immagine del codice

In [15]: pd.read_sql ( "" "SELECT id, first, last


...: DA autori
...: ORDINA PER ultima DESC, prima ASC "" " ,
...: connessione, index_col = [ 'id' ])
...:
Fuori [15]:
primo ultimo
id
5 Alexander Wald
4 Dan Quirk
3 Abbey Deitel
2 Harvey Deitel
1 Paul Deitel

Combinazione delle clausole WHERE e ORDER BY

Le clausole WHERE e ORDER BY possono essere combinate in una query. Prendiamo isbn, titolo,

edizione e copyright di ogni libro nella tabella dei titoli il cui titolo termina con

"Come programmare" e ordinarli in ordine crescente per titolo.


Pagina 743

lecca qui per visualizzare l'immagine del codice

In [16]: pd.read_sql ( "" "SELECT isbn, titolo, edizione, copyright


...: FROM titoli
...: WHERE title LIKE '% Come programmare'
...: ORDER BY titolo "" " , connessione)
Fuori [16]:
copyright dell'edizione del titolo isbn
0 0134444302 Come programmare Android 3 2017
1 0133976890 C Come programmare 8 2016
2 0134448235 C ++ Come programmare 10 2017
3 0132151006 Come programmare Internet e WWW 5 2012
4 0134743350 Java How to Program 11 2018
5 0133406954 Visual Basic 2012 Come programmare 6 2014
6 0134601548 Visual C # How to Program 6 2017
7 0136151574 Visual C ++ How to Program 2 2008

16.2.5 Unione di dati da più tabelle: INNER JOIN

Ricorda che la tabella author_ISBN del database dei libri collega gli autori ai corrispondenti
titoli. Se non separassimo queste informazioni in singole tabelle, avremmo bisogno di includerle
informazioni sull'autore con ciascuna voce nella tabella dei titoli. Ciò comporterebbe l'archiviazione
duplicare le informazioni sull'autore per gli autori che hanno scritto più libri.

È possibile unire i dati da più tabelle, denominate unione delle tabelle, con INNER JOIN .
Produciamo un elenco di autori accompagnati dai codici ISBN per i libri scritti da ogni autore—
poiché ci sono molti risultati per questa query, mostriamo solo l'inizio del risultato:

lecca qui per visualizzare l'immagine del codice

In [17]: pd.read_sql ( "" "SELEZIONA primo, ultimo, isbn


...: DA autori
...: INNER JOIN author_ISBN
...: ON autori.id = author_ISBN.id
...: ORDER BY last, first "" " , connection) .head ()
Fuori [17]:
primo ultimo isbn
0 Abbey Deitel 0132151006
1 Abbey Deitel 0133406954
2 Harvey Deitel 0134289366
3 Harvey Deitel 0135404673
4 Harvey Deitel 0132151006

La clausola ON dell'INNER JOIN utilizza una colonna di chiave primaria in una tabella e una chiave esterna
nell'altra per determinare quali righe unire da ciascuna tabella. Questa query si fonde
la prima e l'ultima colonna della tabella autori con la colonna isbn della tabella author_ISBN

e ordina i risultati in ordine crescente per ultimo poi per primo.

Notare la sintassi autori.id (nome_tabella . Nome_colonna ) nella clausola ON. Questo qualificato
la sintassi del nome è richiesta se le colonne hanno lo stesso nome in entrambe le tabelle.Questa sintassi può
essere utilizzato in qualsiasi istruzione SQL per distinguere le colonne in tabelle diverse che hanno lo stesso
nome. In alcuni sistemi, è possibile utilizzare nomi di tabella qualificati con il nome del database
eseguire query crossdatabase. Come sempre, la query può contenere una clausola ORDER BY.

1C 6.2.6 Istruzione INSERT INTO

16.2.6 Istruzione INSERT INTO Pagina 744

A questo punto, hai interrogato i dati esistenti. A volte eseguirai istruzioni SQL che
modificare il database. Per fare ciò, utilizzerai un oggetto Cursor sqlite3 , che ottieni da
chiamando il metodo del cursore della connessione :

lecca qui per visualizzare l'immagine del codice


In [18]: cursore = connection.cursor ()

Il metodo pandas read_sql utilizza effettivamente un cursore dietro le quinte per eseguire le query

e accedi alle righe dei risultati.

L' istruzione INSERT INTO inserisce una riga in una tabella. Inseriamo un nuovo autore di nome Sue

Rosso nella tabella autori chiamando il metodo Cursor execute , che esegue il suo SQL
argomento e restituisce il cursore:

lecca qui per visualizzare l'immagine del codice

In [19]: cursor = cursor.execute ( "" "INSERT INTO autori (primo, ultimo)


...: VALUES ('Sue', 'Red') "" " )
...:

Le parole chiave SQL INSERT INTO sono seguite dalla tabella in cui inserire la nuova riga
e un elenco di nomi di colonne separati da virgole tra parentesi.L'elenco dei nomi delle colonne è
seguito dalla parola chiave SQL VALUES e da un elenco di valori separati da virgole tra parentesi.
I valori forniti devono corrispondere ai nomi delle colonne specificati sia nell'ordine che nel tipo.

Non specifichiamo un valore per la colonna id perché è una colonna con incremento automatico nel file

tabella autori: questo è stato specificato nello script books.sql che ha creato la tabella.Per ogni
nuova riga, SQLite assegna un valore id univoco che è il valore successivo nel file autoincremented
sequenza (cioè 1, 2, 3 e così via). In questo caso, a Sue Red viene assegnato il numero ID 6. Per confermare
questo, interroghiamo il contenuto della tabella degli autori:

lecca qui per visualizzare l'immagine del codice

In [20]: pd.read_sql ( 'SELECT id, first, last FROM autori' ,


...: connessione, index_col = [ 'id' ])
...:
Fuori [20]:
primo ultimo
id
1 Paul Deitel
2 Harvey Deitel
3 Abbey Deitel
4 Dan Quirk
5 Alexander Wald
6 Sue Red

Nota relativa alle stringhe che contengono virgolette singole


SQL delimita le stringhe con virgolette singole ('). Una stringa contenente una singola virgoletta, come
O'Malley, deve avere due virgolette singole nella posizione in cui appare la virgoletta singola (ad es.

'O''Malley'). Il primo funge da carattere di fuga per il secondo. Non sfuggire single
Pagina 745
virgolette i caratteri in una stringa che fa parte di un'istruzione SQL è un errore di sintassi SQL.

16.2.7 Istruzione UPDATE

Un'istruzione UPDATE modifica i valori esistenti. Supponiamo che il cognome di Sue Red sia
errato nel database e aggiornalo su "Nero":

lecca qui per visualizzare l'immagine del codice

In [21]: cursor = cursor.execute ( "" "UPDATE autori SET last = 'Black'


...: WHERE last = 'Red' AND first = 'Sue' "" " )

La parola chiave UPDATE è seguita dalla tabella da aggiornare, dalla parola chiave SET e da una virgola
elenco separato di coppie nome_colonna = valore che indica le colonne da modificare e le nuove
valori. La modifica verrà applicata a ogni riga se non si specifica una clausola WHERE. Il

La clausola WHERE in questa query indica che dobbiamo aggiornare solo le righe in cui il cognome
è "Red" e il primo nome è "Sue".

Naturalmente, potrebbero esserci più persone con lo stesso nome e cognome. Fare un
passare a una sola riga, è meglio utilizzare la chiave primaria univoca della riga nella clausola WHERE.Nel
in questo caso, avremmo potuto specificare:

DOVE id = 6
Per le istruzioni che modificano il database, l'attributo del conteggio delle righe dell'oggetto Cursor contiene
un valore intero che rappresenta il numero di righe che sono state modificate. Se questo valore è 0, no
sono state apportate modifiche. Quanto segue conferma che UPDATE ha modificato una riga:

lecca qui per visualizzare l'immagine del codice

In [22]: cursor.rowcount
Fuori [22]: 1

Possiamo anche confermare l'aggiornamento elencando i contenuti della tabella degli autori:

lecca qui per visualizzare l'immagine del codice

In [23]: pd.read_sql ( 'SELECT id, first, last FROM autori' ,


...: connessione, index_col = [ 'id' ])
...:
Fuori [23]:
primo ultimo
id
1 Paul Deitel
2 Harvey Deitel
3 Abbey Deitel
4 Dan Quirk
5 Alexander Wald
6 Sue Black

16.2.8 Istruzione DELETE FROM

Un'istruzione SQL DELETE FROM rimuove le righe da una tabella. Rimuoviamo Sue Black dal file
Pagina 746

tabella autori utilizzando il suo ID autore:

lecca qui per visualizzare l'immagine del codice

In [24]: cursor = cursor.execute ( 'DELETE FROM autori WHERE id = 6' )

In [25]: cursor.rowcount
Fuori [25]: 1

La clausola WHERE facoltativa determina le righe da eliminare. Se WHERE viene omesso, tutti i file
le righe della tabella vengono eliminate. Ecco la tabella degli autori dopo l'operazione DELETE:

lecca qui per visualizzare l'immagine del codice

In [26]: pd.read_sql ( 'SELECT id, first, last FROM autori' ,


...: connessione, index_col = [ 'id' ])
...:
Fuori [26]:
primo ultimo
id
1 Paul Deitel
2 Harvey Deitel
3 Abbey Deitel
4 Dan Quirk
5 Alexander Wald

Chiusura del database


Quando non è più necessario accedere al database, è necessario chiamare la chiusura della connessione
metodo per disconnettersi dal database:

connection.close ()

SQL nei Big Data


L'importanza di SQL sta crescendo nei big data. Più avanti in questo capitolo, utilizzeremo Spark SQL per eseguire query
dati in un Spark DataFrame per il quale i dati possono essere distribuiti su molti computer in un file
Spark cluster. Come vedrai, Spark SQL assomiglia molto all'SQL presentato in questa sezione.

16.3 BIG-DATA DATABASE NOSQL E NEWSQL: UN BREVE


TOUR
Per decenni, i sistemi di gestione dei database relazionali sono stati lo standard nei dati
in lavorazione. Tuttavia, richiedono dati strutturati che si adattino a tabelle rettangolari ordinate. Come
aumenta la dimensione dei dati e il numero di tabelle e relazioni, database relazionali
diventano più difficili da manipolare in modo efficiente. Nel mondo dei bigdata di oggi, NoSQL e
Sono emersi database NewSQL per gestire i tipi di archiviazione ed elaborazione dei dati
richieste che i database relazionali tradizionali non possono soddisfare. I big data richiedono enormi
database, spesso distribuiti nei data center di tutto il mondo in enormi cluster di merci
computer. Secondo statista.com, ci sono attualmente oltre 8 milioni di data center
In tutto il mondo. 3

C
3
ttps: //www.statista.com/statistics/500458/worldwidedatacenter
Pagina 747

nditsites / .

oSQL originariamente significava ciò che il suo nome implica. Con la crescente importanza di SQL in big
dati, come SQL su Hadoop e Spark SQL, NoSQL ora si dice che stia per "Non solo
SQL. " I database NoSQL sono pensati per dati non strutturati, come foto, video e natura
lingua che si trova in e-mail, messaggi di testo e post sui social media e dati semistrutturati
come i documenti JSON e XML. I dati semistrutturati spesso avvolgono i dati non strutturati con
informazioni aggiuntive chiamate metadati . Ad esempio, i video di YouTube non sono strutturati
dati, ma YouTube conserva anche i metadati per ogni video, incluso chi lo ha pubblicato, quando è stato pubblicato
è stato pubblicato, un titolo, una descrizione, tag che aiutano le persone a scoprire i video, impostazioni sulla privacy
e altro ancora, tutti restituiti come JSON dalle API di YouTube.Questi metadati aggiungono struttura al file
dati video non strutturati, rendendoli semistrutturati.

Le successive sottosezioni illustrano le quattro categorie di database NoSQL: chiave-valore,


document, columnar (chiamato anche columnbased) e grafico. Inoltre, faremo una panoramica
Database NewSQL, che uniscono le caratteristiche dei database relazionali e NoSQL. Nel ezione 16.4,
presenteremo un case study in cui memorizziamo e manipoliamo un gran numero di tweet JSON
oggetti in un database di documenti NoSQL, quindi riassumere i dati in un file interattivo
visualizzazione visualizzata su una mappa Folium degli Stati Uniti.

16.3.1 Database valori-chiave NoSQL


4
Come i dizionari Python, i database chiave-valore memorizzare le coppie chiave-valore, ma lo sono
ottimizzato per sistemi distribuiti e elaborazione di bigdata. Per affidabilità, tendono a
replicare i dati in più nodi del cluster. Alcuni database di valori-chiave, come Redis, lo sono
implementato in memoria per le prestazioni e altri archiviano dati su disco, come HBase,
che viene eseguito sul file system distribuito HDFS di Hadoop.Altro valore-chiave popolare
i database includono Amazon DynamoDB, Google Cloud Datastore e Couchbase. DynamoDB
e Couchbase sono database multimodello che supportano anche i documenti. HBase è anche un file
database orientato alle colonne.

4
TTP: //en.wikipedia.org/wiki/Keyvalue_database .

16.3.2 Database di documenti NoSQL


5
Un database di documenti memorizza dati semistrutturati, come documenti JSON o XML.
Nei database dei documenti, in genere aggiungi indici per attributi specifici, quindi puoi fare di più
individuare e manipolare in modo efficiente i documenti. Ad esempio, supponiamo che tu stia archiviando JSON
documenti prodotti dai dispositivi IoT e ogni documento contiene un attributo di tipo.Tu potresti
aggiungi un indice per questo attributo in modo da poter filtrare i documenti in base ai loro tipi.Senza
indici, puoi ancora eseguire quell'attività, sarà solo più lento perché devi cercare ciascuno
documento nella sua interezza per trovare l'attributo.

5
TTP: //en.wikipedia.org/wiki/Documentoriented_database .

6
Il database di documenti più popolare (e il database NoSQL in generale più popolare) è
MongoDB , il cui nome deriva da una sequenza di lettere incorporate nella parola
"gigantesco." In un esempio, memorizzeremo un gran numero di tweet in MongoDB per
in lavorazione. Ricorda che le API di Twitter restituiscono i tweet in formato JSON, quindi possono essere archiviati
direttamente in MongoDB. Dopo aver ottenuto i tweet, li riassumeremo in un panda Data

N
hS
un'

Cornice e su una mappa Folium. Altri database di documenti popolari includono Amazon
Pagina 748
DynamoDB (anche un database chiave-valore), Microsoft Azure Cosmos DB e Apache CouchDB.

6
ttps: //dbengines.com/en/ranking .

16.3.3 Database a colonne NoSQL

In un database relazionale, un'operazione di query comune consiste nell'ottenere il valore di una colonna specifica per
ogni riga. Poiché i dati sono organizzati in righe, può farlo una query che seleziona una colonna specifica
prestazioni scadenti. Il sistema di database deve ottenere ogni riga corrispondente, individuare il file richiesto
7,8
colonna ed elimina il resto delle informazioni della riga.Un database colonnare , anche
chiamato database orientato alle colonne , è simile a un database relazionale, ma memorizza
dati strutturati in colonne anziché in righe. Perché tutti gli elementi di una colonna vengono memorizzati
insieme, selezionare tutti i dati per una data colonna è più efficiente.

7
ttps: //en.wikipedia.org/wiki/Columnar_database .

8
ttps: //www.predictiveanalyticstoday.com/topwidecolumnarstore
atabase / .

Considera la nostra tabella autori nel database dei libri:

lecca qui per visualizzare l'immagine del codice

primo ultimo
id
1 Paul Deitel
2 Harvey Deitel
3 Abbey Deitel
4 Dan Quirk
5 Alexander Wald

In un database relazionale, tutti i dati di una riga vengono archiviati insieme. Se consideriamo ogni riga come un file
Tupla Python, le righe sarebbero rappresentate come (1, 'Paul', 'Deitel'), (2,

'Harvey', 'Deitel'), ecc. In un database a colonne, tutti i valori per una data colonna
verrebbero archiviati insieme, come in (1, 2, 3, 4, 5), ('Paul', 'Harvey', 'Abbey',
"Dan", "Alexander") e ("Deitel", "Deitel", "Deitel", "Quirk",
"Wald"). Gli elementi in ogni colonna vengono mantenuti in ordine di riga, quindi il valore in un dato
index in ogni colonna appartiene alla stessa riga. I database colonnari popolari includono MariaDB
ColumnStore e HBase.

16.3.4 Database grafici NoSQL


9
Un grafico modella le relazioni tra gli oggetti. Gli oggetti sono chiamati nodi (o vertici )
e le relazioni sono chiamate bordi . I bordi sono direzionali . Ad esempio, un bordo
che rappresenta i punti di volo di una compagnia aerea dalla città di origine alla città di destinazione, ma non il
0
inversione. Un database a grafo memorizza nodi, bordi e i loro attributi.

9
ttps: //en.wikipedia.org/wiki/Graph_theory .

0
ttps: //en.wikipedia.org/wiki/Graph_database .

Se utilizzi social network, come Instagram, Snapchat, Twitter e Facebook, considera il tuo

dC
1h

grafico sociale, che consiste delle persone che conosci (nodi) e delle relazioni tra
Pagina 749
loro (bordi). Ogni persona ha il proprio grafico sociale e questi sono interconnessi.Il
il famoso problema dei "sei gradi di separazione" dice che due persone nel mondo lo sono
collegati tra loro seguendo un massimo di sei spigoli nel social mondiale
1 2
grafico. Gli algoritmi di Facebook utilizzano i grafici sociali dei loro miliardi di utenti attivi mensilmente
per determinare quali storie dovrebbero apparire nel feed di notizie di ogni utente.Guardando il tuo
interessi, i tuoi amici, i loro interessi e altro ancora, Facebook predice le storie in cui credono
3
sono più rilevanti per te.

1
ttps: //en.wikipedia.org/wiki/Six_degrees_of_separation .

2
ttps: //zephoria.com/top15valuablefacebookstatistics/ .

3
ttps: //newsroom.fb.com/news/2018/05/insidefeednewsfeedranking/ .

Molte aziende utilizzano tecniche simili per creare motori di raccomandazione. Quando tu
sfoglia un prodotto su Amazon, usano un grafico di utenti e prodotti per mostrarti comparabili
prodotti che le persone hanno consultato prima di effettuare un acquisto.Quando sfogli i film su Netflix,
usano un grafico degli utenti e dei film che gli piacevano per suggerire i film che potrebbero interessare
tu.

Uno dei database grafici più popolari è Neo4j. Molti casi d'uso del mondo reale per il grafico
i database sono forniti a:

ttps: //neo4j.com/graphgists/
Nella maggior parte dei casi d'uso, vengono mostrati diagrammi grafici di esempio prodotti da Neo4j.Questi
visualizzare le relazioni tra i nodi del grafico. Dai un'occhiata al libro PDF gratuito di Neo4j, Graph
4
Database .

4
TTP: //neo4j.com/graphdatabasesbooksx2 .

16.3.5 Database NewSQL


I principali vantaggi dei database relazionali includono la sicurezza e il supporto delle transazioni.Nel
particolari database relazionali utilizzano tipicamente ACID (Atomicity, Consistency, Isolation,
5
Durabilità) transazioni:

5
ttps: //en.wikipedia.org/wiki/ACID_ (computer_science) .

L'atomicità garantisce che il database venga modificato solo se tutti i passaggi di una transazione lo sono
riuscito. Se vai a un bancomat per prelevare $ 100, quel denaro non viene rimosso dal tuo
conto a meno che tu non abbia abbastanza soldi per coprire il prelievo e ce ne sia abbastanza
soldi nel bancomat per soddisfare la tua richiesta.

La coerenza garantisce che lo stato del database sia sempre valido. Nell'esempio di prelievo
sopra, il saldo del tuo nuovo account dopo la transazione rifletterà esattamente ciò che hai
prelevato dal tuo account (e possibilmente commissioni bancomat).

L'isolamento garantisce che le transazioni simultanee si verifichino come se fossero state eseguite
sequenzialmente. Ad esempio, se due persone condividono un conto bancario congiunto ed entrambe tentano di farlo

1h
h

prelevare denaro contemporaneamente da due bancomat separati, una transazione deve attendere
Pagina 750
fino al completamento dell'altro.

La durabilità garantisce che le modifiche al database sopravvivano anche a guasti hardware.

Se cerchi vantaggi e svantaggi dei database NoSQL, vedrai che NoSQL


i database generalmente non forniscono il supporto ACID. I tipi di applicazioni che utilizzano NoSQL
i database in genere non richiedono le garanzie fornite dai database conformi ad ACID.
Molti database NoSQL in genere aderiscono al BASE (Basic Availability, Softstate,
Eventual consistency) , che si concentra maggiormente sulla disponibilità del database. Mentre,
I database ACID garantiscono la coerenza quando si scrive nel database, database BASE
fornire coerenza in un momento successivo.

I database NewSQL uniscono i vantaggi dei database relazionali e NoSQL per bigdata
compiti di elaborazione. Alcuni popolari database NewSQL includono VoltDB, MemSQL, Apache Ignite
e Google Spanner.

16.4 CASO DI STUDIO: UN DOCUMENTO JSON DI MONGODB


BANCA DATI
MongoDB è un database di documenti in grado di archiviare e recuperare documenti JSON.
Le API di Twitter ti restituiscono i tweet come oggetti JSON, che puoi scrivere direttamente in un file
Database MongoDB. In questa sezione potrai:

usa Tweepy per trasmettere in streaming i tweet sui 100 senatori statunitensi e archiviarli in un MongoDB
Banca dati,

usa i panda per riassumere i primi 10 senatori con l'attività di tweet e

mostra una mappa interattiva Folium degli Stati Uniti con un indicatore popup per stato
che mostra il nome dello stato e i nomi di entrambi i senatori, i loro partiti politici e tweet
conta.

Utilizzerai un cluster MongoDB Atlas gratuito basato su cloud, che non richiede installazione e
attualmente consente di memorizzare fino a 512 MB di dati. Per archiviarne di più, puoi scaricare il file
MongoDB Community Server da:

lecca qui per visualizzare l'immagine del codice

ttps: //www.mongodb.com/downloadcenter/community

ed eseguirlo localmente oppure puoi iscriverti al servizio Atlas a pagamento di MongoDB .


Installazione delle librerie Python necessarie per interagire con MongoDB
Utilizzerai la libreria pymongo per interagire con i database MongoDB dal tuo codice Python.
Avrai anche bisogno della libreria dnspython per connetterti a un MongoDB Atlas Cluster. Installare
queste librerie, utilizzare i seguenti comandi:

lecca qui per visualizzare l'immagine del codice

C
h

Pagina 751
conda install c condaforge pymongo
conda installa c condaforge dnspython

keys.py
La sottocartella TwitterMongoDB della cartella degli esempi ch16 contiene il codice di questo esempio e

keys.py file. Modifica questo file per includere le tue credenziali Twitter e la tua chiave OpenMapQuest
dal capitolo "Data mining Twitter". Dopo aver discusso della creazione di un cluster MongoDB Atlas,
dovrai anche aggiungere la tua stringa di connessione MongoDB a questo file.

16.4.1 Creazione del MongoDB Atlas Cluster


Per registrarti per un account gratuito vai su

ttps: //mongodb.com

quindi inserisci il tuo indirizzo e-mail e fai clic su Inizia gratuitamente. Nella pagina successiva, inserisci il tuo
nome e creare una password, quindi leggere i termini di servizio. Se sei d'accordo, fai clic su Inizia
gratuitamente in questa pagina e verrai indirizzato alla schermata per configurare il tuo cluster. Fare clic su Build
il mio primo cluster per iniziare.

Ti guidano attraverso i passaggi iniziali con bolle popup che descrivono e indicano
a ogni attività che devi completare. Forniscono le impostazioni predefinite per il loro Atlas gratuito
cluster (M0 come si riferiscono ad esso), quindi assegna un nome al tuo cluster in Cluster Name
sezione, quindi fare clic su Crea cluster. A questo punto, ti porteranno alla pagina Cluster e
inizia a creare il tuo nuovo cluster, operazione che richiede diversi minuti.

Successivamente, verrà visualizzato un tutorial popup Connect to Atlas, che mostra un elenco di controllo di passaggi aggiuntivi
necessario per farti funzionare:

Crea il tuo primo utente di database: questo ti consente di accedere al tuo cluster.

Inserisci il tuo indirizzo IP nella whitelist: si tratta di una misura di sicurezza che garantisce solo l'IP
gli indirizzi che verifichi possono interagire con il tuo cluster. Per connettersi a questo cluster
da più posizioni (scuola, casa, lavoro, ecc.), dovrai inserire nella whitelist ogni indirizzo IP
da cui intendi connetterti.

Connettiti al tuo cluster: in questo passaggio individuerai la stringa di connessione del tuo cluster,
che consentirà al tuo codice Python di connettersi al server.

Creazione del primo utente del database


Nella finestra popup del tutorial, fai clic su Crea il tuo primo utente di database per continuare il file
tutorial, quindi segui le istruzioni sullo schermo per visualizzare la scheda Sicurezza del cluster e fai clic su +
AGGIUNGI NUOVO UTENTE. Nella finestra di dialogo Aggiungi nuovo utente, crea un nome utente e una password. Scrivi
questi giù, ne avrai bisogno per un momento. Fare clic su Aggiungi utente per tornare a Connetti a
Tutorial popup Atlas.

Inserisci il tuo indirizzo IP nella whitelist


Nella finestra popup del tutorial, fare clic su Whitelist your IP address per continuare il tutorial,
quindi seguire le istruzioni sullo schermo per visualizzare la Whitelist IP del cluster e fare clic su + AGGIUNGI IP

INDIRIZZO. Nella finestra di dialogo Aggiungi voce whitelist, puoi aggiungere il tuo computer
Pagina 752
indirizzo IP corrente o consentire l'accesso da qualsiasi luogo, cosa che non è consigliabile per
database di produzione, ma va bene per scopi di apprendimento. Fare clic su CONSENTI L'ACCESSO DA
OVUNQUE, quindi fare clic su Conferma per tornare al tutorial popup Connect to Atlas.

Connettiti al tuo cluster


Nella finestra popup del tutorial, fai clic su Connetti al tuo cluster per continuare il tutorial, quindi
seguire le istruzioni sullo schermo per visualizzare la finestra di dialogo Connect to YourClusterName del cluster .
La connessione a un database MongoDB Atlas da Python richiede una stringa di connessione. Ottenere
la stringa di connessione, fare clic su Connect Your Application, quindi su Short SRV
stringa di connessione. La stringa di connessione verrà visualizzata sotto Copia l'indirizzo SRV.
Fare clic su COPIA per copiare la stringa. Incolla questa stringa nel file keys.py come
valore di mongo_connection_string. Sostituisci "<PASSWORD>" nella stringa di connessione
con la tua password e sostituisci il nome del database "test" con "senators", che lo farà

essere il nome del database in questo esempio. Nella parte inferiore del Connect to
YourClusterName , fare clic su Chiudi. Ora sei pronto per interagire con il tuo cluster Atlas.

16.4.2 Streaming di tweet in MongoDB

Per prima cosa presenteremo una sessione IPython interattiva che si connette al database MongoDB,
scarica i tweet attuali tramite lo streaming di Twitter e riassume i primi 10 senatori tramite tweet
contare. Successivamente, presenteremo la classe TweetListener, che gestisce i tweet in arrivo e
memorizza il proprio JSON in MongoDB. Infine, continueremo la sessione IPython creando un file
mappa interattiva di Folium che mostra le informazioni dai tweet che abbiamo memorizzato.

Usa Tweepy per autenticarti con Twitter


Innanzitutto, usiamo Tweepy per autenticarci con Twitter:

lecca qui per visualizzare l'immagine del codice

In [1]: importa tweepy, keys

In [2]: auth = tweepy.OAuthHandler (


...: keys.consumer_key, keys.consumer_secret)
...: auth.set_access_token (keys.access_token,
...: keys.access_token_secret)
...:

Successivamente, configura l'oggetto API Tweepy in modo che attenda se la nostra app raggiunge i limiti di velocità di Twitter.

lecca qui per visualizzare l'immagine del codice

In [3]: api = tweepy.API (auth, wait_on_rate_limit = True ,


...: wait_on_rate_limit_notify = True )
...:

Caricamento dei dati dei senatori


Useremo le informazioni nel file senators.csv (che si trova nella cartella degli esempi ch16's
Sottocartella TwitterMongoDB) per tenere traccia dei tweet verso, da e su ogni senatore degli Stati Uniti. Il file
contiene il codice dello stato di due lettere del senatore, il nome, il partito, l'handle di Twitter e l'ID di Twitter.

Twitter ti consente di seguire utenti specifici tramite i loro ID Twitter numerici, ma questi devono essere
Pagina 753
inviato come rappresentazioni di stringa di quei valori numerici.Quindi, carichiamo senators.csv
in panda, converti i valori TwitterID in stringhe (utilizzando il metodo Series astype ) e
visualizzare diverse righe di dati. In questo caso, impostiamo 6 come numero massimo di colonne su
Schermo. Successivamente aggiungeremo un'altra colonna al DataFrame e questa impostazione lo garantirà
vengono visualizzate tutte le colonne, piuttosto che alcune con in mezzo:

lecca qui per visualizzare l'immagine del codice

In [4]: importa i panda come pd

In [5]: senators_df = pd.read_csv ( 'senators.csv' )

In [6]: senators_df [ 'TwitterID' ] = senators_df [ 'TwitterID' ] .astype (str)

In [7]: pd.options.display.max_columns = 6

In [8]: senators_df.head ()
Fuori [8]:
Stato Nome Parte Twitter Gestisci TwitterID
0 AL Richard Shelby R SenShelby 21111098
1 AL Doug Jomes D SenDougJones 941080085121175552
2 AK Lisa Murkowski R lisamurkowski 18061669
3 AK Dan Sullivan R SenDanSullivan 2891210047
4 AZ Jon Kyl R SenJonKyl 24905240

Configurazione di MongoClient
Per memorizzare il JSON del tweet come documenti in un database MongoDB, devi prima connetterti a
il tuo cluster MongoDB Atlas tramite un MongoClient pymongo , che riceve il tuo cluster
stringa di connessione come argomento:

lecca qui per visualizzare l'immagine del codice

In [9]: da pymongo importa MongoClient

In [10]: atlas_client = MongoClient (keys.mongo_connection_string)

Ora possiamo ottenere un oggetto Database pymongo che rappresenta il database dei senatori. Il
la seguente istruzione crea il database se non esiste:

lecca qui per visualizzare l'immagine del codice

In [11]: db = atlas_client.senators

Configurazione del Tweet Stream


Specifichiamo il numero di tweet da scaricare e creiamo il TweetListener.Passiamo il file

db che rappresenta il database MongoDB nel TweetListener in modo che possa scrivere il file
tweet nel database. A seconda della velocità con cui le persone twittano su
Senatori, potrebbero volerci minuti o ore per ricevere 10.000 tweet. A scopo di test, potresti
desidera utilizzare un numero inferiore:

lecca qui per visualizzare l'immagine del codice

C
Pagina 754
In [12]: from tweetlistener import TweetListener

In [13]: tweet_limit = 10000

In [14]: twitter_stream = tweepy.Stream (api.auth,


...: TweetListener (api, db, tweet_limit))
...:

Avvio del Tweet Stream

Il live streaming di Twitter ti consente di monitorare fino a 400 parole chiave e di seguire fino a 5.000 Twitter
ID alla volta. In questo caso, seguiamo gli handle Twitter dei senatori e seguiamo quelli del senatore
ID Twitter. Questo dovrebbe darci tweet da, ae su ogni senatore. Mostrarti
avanzamento, vengono visualizzati il ​nome della schermata e il timestamp per ogni tweet ricevuto e il totale
numero di tweet finora. Per risparmiare spazio, mostriamo qui solo uno di quegli output di tweet e
sostituire il nome della schermata dell'utente con XXXXXXX:

lecca qui per visualizzare l'immagine del codice

In [15]: twitter_stream.filter (track = senators_df.TwitterHandle.tolist (),


...: follow = senators_df.TwitterID.tolist ())
...:
Nome schermo: XXXXXXX
Creato a: Sun Dec 16 17:19:19 +0000 2018
Tweet ricevuti: 1
...

Classe TweetListener

Per questo esempio, abbiamo leggermente modificato la classe TweetListener da "Data Mining
Capitolo "Twitter". Gran parte del codice Twitter e Tweepy mostrato di seguito è identico al codice
hai visto in precedenza, quindi ci concentreremo solo sui nuovi concetti qui:

lecca qui per visualizzare l'immagine del codice

1 # tweetlistener.py
2 "" "TweetListener scarica i tweet e li memorizza in MongoDB." ""
3 importare json
4 import tweepy
5
6 classi TweetListener (tweepy.StreamListener):
7 "" "Gestisce il flusso di Tweet in arrivo." ""
8
9 def __init __ (self, api, database, limit = 10000 ):
10 "" "Crea variabili di istanza per tenere traccia del numero di tweet." ""
11 self.db = database
12 self.tweet_count = 0
13 auto. TWEET_LIMIT = limite # 10.000 per impostazione predefinita
14 super () .__ init __ (api) # chiama l'init della superclasse
15
16 def on_connect (self):
17 "" "Chiamato quando il tentativo di connessione ha esito positivo, abilitazione
18 di eseguire le attività dell'applicazione appropriate a quel punto. "" "
19 print ( "Connessione a Twitter \ n" riuscita )
20
21 def on_data (self, data):
22 "" "Chiamato quando Twitter ti invia un nuovo tweet." ""
23 self.tweet_count + = 1 # numero di traccia di tweet elaborati
24 json_data = json.loads (data) # converte la stringa in JSON

C
25 self.db.tweets.insert_one (json_data) # memorizza nella raccolta dei tweets Pagina 755
26 print (f 'Screen name: {json_data [ "user" ] [ "name" ]} ' )
27 print (f 'Creato a: {json_data [ "created_at" ]} ' )
28 print (f "Tweet ricevuti: {self.tweet_count} " )
29
30 # se viene raggiunto TWEET_LIMIT, restituisci False per terminare lo streaming
31 return self.tweet_count! = Self. TWEET_LIMIT
32
33 def on_error (self, status):
34 stampa (stato)
35 return True

reviously, TweetListener ha ignorato il metodo on_status per ricevere lo stato di Tweepy


oggetti che rappresentano i tweet. Qui, invece, sovrascriviamo il metodo on_data (righe 21–31).
Invece degli oggetti Status, on_data riceve il JSON grezzo di ogni oggetto tweet . Linea 24
converte la stringa JSON ricevuta da on_data in un oggetto JSON Python.Ogni MongoDB
il database contiene una o più raccolte di documenti. Alla riga 25, l'espressione

self.db.tweets

accede alla raccolta dei tweet del database dell'oggetto Database, creandola se non lo fa già
esistere. La riga 25 utilizza il metodo insert_one della raccolta tweets per memorizzare il JSON
oggetto nella raccolta dei tweet.

Contando i tweet per ogni senatore


Successivamente, eseguiremo una ricerca full-text sulla raccolta di tweet e conteggeremo il numero di
tweet contenenti l'handle Twitter di ogni senatore. Per eseguire una ricerca di testo in MongoDB, devi creare
6
un indice di testo per la raccolta. Specifica i campi del documento da cercare. Ogni testo
index è definito come una tupla contenente il nome del campo da cercare e il tipo di indice ('testo').
L'identificatore di caratteri jolly di MongoDB ($ **) indica che ogni campo di testo in un documento (un file JSON
oggetto tweet nel nostro caso) dovrebbe essere indicizzato per una ricerca full-text:

6
Per ulteriori dettagli sui tipi di indice MongoDB, sugli indici di testo e sugli operatori, vedere:
ttps: //docs.mongodb.com/manual/indexes ,
TTP: //docs.mongodb.com/manual/core/indextext e
ttps: //docs.mongodb.com/manual/reference/operator .

lecca qui per visualizzare l'immagine del codice

In [16]: db.tweets.create_index ([( '$ **' , 'text' )])


Uscita [16]: "$ ** _ testo"

Una volta definito l'indice, possiamo utilizzare il metodo count_documents della Collection per
contare il numero totale di documenti nella raccolta che contengono il testo specificato. Facciamo
cerca nella raccolta di tweet del database ogni handle di Twitter nel file senators_df

Colonna TwitterHandle di DataFrame:

lecca qui per visualizzare l'immagine del codice

In [17]: tweet_counts = []

P
C
1h

In [18]: for senator in senators_df.TwitterHandle: Pagina 756


...: tweet_counts.append (db.tweets.count_documents (
...: { "$ text" : { "$ search" : senator}}))
...:

L'oggetto JSON passato a count_documents in questo caso indica che stiamo usando il
indice denominato testo per cercare il valore del senatore.
Mostra il conteggio dei tweet per ogni senatore
Creiamo una copia del DataFrame senators_df che contiene tweet_counts come file

nuova colonna, quindi visualizza i primi 10 senatori in base al conteggio dei tweet:

lecca qui per visualizzare l'immagine del codice

In [19]: tweet_counts_df = senators_df.assign (Tweets = tweet_counts)

In [20]: tweet_counts_df.sort_values ​(by = 'Tweets' ,


...: crescente = False ) .head ( 10 )
...:

Fuori [20]:
Stato Nome Parte Twitter Gestisci Tweet TwitterID
78 SC Lindsey Graham R LindseyGrahamSC 432895323 1405
41 MA Elizabeth Warren D SenWarren 970207298 1249
8 CA Dianne Feinstein D SenFeinstein 476256944 1079
20 HI Brian Schatz D brianschatz 47747074 934
62 NY Chuck Schumer D SenSchumer 17494010 811
24 IL Tammy Duckworth D SenDuckworth 1058520120 656
13 CT Richard Blumenthal D SenBlumenthal 278124059 646
21 HI Mazie Hirono D maziehirono 92186819 628
86 UT Orrin Hatch R SenOrrinHatch 262756641506
77 RI Sheldon Whitehouse D SenWhitehouse 242555999 350

Ottieni le posizioni di stato per tracciare i marker


Successivamente, utilizzeremo le tecniche apprese nel capitolo "Data mining di Twitter" per ottenerle
latitudine e longitudine dello stato. Presto li useremo per posizionarli su una mappa Folium
marcatori popup che contengono i nomi e il numero di tweet che menzionano ogni stato
senatori.

Il file state_codes.py contiene un dizionario state_codes che mappa lo stato di due lettere
codici ai loro nomi di stato completi. Useremo i nomi degli stati completi con OpenMapQuest di geopy
7
funzione di geocodifica per cercare la posizione di ogni stato.Per prima cosa, importiamo le librerie che abbiamo
need e il dizionario state_codes:

7
Usiamo nomi di stato completi perché, durante i nostri test, i codici di stato a due lettere non lo hanno fatto
restituire sempre le posizioni corrette.

lecca qui per visualizzare l'immagine del codice

In [21]: da geopy importa OpenMapQuest

In [22]: import time

In [23]: da state_codes importa state_codes

1C

Quindi, facciamo in modo che l'oggetto geocodificatore traduca i nomi delle posizioni in oggetti Posizione:
Pagina 757

lecca qui per visualizzare l'immagine del codice

In [24]: geo = OpenMapQuest (api_key = keys.mapquest_key)

Ci sono due senatori per ogni stato, quindi possiamo cercare una volta la posizione di ogni stato e utilizzarlo
l'oggetto Posizione per entrambi i senatori di quello stato. Allora prendiamo i nomi degli stati univoci
ordinali in ordine crescente:

lecca qui per visualizzare l'immagine del codice

In [25]: states = tweet_counts_df.State.unique ()

In [26]: states.sort ()

I due frammenti successivi utilizzano il codice del capitolo "Twitter di data mining" per cercarli
posizione dello stato. Nello snippet [28], chiamiamo la funzione geocode con il nome dello stato seguito
8
da ", USA" per assicurarci di ottenere località negli Stati Uniti, poiché ci sono luoghi al di fuori di
Stati Uniti con gli stessi nomi degli Stati Uniti. Per mostrare i progressi, mostriamo ogni nuovo
Stringa dell'oggetto posizione:

8
Quando inizialmente abbiamo eseguito la geocodifica per lo stato di Washington, OpenMapQuest è tornato
Posizione di Washington, DC. Quindi abbiamo modificato state_codes.py per utilizzare lo Stato di Washington
anziché.

lecca qui per visualizzare l'immagine del codice

In [27]: località = []

In [28]: per lo stato negli stati:


...: elaborato = Falso
...: ritardo = .1
...: mentre non elaborato:
...: prova :
...: locations.append (
...: geo.geocode (state_codes [state] + ', USA' ))
...: print (locations [ 1 ])
...: elaborato = vero
...: eccetto : # scaduto, quindi attendi prima di riprovare
...: print ( "Servizio OpenMapQuest scaduto. In attesa." )
...: time.sleep (ritardo)
...: ritardo + = .1
...:
Alaska, Stati Uniti d'America
Alabama, Stati Uniti d'America
Arkansas, Stati Uniti d'America
...

Raggruppare i conteggi del tweet per stato


Useremo il numero totale di tweet per i due senatori in uno stato per colorare quello stato sul file
carta geografica. I colori più scuri rappresenteranno gli stati con un numero maggiore di tweet.Per preparare i dati per
mappatura, usiamo il metodo groupby DataFrame dei panda per raggruppare i senatori per stato
e calcola il totale dei tweet per stato:

1C

lecca qui per visualizzare l'immagine del codice


Pagina 758

In [29]: tweets_counts_by_state = tweet_counts_df.groupby (


...: 'State' , as_index = False ) .sum ()
...:

In [30]: tweets_counts_by_state.head ()
Fuori [30]:
Tweet di stato
0 AK 27
1 AL 2
2 RA 47
3 AZ 47
4 CA 1135

L'argomento parola chiave as_index = False nello snippet [29] indica che i codici di stato

dovrebbero essere valori in una colonna dell'oggetto GroupBy risultante , piuttosto che gli indici per il
righe. Il metodo sum dell'oggetto GroupBy somma i dati numerici (i tweet per stato).
Lo snippet [30] mostra diverse righe dell'oggetto GroupBy in modo che tu possa vedere alcuni dei risultati.

Creazione della mappa


Quindi, creiamo la mappa. Potresti voler regolare lo zoom. Sul nostro sistema, quanto segue
snippet crea una mappa in cui inizialmente possiamo vedere solo gli Stati Uniti continentali.
Ricorda che le mappe Folium sono interattive, quindi una volta visualizzata la mappa puoi scorrere fino a
ingrandire e rimpicciolire o trascinare per visualizzare aree diverse, come Alaska o Hawaii:

lecca qui per visualizzare l'immagine del codice

In [31]: import folium

In [32]: usmap = folium.Map (location = [ 39.8283 , 98.5795 ],


...: zoom_start = 4 , detect_retina = True ,
...: tiles = 'Stamen Toner' )
...:

Creazione di un coropleto per colorare la mappa

Un coropleto ombreggia le aree in una mappa utilizzando i valori specificati per determinare il colore. Andiamo
creare un coropleto che colora gli stati in base al numero di tweet che contengono i
Twitter gestisce. Innanzitutto, salva il file usstates.json di Folium in

ttps: //raw.githubusercontent.com/pythonvisualization/folium/master/examples/d ta / usst


o la cartella contenente questo esempio. Questo file contiene un dialetto JSON chiamato GeoJSON
(Geographic JSON) che descrive i confini delle forme, in questo caso i confini
di ogni stato degli Stati Uniti. Il coropleto usa queste informazioni per ombreggiare ogni stato. Per saperne di più
9
GeoJSON, vedi ttp: //geojson.org/ . I seguenti frammenti creano il coropleto, quindi
aggiungilo alla mappa:

9
Folium fornisce molti altri file GeoJSON nella sua cartella degli esempi in

ttps: //github.com/python
isualizzazione / folium / albero / master / examples / data . Puoi anche crearne uno tuo

hC
1vht

a
Pagina 759
ttp: //geojson.io .

lecca qui per visualizzare l'immagine del codice

In [33]: choropleth = folium.Choropleth (


...: geo_data = 'usstates.json' ,
...: name = 'choropleth' ,
...: data = tweets_counts_by_state,
...: colonne = [ "Stato" , "Tweet" ],
...: key_on = 'feature.id' ,
...: fill_color = 'YlOrRd' ,
...: fill_opacity = 0.7 ,
...: line_opacity = 0.2 ,
...: legend_name = 'Tweets by State'
...:) .add_to (usmap)
...:

In [34]: layer = folium.LayerControl (). Add_to (usmap)

In questo caso, abbiamo utilizzato i seguenti argomenti:

geo_data = 'usstates.json': questo è il file contenente GeoJSON che specifica


le forme da colorare.

name = 'choropleth': Folium visualizza il Choropleth come un livello sulla mappa.Questo


è il nome di quel livello che apparirà nei controlli dei livelli della mappa, che ti permettono di farlo
nascondi e mostra i livelli. Questi controlli vengono visualizzati quando si fa clic sull'icona dei livelli () nel file
carta geografica.

data = tweets_counts_by_state: questo è un DataFrame (o serie) dei panda


contenente i valori che determinano i colori coropletici.

colonne = ['State', 'Tweets'] - Quando i dati sono un DataFrame, questo è un elenco di


due colonne che rappresentano le chiavi ei valori corrispondenti utilizzati per colorare il file
Coropleto.

key_on = 'feature.id': questa è una variabile nel file GeoJSON a cui il file

Il coropleto lega i valori nell'argomento delle colonne.

fill_color = 'YlOrRd' — Questa è una mappa dei colori che specifica i colori da usare per riempire il
stati. Folium fornisce 12 mappe di colori: 'BuGn', 'BuPu', 'GnBu', 'OrRd', 'PuBu',
"PuBuGn", "PuRd", "RdPu", "YlGn", "YlGnBu", "YlOrBr" e "YlOrRd". tu
dovresti sperimentare con questi per trovare quelli più efficaci e accattivanti per il tuo
applicazione (i).

fill_opacity = 0.7: un valore compreso tra 0,0 (trasparente) e 1,0 (opaco) che specifica il valore
trasparenza dei colori di riempimento visualizzati negli stati.

line_opacity = 0.2: un valore compreso tra 0,0 (trasparente) e 1,0 (opaco) che specifica il valore
trasparenza delle linee utilizzate per delineare gli stati.

legend_name = 'Tweets by State': nella parte superiore della mappa, viene visualizzato il Choropleth
una barra dei colori (la legenda) che indica l'intervallo di valori rappresentato dai colori. Questo
Il testo nome_legenda appare sotto la barra dei colori per indicare cosa rappresentano i colori.

C
h

L'elenco completo degli argomenti delle parole chiave coropletiche è documentato in:
Pagina 760

ttp: //pythonvisualization.github.io/folium/modules.html#folium.features.Choro leth

ripetendo gli indicatori di mappa per ogni stato


Successivamente, creeremo Marker per ogni stato. Per garantire che i senatori siano visualizzati in
ordine decrescente per il numero di tweet nel Marker di ogni stato, ordiniamo

tweet_counts_df in ordine decrescente dalla colonna "Tweets":

lecca qui per visualizzare l'immagine del codice

In [35]: Sort_df = tweet_counts_df.sort_values ​(


...: by = 'Tweets' , crescente = False )
...:

Il ciclo nel seguente frammento crea i marcatori. Primo,

Sort_df.groupby ( "Stato" )

gruppi ordinati_df per 'Stato'. Il metodo groupby di un DataFrame mantiene l' originale
ordine delle righe in ogni gruppo. All'interno di un dato gruppo, il senatore con il maggior numero di tweet sarà il primo,
perché abbiamo ordinato i senatori in ordine decrescente in base al conteggio dei tweet nello snippet [35]:

lecca qui per visualizzare l'immagine del codice

In [36]: for index, (name, group) in enumerate (Sort_df.groupby ( 'State' )):


...: strings = [state_codes [nome]] # utilizzato per assemblare il testo popup
...:
...: per s in group.itertuples ():
...: strings.append (
...: strings.append (
...:
...: text = '<br>' .join (stringhe)
...: marker = folium.Marker (
...: (posizioni [indice] .latitudine, posizioni [indice] .longitudine),
...: popup = testo)
...: marker.add_to (usmap)
...:
...:

Passiamo il DataFrame raggruppato da enumerare, così possiamo ottenere un indice per ogni gruppo,
che useremo per cercare la posizione di ogni stato nell'elenco delle località.Ogni gruppo ha un file
nome (il codice dello stato che abbiamo raggruppato) e una raccolta di elementi in quel gruppo (i due senatori
per quello stato). Il ciclo funziona come segue:

Cerchiamo il nome completo dello stato nel dizionario state_codes, quindi lo memorizziamo nel file
elenco di stringhe: utilizzeremo questo elenco per assemblare il testo popup del marker.

Il ciclo annidato attraversa gli elementi nella raccolta di gruppi, restituendo ciascuno come file
tupla denominata che contiene i dati di un dato senatore. Creiamo una stringa formattata per
attuale senatore contenente il nome della persona, il partito e il numero di tweet, quindi aggiungere

C
C
h

quello alla lista delle stringhe.


Pagina 761

Il testo Marker può utilizzare HTML per la formattazione. Uniamo gli elementi della lista delle stringhe,
separandoli dal successivo con un elemento HTML <br> che crea una nuova riga in
HTML.

Creiamo il Marker. Il primo argomento è la posizione del Marker come tupla contenente
la latitudine e la longitudine. L'argomento della parola chiave popup specifica il testo da visualizzare se
l'utente fa clic sul marker.

Aggiungiamo il Marker alla mappa.

Visualizzazione della mappa


Infine, salviamo la mappa in un file HTML

lecca qui per visualizzare l'immagine del codice

In [17]: usmap.save ( 'SenatorsTweets.html' )

Apri il file HTML nel tuo browser web per visualizzare e interagire con la mappa. Ricordalo tu
può trascinare la mappa per vedere Alaska e Hawaii. Qui mostriamo il testo popup per il sud
Indicatore Carolina:
Potresti migliorare questo caso di studio per utilizzare le tecniche di analisi del sentiment che hai imparato
capitoli precedenti per valutare come positivo, neutro o negativo il sentimento espresso dalle persone
che inviano tweet ("tweeter") menzionando il nome di ogni senatore.

16.5 HADOOP
Le sezioni successive mostrano come Apache Hadoop e Apache Spark gestiscono i bigdata
sfide di archiviazione ed elaborazione tramite enormi cluster di computer, massicciamente paralleli
elaborazione, programmazione Hadoop MapReduce e tecniche di elaborazione in memoria Spark.
Qui, discutiamo di Apache Hadoop, una tecnologia di infrastruttura bigdata chiave che funge anche da
la base per molti recenti progressi nell'elaborazione di bigdata e un intero ecosistema

f strumenti software in continua evoluzione per supportare le esigenze odierne dei bigdata.
Pagina 762

16.5.1 Panoramica di Hadoop


Quando Google è stato lanciato nel 1998, la quantità di dati online era già enorme
0
circa 2,4 milioni di siti Web: veri big data. Oggi sono quasi due miliardi
1
siti web (aumento di quasi mille volte) e Google gestisce oltre duemila miliardi di ricerche
2
per anno! Avendo utilizzato la ricerca di Google sin dal suo inizio, la nostra sensazione è che le risposte di oggi
sono significativamente più veloci.

0
ttp: //www.internetlivestats.com/totalnumberofwebsites/ .

1
ttp: //www.internetlivestats.com/totalnumberofwebsites/ .

2
ttp: //www.internetlivestats.com/googlesearchstatistics/ .

Quando Google stava sviluppando il loro motore di ricerca, sapevano che dovevano tornare
risultati di ricerca rapidamente. L'unico modo pratico per farlo era archiviare e indicizzare l'intero file
Internet utilizzando una combinazione intelligente di memoria secondaria e memoria principale.Computer di
quel tempo non poteva contenere quella quantità di dati e non poteva analizzare quella quantità di dati velocemente
sufficiente per garantire risposte tempestive alle query di ricerca. Quindi Google ha sviluppato un clustering
sistema, collegando insieme un gran numero di computer, chiamati nodi . Perché avere di più
computer e più connessioni tra di loro significavano maggiori possibilità di guasti hardware,
hanno inoltre introdotto livelli elevati di ridondanza per garantire la continuità del sistema
funzionante anche se i nodi all'interno dei cluster falliscono. I dati sono stati distribuiti tra tutti questi
"computer di base" poco costosi. Per soddisfare una richiesta di ricerca, tutti i computer in
cluster ha cercato in parallelo la porzione di web che avevano localmente.Poi i risultati di quelli
le ricerche sono state raccolte e segnalate all'utente.

A tal fine, Google aveva bisogno di sviluppare l'hardware e il software di clustering,


compreso l'archiviazione distribuita. Google pubblica i suoi progetti, ma non li rende open source
Software. Programmatori di Yahoo !, lavorando sui progetti di Google nel "Google File System"
3
carta, quindi ha costruito il proprio sistema.Hanno aperto il loro lavoro e gli Apache
l'organizzazione ha implementato il sistema come Hadoop. Il nome deriva da un elefante imbottito
animale che apparteneva a un bambino di uno dei creatori di Hadoop.

3
ttp: //static.googleusercontent.com/media/research.google.com/en//archive/gf
osp2003.pdf .

Anche altri due articoli di Google hanno contribuito all'evoluzione di Hadoop: "MapReduce:
4
Elaborazione dati semplificata su cluster di grandi dimensioni "e" Bigtable: un sistema di archiviazione distribuito
5
per i dati strutturati ", che era la base per Apache HBase (un valore-chiave NoSQL e
6
database basato su colonne).

4
ttp: //static.googleusercontent.com/media/research.google.com/en//archive/ma ridurre
sdi04.pdf .

5
ttp: //static.googleusercontent.com/media/research.google.com/en//archive/bi tavolo
sdi06.pdf .

6
Possono esserlo molti altri articoli influenti su grandi temi (compresi quelli che abbiamo menzionato)

2o
ghpS

Trovato a:
Pagina 763
ttps: //bigdatamadesimple.com/researchpapersthatchanged
heworldofbigdata / .

DFS, MapReduce e YARN


I componenti chiave di Hadoop sono:

HDFS (Hadoop Distributed File System) per l'archiviazione di enormi quantità di dati
in tutto un cluster, e

MapReduce per implementare le attività che elaborano i dati.

In precedenza nel libro abbiamo introdotto la programmazione dello stile funzionale di base e il filtro / mappa / riduzione.
Hadoop MapReduce è simile nel concetto, solo su una scala massicciamente parallela. Un MapReduce
l'attività esegue due passaggi: mappatura e riduzione . La fase di mappatura, che può anche
include il filtraggio , elabora i dati originali nell'intero cluster e li mappa in tuple
di coppie chiave-valore. La fase di riduzione combina quindi quelle tuple per produrre i risultati di
l'attività MapReduce. La chiave è come viene eseguito il passaggio MapReduce. Hadoop divide il file
i dati in batch che distribuisce tra i nodi del cluster, ovunque da pochi
7
nodi a un Yahoo! cluster con 40.000 nodi e oltre 100.000 core. Anche Hadoop
distribuisce il codice dell'attività MapReduce ai nodi del cluster ed esegue il codice in formato
parallelo su ogni nodo. Ogni nodo elabora solo il batch di dati archiviati su quel nodo.Il
la fase di riduzione combina i risultati di tutti i nodi per produrre il risultato finale. Per
coordinare questo, Hadoop utilizza YARN ("l'ennesimo negoziatore di risorse") per gestire tutto
le risorse nel cluster e pianificare le attività per l'esecuzione.

7
ttps: //wiki.apache.org/hadoop/PoweredBy .

Ecosistema Hadoop
Sebbene Hadoop sia iniziato con HDFS e MapReduce, seguito da vicino da YARN, è cresciuto
in un grande ecosistema che include Spark (discusso in ezioni 16.6- 6.7 ) e molti altri
8 9 0
Progetti Apache:,,

8
ttps: //hortonworks.com/ecosystems/ .

9
ttps: //readwrite.com/2018/06/26/completeguideofhadoop
cosystemcomponents / .

0
ttps: //www.janbasktraining.com/blog/introductionarchitecture
omponentshadoopecosystem / .

Ambari ( ttps: //ambari.apache.org ): strumenti per la gestione dei cluster Hadoop.

Trapano ( ttps: //drill.apache.org ): query SQL di dati non relazionali in Hadoop


e database NoSQL.

Flume ( ttps: //flume.apache.org ) : un servizio per la raccolta e l'archiviazione (in HDFS


e altro storage) dati di eventi in streaming, come log di server ad alto volume, messaggi IoT e
Di Più.

HBase ( ttps: //hbase.apache.org ) —Un database NoSQL per big data con “miliardi

H
1

het1S
32c

1
f righe per milioni di colonne, in cima a gruppi di hardware di base. "
Pagina 764

1
Abbiamo usato la parola by per sostituire X nel testo originale.

Alveare ( ttps: //hive.apache.org ) : utilizza SQL per interagire con i dati nei dati
magazzini. Un data warehouse aggrega dati di vario tipo da varie fonti.
Le operazioni comuni includono l'estrazione dei dati, la trasformazione e il caricamento (noto come ETL )
in un altro database, in genere in modo da poterlo analizzare e creare rapporti da esso.

Impala ( ttps: //impala.apache.org ) —Un database per realtime basato su SQL


query sui dati distribuiti archiviati in Hadoop HDFS o HBase.

Kafka ( ttps: //kafka.apache.org ): messaggistica in tempo reale, elaborazione in streaming e


archiviazione, in genere per trasformare ed elaborare dati di streaming ad alto volume, come il sito web
attività e streaming di dati IoT.

Maiale (ttps: //pig.apache.org ) : una piattaforma di scripting che converte l'analisi dei dati
task da un linguaggio di scripting chiamato Pig Latin in MapReduce tasks.

Sqoop ( ttps: //sqoop.apache.org ): strumento per lo spostamento strutturato, semistrutturato


e dati non strutturati tra database.

Tempesta ( ttps: //storm.apache.org ): un sistema di elaborazione dello streaming in tempo reale per
attività come analisi dei dati, apprendimento automatico, ETL e altro ancora.

ZooKeeper ( ttps: //zookeeper.apache.org ) : un servizio per la gestione del cluster


configurazioni e coordinamento tra i cluster.

E altro ancora.

Provider Hadoop
Numerosi fornitori di cloud forniscono Hadoop come servizio, tra cui Amazon EMR, Google Cloud
DataProc, IBM Watson Analytics Engine, Microsoft Azure HDInsight e altri. Inoltre,
aziende come Cloudera e Hortonworks (che al momento in cui scrivo si stanno fondendo)
offrire componenti e strumenti Hadoopecosystem integrati tramite i principali fornitori di cloud.Essi
2
offrono anche ambienti scaricabili gratuitamente che puoi eseguire sul desktop per l'apprendimento,
sviluppo e test prima di impegnarsi per l'hosting basato su cloud, che possono incorrere in
costi significativi. Introduciamo la programmazione MapReduce nell'esempio seguente
sezioni utilizzando un cluster Azure HDInsight basato su cloud Microsoft, che fornisce Hadoop
come servizio.

2
Verificare prima i requisiti di sistema significativi per assicurarsi di disporre di spazio su disco e
memoria necessaria per eseguirli.

Hadoop 3
3
Apache continua a far evolvere Hadoop. Hadoop 3 è stato rilasciato nel dicembre 2017 con
molti miglioramenti, tra cui prestazioni migliori e archiviazione notevolmente migliorata
4
efficienza.

3
Per un elenco delle funzionalità di Hadoop 3, vedere
ttps: //hadoop.apache.org/docs/r3.0.0/ .

4
3o
h
4 Pagina 765
ttps: //www.datanami.com/2018/10/18/ishadoopofficiallydead/ .

16.5.2 Riassumere le lunghezze delle parole in Romeo e Giulietta tramite MapReduce

Nelle successive sottosezioni, creerai un cluster di computer multinodo basato su cloud


utilizzando Microsoft Azure HDInsight. Quindi, utilizzerai le funzionalità del servizio per dimostrare
Hadoop MapReduce in esecuzione su quel cluster. L'attività MapReduce che definirai lo farà
determinare la lunghezza di ogni parola in RomeoAndJuliet.txt (dal " Linguaggio naturale
rocessing ”capitolo), quindi riassumono quante parole di ogni lunghezza ci sono.Dopo
definendo i passaggi di mappatura e riduzione dell'attività, invierai l'attività al tuo HDInsight
cluster e Hadoop deciderà come utilizzare il cluster di computer per eseguire l'attività.

16.5.3 Creazione di un cluster Apache Hadoop in Microsoft Azure HDInsight

La maggior parte dei principali fornitori di cloud ha il supporto per i cluster di elaborazione Hadoop e Spark
può essere configurato per soddisfare i requisiti dell'applicazione. Cluster basati su cloud multinodo
in genere sono servizi a pagamento , sebbene la maggior parte dei fornitori fornisca prove o crediti gratuiti in modo che tu possa provare
i loro servizi.

Vogliamo che tu possa sperimentare il processo di creazione di cluster e utilizzarli per eseguire
compiti. Quindi, in questo esempio Hadoop, userai il servizio HDInsight di Microsoft Azure per creare
cluster di computer basati su cloud in cui testare i nostri esempi. Vai a

ttps: //azure.microsoft.com/enus/free
per registrarsi per un account. Microsoft richiede una carta di credito per la verifica dell'identità.

Vari servizi sono sempre gratuiti e alcuni si possono continuare a utilizzare per 12 mesi. Per
informazioni su questi servizi vedere:

ttps: //azure.microsoft.com/enus/free/freeaccountfaq/

Microsoft ti dà anche un credito per sperimentare i loro servizi a pagamento , come il loro
Servizi Hadoop e Spark di HDInsight. Una volta esauriti i crediti o trascorsi 30 giorni (a seconda di quale
viene prima), non puoi continuare a utilizzare i servizi a pagamento a meno che non autorizzi Microsoft a farlo
carica la tua carta.

5
Poiché utilizzerai il credito del tuo nuovo account Azure per questi esempi, discuteremo come farlo
configurare un cluster a basso costo che utilizzi meno risorse di elaborazione rispetto a quelle allocate da Microsoft
6
predefinito. Attenzione: una volta allocato un cluster, comporta dei costi indipendentemente dal fatto che tu lo sia
usarlo o no. Quindi, quando completi questo case study, assicurati di eliminare il tuo
cluster e altre risorse, in modo da non incorrere in costi aggiuntivi. Per più
informazioni, vedere:

5
Per le ultime funzionalità dell'account gratuito di Microsoft, visita
ttps: //azure.microsoft.com/en
s / libero / .

6
Per le configurazioni cluster consigliate da Microsoft, vedere
ttps: //docs.microsoft.com/enus/azure/hdinsight/hdinsight
componentversioning # defaultnodeconfigurationandvirtualmachine

PuhN
3h

izesforclusters . Se configuri un cluster troppo piccolo per un determinato scenario, quando


Pagina 766
se provi a distribuire il cluster riceverai un errore.

ttps: //docs.microsoft.com/enus/azure/azureresourcemanager/resourcegrouppo tal

o documentazione e video relativi a Azurer, visitare:

ttps: //docs.microsoft.com/enus/azure/: la documentazione di Azure.

ttps: //channel9.msdn.com/ - Rete video di Microsoft Channel 9.

ttps: //www.youtube.com/user/windowsazure: il canale Azure di Microsoft attivo


Youtube.

Creazione di un cluster Hadoop HDInsight


Il collegamento seguente spiega come configurare un cluster per Hadoop usando Azure HDInsight
servizio:

ttps: //docs.microsoft.com/enus/azure/hdinsight/hadoop/apachehadooplinuxcre teclust

hile seguendo i passaggi Crea un cluster Hadoop, tieni presente quanto segue:

Nel passaggio 1 si accede al portale di Azure accedendo al proprio account all'indirizzo

ttps: //portal.azure.com

Nel passaggio 2 , Data + Analytics è ora denominato Analytics e l'icona e l'icona HDInsight
il colore è cambiato rispetto a quanto mostrato nel tutorial.

Nel passaggio 3 , è necessario scegliere un nome di cluster che non non esiste già. Quando entri
il nome del tuo cluster, Microsoft verificherà se quel nome è disponibile e visualizzerà un file
messaggio se non lo è. Devi creare una password. Per il gruppo di risorse, farai anche
è necessario fare clic su Crea nuovo e fornire un nome di gruppo. Lascia tutte le altre impostazioni in questo passaggio
come è.

Al passaggio 5 : in Seleziona un account di archiviazione, fai clic su Crea nuovo e fornisci uno spazio di archiviazione
nome account contenente solo lettere minuscole e numeri.Come il nome del cluster, il
il nome dell'account di archiviazione deve essere univoco.
Quando arrivi al riepilogo del cluster, vedrai che Microsoft inizialmente configura il file
cluster come Head (2 x D12 v2), Worker (4 x D4 v2). Al momento della stesura di questo articolo, il
il costo orario stimato per questa configurazione era di $ 3,11. Questa configurazione utilizza un totale di 6 CPU
nodi con 40 core, molto più di quanto ci serve per scopi dimostrativi.

Puoi modificare questa configurazione per utilizzare meno CPU e core, risparmiando anche denaro. Facciamo cambio
la configurazione a un cluster di quattro CPU con 16 core che utilizza computer meno potenti.Nel
il riepilogo del cluster:

W
F
S
hh

1. Fare clic su Modifica a destra di Dimensione cluster.


Pagina 767

2. Modificare il Numero di nodi di lavoro su 2.

3. Fare clic su Dimensione nodo di lavoro, quindi su Visualizza tutto, selezionare D3 v2 (questa è la dimensione minima della CPU per
Nodi Hadoop) e fare clic su Seleziona.

4. Fare clic su Dimensioni nodo Head, quindi su Visualizza tutto, selezionare D3 v2 e fare clic su Seleziona.

5. Fare clic su Avanti e di nuovo su Avanti per tornare al riepilogo del cluster. Microsoft lo farà
convalidare la nuova configurazione.

6. Quando il pulsante Crea è abilitato, fare clic su di esso per distribuire il cluster.

Microsoft impiega 20-30 minuti per "avviare" il cluster. Durante questo periodo, Microsoft lo è
allocando tutte le risorse e il software richiesto dal cluster.

Dopo le modifiche di cui sopra, il nostro costo stimato per il cluster era di $ 1,18 l'ora, in base a
utilizzo medio per cluster configurati in modo simile. I nostri addebiti effettivi erano inferiori. Se tu
si verificano problemi durante la configurazione del cluster, Microsoft fornisce HDInsight basato sulla chat
supporto a:

ttps: //azure.microsoft.com/enus/resources/knowledgecenter/technicalchat/

16.5.4 Streaming Hadoop


Per linguaggi come Python che non sono supportati in modo nativo in Hadoop, devi usare Hadoop
streaming per implementare le tue attività. Nello streaming Hadoop, Python scrive che
implementare le fasi di mappatura e riduzione utilizzare il flusso di input standard e
flusso di output standard per comunicare con Hadoop. Di solito, lo standard input
stream legge dalla tastiera e il flusso di output standard scrive sulla riga di comando.
Tuttavia, questi possono essere reindirizzati (come fa Hadoop) per leggere da altre fonti e scrivere su
altre destinazioni. Hadoop utilizza i flussi come segue:

Hadoop fornisce l'input allo script di mappatura, chiamato mappatore . Questo script legge
il suo input dal flusso di input standard.

Il mappatore scrive i suoi risultati nel flusso di output standard.

Hadoop fornisce l'output del mapper come input per lo script di riduzione, chiamato
riduttore: che legge dal flusso di input standard.

Il riduttore scrive i suoi risultati nel flusso di output standard.

Hadoop scrive l'output del riduttore nel file system Hadoop (HDFS).

La terminologia del mappatore e del riduttore usata sopra dovrebbe suonarvi familiare dal nostro
discussioni sulla programmazione in stile funzionale e filtro, mappatura e riduzione nelle "Sequenze:
Capitolo Liste e tuple ".

1h 6.5.5 Implementazione del Mapper

16.5.5 Implementazione del mapping Pagina 768

In questa sezione, creerai uno script mapper che accetta righe di testo come input da Hadoop e
li associa a coppie chiave-valore in cui ogni chiave è una parola e il valore corrispondente è 1.
Il mappatore vede ogni parola individualmente quindi, per quanto la riguarda, ce n'è solo una per ciascuna
parola. Nella sezione successiva, il riduttore riassumerà queste coppie chiave - valore per chiave, riducendole
i conteggi a un singolo conteggio per ogni chiave. Per impostazione predefinita, Hadoop si aspetta l'output del mapper e
l'input e l'output del riduttore devono essere sotto forma di coppie chiave - valore separate da una tabulazione .

Nello script mapper (length_mapper.py), la notazione #! nella riga 1 dice a Hadoop di eseguire
il codice Python usando python3, piuttosto che l'installazione predefinita di Python 2. Questa linea deve
viene prima di tutti gli altri commenti e codice nel file. Al momento della stesura di questo articolo, Python 2.7.12
e Python 3.5.2 sono stati installati. Nota che poiché il cluster non ha Python 3.6 o
superiore, non è possibile utilizzare fstrings nel codice.

lecca qui per visualizzare l'immagine del codice

1 #! / Usr / bin / env python3


2 # length_mapper.py
3 "" "Associa le righe di testo a coppie di valori-chiave di lunghezza di parole e 1." ""
4 import sys
5
6 def tokenize_input ():
7 "" "Dividi ogni riga di input standard in un elenco di stringhe." ""
8 per la riga in sys.stdin:
9 rendimento line.split ()
10
11 # legge ogni riga nello standard input e per ogni parola
12 # produce una coppia di valori-chiave contenente la parola, una tabulazione e 1
13 per la riga in tokenize_input ():
14 per parola in linea:
15 print (str (len (word)) + '\ t1' )

La funzione generatore tokenize_input (righe 6–9) legge righe di testo dallo standard input
stream e per ciascuno restituisce un elenco di stringhe. Per questo esempio, non stiamo rimuovendo
punteggiatura o interrompi parole come abbiamo fatto nella
capitolo
" sull'elaborazione del linguaggio naturale ”.

Quando Hadoop esegue lo script, le righe 13-15 ripetono gli elenchi di stringhe da
tokenize_input. Per ogni lista (riga) e per ogni stringa (parola) in quella lista, riga 15
restituisce una coppia chiave-valore con la lunghezza della parola come chiave, una tabulazione (\ t) e il valore 1,
indicando che c'è una parola (finora) di quella lunghezza. Certo, probabilmente ce ne sono molti
parole di quella lunghezza. Il passaggio di riduzione dell'algoritmo MapReduce riassumerà queste chiavi:
coppie valore, riducendo tutte quelle con la stessa chiave a una singola coppia chiave-valore con il totale
contare.

16.5.6 Implementazione del riduttore

Nello script del riduttore (length_reducer.py), la funzione tokenize_input (righe 8-11) è una
funzione di generatore che legge e divide lecoppie chiave - valore prodotte dal mappatore. Ancora,
l'algoritmo MapReduce fornisce lo standard input. Per ogni riga, tokenize_input
rimuove qualsiasi spazio bianco iniziale o finale (come la nuova riga di terminazione) e restituisce un elenco
contenente la chiave e un valore.

lecca qui per visualizzare l'immagine del codice

N
C
Pagina 769
1 #! / Usr / bin / env python3
2 # length_reducer.py
3 "" "Conta il numero di parole con ciascuna lunghezza." ""
4 import sys
5 da itertools importa groupby
6 da operatore import itemgetter
7
8 def tokenize_input ():
9 "" "Dividi ogni riga di input standard in una chiave e un valore." ""
10 per la riga in sys.stdin:
11 rendimento line.strip (). Split ( '\ t' )
12
13 # produce coppie di valori-chiave di lunghezze di parole e conteggi separati da tabulazioni
14 per word_length, group in groupby (tokenize_input (), itemgetter ( 0 )):
15 prova :
16 total = sum (int (count) for word_length, count in group)
17 print (word_length + '\ t' + str (total))
18 tranne ValueError:
19 pass # ignora la parola se il suo conteggio non era un numero intero

Quando l'algoritmo MapReduce esegue questo riduttore, le righe 14-19 utilizzano la funzione groupby
dal modulo itertools per raggruppare tutte le lunghezze di parola dello stesso valore:

Il primo argomento chiama tokenize_input per ottenere gli elenchi che rappresentano il valore - chiave
coppie.

Il secondo argomento indica che le coppie chiave - valore devono essere raggruppate in base a
elemento all'indice 0 in ogni elenco: questa è la chiave.

La riga 16 somma tutti i conteggi per una determinata chiave. La riga 17 restituisce una nuova coppia chiave - valore composta da
della parola e del suo totale. L'algoritmo MapReduce prende tutti gli output finali del conteggio parole
e li scrive in un file in HDFS, il file system Hadoop.

16.5.7 Preparazione per eseguire l'esempio di MapReduce

Successivamente, caricherai i file nel cluster in modo da poter eseguire l'esempio.In un comando
Prompt, Terminal o shell, passare alla cartella contenente gli script del mappatore e del riduttore
e il file RomeoAndJuliet.txt. Assumiamo che tutti e tre siano nel capitolo 16 di questo capitolo
cartella examples, quindi assicurati di copiare prima il tuo file RomeoAndJuliet.txt in questa cartella.

Copia dei file di script nel cluster Hadoop HDInsight


Immettere il seguente comando per caricare i file. Assicurati di sostituire YourClusterName con
il nome del cluster che hai specificato durante la configurazione del cluster Hadoop e premi Invio solo dopo
hai digitato l'intero comando. I due punti nel seguente comando sono obbligatori e
indica che fornirai la password del tuo cluster quando richiesto. A quel prompt, digita
password specificata durante la configurazione del cluster, quindi premere Invio :

lecca qui per visualizzare l'immagine del codice

scp length_mapper.py length_reducer.py RomeoAndJuliet.txt


sshuser @ YourClusterName ssh.azurehdinsight.net:

La prima volta che lo fai, ti verranno chiesti motivi di sicurezza per confermare che ti fidi del

host di destinazione (ovvero Microsoft Azure).


Pagina 770

Copia di RomeoAndJuliet nel file system Hadoop


Affinché Hadoop legga i contenuti di RomeoAndJuliet.txt e fornisca le righe di testo a
7
il tuo mappatore, devi prima copiare il file nel file system di Hadoop.Innanzitutto, devi usare ssh
per accedere al tuo cluster e accedere alla sua riga di comando.In un prompt dei comandi, terminale o
shell, esegui il seguente comando. Assicurati di sostituire YourClusterName con il tuo cluster
nome. Ancora una volta, ti verrà richiesta la password del cluster:

7
Utenti Windows: se ssh non funziona, installalo e abilitalo come descritto in

ttps: //blogs.msdn.microsoft.com/powershell/2017/12/15/usingthe
opensshbetainwindows10fallcreatorsupdateandwindowsserver
709 / . Dopo aver completato l'installazione, disconnettersi e accedere nuovamente o riavviare il sistema su
abilitare ssh.

lecca qui per visualizzare l'immagine del codice

ssh sshuser @ YourClusterName ssh.azurehdinsight.net

Per questo esempio, utilizzeremo il seguente comando Hadoop per copiare il file di testo nel file
cartella / esempi / dati già esistenti che il cluster fornisce per l'utilizzo con Microsoft

Esercitazioni su Azure Hadoop. Di nuovo, premi Invio solo dopo aver digitato l'intero comando:

lecca qui per visualizzare l'immagine del codice

hadoop fs copyFromLocal RomeoAndJuliet.txt


/example/data/RomeoAndJuliet.txt

16.5.8 Esecuzione del lavoro MapReduce

Ora puoi eseguire il lavoro MapReduce per RomeoAndJuliet.txt sul tuo cluster da
eseguendo il seguente comando. Per tua comodità, abbiamo fornito il testo di questo
comando nel file filato.txt con questo esempio, così puoi copiarlo e incollarlo. Noi
ha riformattato il comando qui per leggibilità:

lecca qui per visualizzare l'immagine del codice

barattolo di filato /usr/hdp/current/hadoopmapreduceclient/hadoopstreaming.jar


D mapred.output.key.comparator.class =
org.apache.hadoop.mapred.lib.KeyFieldBasedComparator
D mapred.text.key.comparator.options = n
file length_mapper.py, length_reducer.py
mapper length_mapper.py
riduttore length_reducer.py
input /example/data/RomeoAndJuliet.txt
output / esempio / wordlengthsoutput

Il comando filato richiama lo strumento YARN di Hadoop ("l'ennesimo negoziatore di risorse") per

gestire e coordinare l'accesso alle risorse Hadoop utilizzate dall'attività MapReduce. Il file
hadoopstreaming.jar contiene l'utilità di streaming Hadoop che ti consente di utilizzare
Python per implementare il mappatore e il riduttore. Le due opzioni D impostano le proprietà di Hadoop

C
3h
1

che gli consentono di ordinare le coppie chiave - valore finali per chiave (KeyFieldBasedComparator) in
Pagina 771

ordine decrescente numericamente (n; il meno indica l'ordine decrescente) anziché


in ordine alfabetico. Gli altri argomenti della riga di comando sono:

file: un elenco di nomi di file separati da virgole.Hadoop copia questi file su ogni nodo
nel cluster in modo che possano essere eseguiti localmente su ogni nodo.

mapper: il nome del file di script del mapper.

riduttore: il nome del file di script del riduttore

input: il file o la directory di file da fornire come input al mapper.

output: la directory HDFS in cui verrà scritto l'output.Se questa cartella è già
esiste, si verificherà un errore.

L'output seguente mostra alcuni feedback che Hadoop produce come MapReduce
il lavoro viene eseguito. Abbiamo sostituito parti dell'output con per risparmiare spazio e abbiamo messo in grassetto diverse righe di
interesse tra cui:

Il numero totale di "percorsi di input da elaborare": la prima sorgente di input in questo esempio è

RomeoAndJuliet.txt file.

Il "numero di suddivisioni" —2 in questo esempio, in base al numero di nodi di lavoro nel nostro
grappolo.

Le informazioni sulla percentuale di completamento.

Contatori del file system, che includono il numero di byte letti e scritti.

Contatori lavoro, che mostrano il numero di attività di mappatura e riduzione utilizzate e


varie informazioni sui tempi.

MapReduce Framework, che mostra varie informazioni sui passaggi eseguiti.

lecca qui per visualizzare l'immagine del codice

ackageJobJar: [] [/usr/hdp/2.6.5.300413/hadoopmapreduce/hadoopstreaming2.7.3.2.6.
...
18/12/05 16:46:25 INFO mapred.FileInputFormat: Totale percorsi di input da elaborare: 1
18/12/05 16:46:26 INFO mapreduce.JobSubmitter: numero di split: 2
...
18/12/05 16:46:26 INFO mapreduce.Job: L'URL per monitorare il lavoro: http: //hn0paulte.y3
...
18/12/05 16:46:35 INFO mapreduce.Job: map 0% reduce 0%
18/12/05 16:46:43 INFO mapreduce.Job: map 50% reduce 0%
18/12/05 16:46:44 INFO mapreduce.Job: map 100% reduce 0%
18/12/05 16:46:48 INFO mapreduce.Job: map 100% reduce 100%
18/12/05 16:46:50 INFO mapreduce.Job: Job job_1543953844228_0025 completato con successo
18/12/05 16:46:50 INFO mapreduce.Job: Counters: 49
Contatori del file system
FILE: numero di byte letti = 156411
FILE: numero di byte scritti = 813764
...
Contatori di lavoro

Attività mappa avviate = 2 Pagina 772


Attività di riduzione avviate = 1
...
MapReduce Framework
Record di input mappa = 5260
Record output mappa = 25956
Byte output mappa = 104493
Byte materializzati output mappa = 156417
Byte suddivisi in input = 346
Combina record di input = 0
Combina record di output = 0
Riduci gruppi di input = 19
Riduci byte shuffle = 156417
Riduci record di input = 25956
Riduci record di output = 19
Record sparsi = 51912
Mappe mescolate = 2
Casuali non riusciti = 0
Uscite mappa unite = 2
Tempo GC trascorso (ms) = 193
Tempo di CPU impiegato (ms) = 4440
Snapshot della memoria fisica (byte) = 1942798336
Snapshot della memoria virtuale (byte) = 8463282176
Utilizzo dell'heap vincolato totale (byte) = 3177185280
...
18/12/05 16:46:50 INFO streaming.StreamJob: directory di output: / example / wordlengthsoutp

Ispezione dei conteggi di parole


Hadoop MapReduce salva il suo output in HDFS, quindi per vedere il conteggio delle parole effettivo è necessario
guarda il file in HDFS all'interno del cluster eseguendo il seguente comando:

lecca qui per visualizzare l'immagine del codice

hdfs dfs text / example / wordlengthsoutput / part00000

Ecco i risultati del comando precedente:

lecca qui per visualizzare l'immagine del codice

8/12/05 16:47:19 INFO lzo.GPLNativeCodeLoader: libreria gpl nativa caricata


18/12/05 16:47:19 INFO lzo.LzoCodec: nativelzo libr
1 1140
2 3869
3 4699
4 5651
5 3668
6 2719
7 1624
8 1062
9 855
10 317
11 189
12 95
13 35
14 13
15 9
16 6
17 3
18 1
23 1

V
C
Pagina 773

Eliminazione del cluster in modo da non incorrere in addebiti

Attenzione: assicurati di eliminare i tuoi cluster e le risorse associate (come


archiviazione) in modo da non incorrere in costi aggiuntivi. Nel portale di Azure fare clic su Tutto
risorse per vedere il tuo elenco di risorse, che includerà il cluster che hai configurato e il file
account di archiviazione impostato. Entrambi possono incorrere in costi se non vengono eliminati. Seleziona ciascuno
risorsa e fare clic sul pulsante Elimina per rimuoverla. Ti verrà chiesto di confermare digitando sì.
Per ulteriori informazioni, vedere:

ttps: //docs.microsoft.com/enus/azure/azureresourcemanager/resourcegrouppo tal

6.6 SCINTILLA
In questa sezione, faremo una panoramica di Apache Spark. Useremo la libreria Python PySpark e
Le funzionalità di filtro / mappa / riduzione dello stile funzionale di Spark per implementare un semplice conteggio delle parole
esempio che riassume la parola conta in Romeo e Giulietta .

16.6.1 Panoramica di Spark


Quando si elaborano veri big data, le prestazioni sono fondamentali. Hadoop è orientato a diskbased
elaborazione batch: lettura dei dati dal disco, elaborazione dei dati e scrittura dei risultati
torna su disco. Molte applicazioni bigdata richiedono prestazioni migliori di quelle possibili
operazioni diskintensive. In particolare, applicazioni di streaming veloce che richiedono sia real
l'elaborazione time o nearrealtime non funzionerà in un'architettura basata su disco.

Storia
Spark è stato inizialmente sviluppato nel 2009 presso la U. C. Berkeley e finanziato da DARPA (the Defense
Agenzia per progetti di ricerca avanzata). Inizialmente, è stato creato come esecuzione distribuita
8
motore per machine learning ad alte prestazioni. Utilizza un'architettura inmemory che
"È stato utilizzato per ordinare 100 TB di dati 3 volte più velocemente di Hadoop MapReduce su 1/10 del
9 0
macchine "ed esegue alcuni carichi di lavoro fino a 100 volte più velocemente di Hadoop. Spark's
prestazioni notevolmente migliori nelle attività di elaborazione batch stanno portando molte aziende a
1 2 3
sostituire Hadoop MapReduce con Spark. ,

8
ttps: //gigaom.com/2014/06/28/4reasonswhysparkcouldjolt
adoopintohyperdrive / .

9
ttps: //spark.apache.org/faq.html .

0
ttps: //spark.apache.org/ .

1
ttps: //bigdatamadesimple.com/issparkbetterthanhadoopmap
educe / .

2
ttps: //www.datanami.com/2018/10/18/ishadoopofficiallydead/ .

3
ttps: //blog.thecodeteam.com/2018/01/09/changingfacedata
nalyticsfastdatadisplacesbigdata / .

1
UN
43un'
hrh
architettura e componenti

architettura e componenti Pagina 774

Sebbene sia stato inizialmente sviluppato per funzionare su Hadoop e utilizzare componenti Hadoop come HDFS
e YARN, Spark può essere eseguito autonomamente su un singolo computer (in genere per l'apprendimento e il test
scopi), autonomo su un cluster o utilizzando vari gestori di cluster e archiviazione distribuita
sistemi. Per la gestione delle risorse, Spark funziona su Hadoop YARN, Apache Mesos, Amazon
EC2 e Kubernetes e supporta molti sistemi di archiviazione distribuiti, tra cui HDFS,
4
Apache Cassandra, Apache HBase e Apache Hive.

4
ttp: //spark.apache.org/ .

Al centro di Spark ci sono i set di dati distribuiti resilienti (RDD) , che utilizzerai per
elaborare i dati distribuiti utilizzando la programmazione in stile funzionale. Oltre a leggere i dati
dal disco e la scrittura dei dati su disco, Hadoop utilizza la replica per la tolleranza agli errori, che aggiunge
sovraccarico ancora di più basato su disco. Gli RDD eliminano questo sovraccarico rimanendo in memoria—
utilizzando il disco solo se i dati non si adattano alla memoria e non replicando i dati. Maniglie Spark
tolleranza agli errori ricordando i passaggi utilizzati per creare ogni RDD, in modo che possa ricostruire un dato
5
RDD se un nodo del cluster non riesce.

5
ttps: //spark.apache.org/research.html .

Spark distribuisce le operazioni specificate in Python ai nodi del cluster per il parallelo
esecuzione. Spark streaming ti consente di elaborare i dati non appena vengono ricevuti.Spark DataFrames,
che sono simili ai DataFrame di panda, ti consentono di visualizzare gli RDD come una raccolta di file
colonne denominate. Puoi usare Spark DataFrames con Spark SQL per eseguire query su
dati distribuiti. Spark include anche Spark MLlib (la libreria Spark Machine Learning),
che ti consente di eseguire algoritmi di apprendimento automatico, come quelli in cui hai imparato
hapters 14 e 5 . Nel prossimo utilizzo useremo RDD, Spark streaming, DataFrames e Spark SQL
pochi esempi.

Fornitori
I provider Hadoop in genere forniscono anche il supporto Spark. Oltre ai fornitori elencati in
Sezione 16.5 , ci sono fornitori specifici per Spark come Databricks. Forniscono uno "zero
6
piattaforma cloud di gestione basata su Spark ". Anche il loro sito web è un'ottima risorsa
per imparare a usare Spark. La piattaforma Databricks a pagamento viene eseguita su Amazon AWS o Microsoft Azure.
Databricks fornisce anche una Databricks Community Edition gratuita, che è un ottimo modo per ottenere
iniziato con Spark e l'ambiente Databricks.

6
ttps: //databricks.com/product/faq .

16.6.2 Docker e gli stack Docker di Jupyter


In questa sezione, mostreremo come scaricare ed eseguire uno stack Docker contenente Spark e
il modulo PySpark per accedere a Spark da Python. Scriverai il codice di esempio di Spark
in un taccuino Jupyter. Per prima cosa, esaminiamo Docker.

Docker
Docker è uno strumento per confezionare software in contenitori (chiamati anche immagini ) che raggruppano
tutto il necessario per eseguire quel software su più piattaforme. Alcuni pacchetti software che abbiamo
l'uso in questo capitolo richiede installazione e configurazione complicate. Per molti di questi ci sono

4UN
1ShC

container Docker preesistenti che puoi scaricare gratuitamente ed eseguire localmente sul tuo file
Pagina 775

computer desktop o notebook. Questo rende Docker un ottimo modo per aiutarti a iniziare
nuove tecnologie rapidamente e comodamente.

Docker aiuta anche con la riproducibilità negli studi di ricerca e analisi. Puoi creare
contenitori Docker personalizzati configurati con le versioni di ogni software e
ogni libreria che hai usato nel tuo studio. Ciò consentirebbe ad altri di ricreare l'ambiente
hai usato, quindi riproduci il tuo lavoro e ti aiuterà a riprodurre i tuoi risultati in un secondo momento.
Useremo Docker in questa sezione per scaricare ed eseguire un container Docker che è
preconfigurato per eseguire applicazioni Spark.

Installazione di Docker
Puoi installare Docker per Windows 10 Pro o macOS su:

ttps: //www.docker.com/products/dockerdesktop

In Windows 10 Pro, è necessario consentire al programma di installazione "Docker per Windows.exe" di creare
modifiche al sistema per completare il processo di installazione. A tale scopo, fare clic su Sì quando
7
Windows chiede se si desidera consentire al programma di installazione di apportare modifiche al sistema.finestre
10 Gli utenti domestici devono utilizzare Virtual Box come descritto in:

7
Alcuni utenti Windows potrebbero dover seguire le istruzioni in Consenti ad app specifiche di
apportare modifiche alle cartelle controllate in ttps: //docs.microsoft.com/en
us / windows / security / threatprotection / windowsdefenderexploit
uard / customizecontrolledfoldersexploitguard .

ttps: //docs.docker.com/machine/drivers/virtualbox/

Gli utenti Linux devono installare Docker Community Edition come descritto in:

ttps: //docs.docker.com/install/overview/

Per una panoramica generale di Docker, leggi la Guida introduttiva su:

ttps: //docs.docker.com/getstarted/

Stack Docker di Jupyter


Il team di Jupyter Notebooks ha preconfigurato diversi contenitori Jupyter "Docker stack"
per scenari di sviluppo Python comuni. Ciascuno ti consente di utilizzare i notebook Jupyter per
sperimentare potenti funzionalità senza doversi preoccupare della complessa configurazione del software
problemi. In ogni caso, puoi aprire JupyterLab nel tuo browser web, aprire un taccuino in
JupyterLab e inizia a scrivere codice. JupyterLab fornisce anche una finestra di terminale che puoi
utilizzare nel browser come il terminale del computer, il prompt dei comandi di Anaconda o la shell.
Tutto ciò che ti abbiamo mostrato in IPython fino a questo punto può essere eseguito utilizzando IPython in
Finestra del terminale di JupyterLab.

Useremo lo stack Docker jupyter / pysparknotebook, che è preconfigurato con

4g
hh

tutto ciò di cui hai bisogno per creare e testare le app Apache Spark sul tuo computer.Quando combinato
Pagina 776
con l'installazione di altre librerie Python che abbiamo usato in tutto il libro, puoi implementare
la maggior parte degli esempi di questo libro che utilizzano questo contenitore.Per ulteriori informazioni sul Docker disponibile
pile, visita:
ttps: //jupyterdockerstacks.readthedocs.io/en/latest/index.html

Esegui Jupyter Docker Stack

Prima di eseguire il passaggio successivo, assicurati che JupyterLab non sia attualmente in esecuzione sul tuo
computer. Scarichiamo ed eseguiamo lo stack Docker jupyter / pysparknotebook. Per
assicurati di non perdere il tuo lavoro quando chiudi il container Docker, allegheremo un file
cartella del filesystem locale nel contenitore e usala per salvare il tuo notebook — utenti Windows
dovrebbe sostituire \ con ^. :

lecca qui per visualizzare l'immagine del codice

docker run p 8888: 8888 p 4040: 4040 utente it root \


v fullPathToTheFolderYouWantToUse : / home / jovyan / work \
jupyter / pysparknotebook: 14fdfbf9cfc1 start.sh jupyter lab

La prima volta che esegui il comando precedente, Docker scaricherà il contenitore Docker
di nome:

lecca qui per visualizzare l'immagine del codice

jupyter / pysparknotebook: 14fdfbf9cfc1

La notazione ": 14fdfbf9cfc1" indica lo specifico jupyter / pysparknotebook


container da scaricare. Al momento della stesura di questo documento, 14fdfbf9cfc1 era la versione più recente di
Il container. Specificare la versione come abbiamo fatto qui aiuta con la riproducibilità . Senza il
": 14fdfbf9cfc1" nel comando, Docker scaricherà l' ultima versione di
container, che potrebbe contenere versioni software diverse e potrebbe non essere compatibile con
il codice che stai tentando di eseguire. Il contenitore Docker è quasi 6 GB, quindi il download iniziale
il tempo dipenderà dalla velocità della tua connessione Internet.

Apertura di JupyterLab nel tuo browser


Una volta che il contenitore è stato scaricato e in esecuzione, vedrai un'istruzione nel tuo comando
Prompt, Terminale o finestra della shell come:

lecca qui per visualizzare l'immagine del codice

Copia / incolla questo URL nel tuo browser quando ti connetti per la prima volta, per iniziare

http: // (bb00eb337630 o 127.0.0.1): 8888 /? token =


9570295e90ee94ecef75568b95545b7910a8f5502e6f5680

Copia la lunga stringa esadecimale (la stringa sul tuo sistema sarà diversa da questa):

C
h

Pagina 777
9570295e90ee94ecef75568b95545b7910a8f5502e6f5680

quindi apri http: // localhost: 8888 / lab nel tuo browser (localhost corrisponde a
127.0.0.1 nell'output precedente) e incolla il tuo token nel campo Password o token.
Fare clic su Accedi per accedere all'interfaccia di JupyterLab. Se chiudi accidentalmente il browser,
vai su http: // localhost: 8888 / lab per continuare la sessione.

Quando si esegue in questo contenitore Docker, la cartella di lavoro nella scheda File sul lato sinistro di
JupyterLab rappresenta la cartella allegata al contenitore nella finestra mobile run
opzione v del comando. Da qui puoi aprire i file del taccuino che ti forniamo. Qualunque
i nuovi blocchi note o altri file creati verranno salvati in questa cartella per impostazione predefinita.Perché il
La cartella di lavoro del contenitore Docker è collegata a una cartella sul tuo computer, qualsiasi file tu
create in JupyterLab rimarrà sul tuo computer, anche se decidi di eliminare il Docker
contenitore.

Accesso alla riga di comando del contenitore Docker


Ogni contenitore Docker ha un'interfaccia a riga di comando come quella che hai usato per eseguire IPython
in tutto questo libro. Tramite questa interfaccia, puoi installare i pacchetti Python nel Docker
container e persino utilizzare IPython come hai fatto in precedenza.

Apri un prompt dei comandi, un terminale o una shell Anaconda separati ed elenca i file
eseguire contenitori Docker con il comando:

docker ps

L'output di questo comando è ampio, quindi le righe di testo probabilmente andranno a capo, come in:

lecca qui per visualizzare l'immagine del codice

COMANDO IMMAGINE ID CONTENITORE


PORTE DI STATO CREATE
NOMI
f54f62b7e6d5 jupyter / pysparknotebook: 14fdfbf9cfc1 "tini g
/ bin / bash "2 minuti fa Su 2 minuti 0.0.0.0:8888>8888/tcp
friendly_pascal

Nell'ultima riga dell'output del nostro sistema sotto l'intestazione della colonna NAMES nella terza riga c'è il file
nome che Docker ha assegnato in modo casuale al contenitore in esecuzione, friendly_pascal, il
il nome sul tuo sistema sarà diverso. Per accedere alla riga di comando del contenitore, eseguire il file
seguente comando, sostituendo container_name con il nome del container in esecuzione:

finestra mobile exec è CONTAINER_NAME / bin / bash

Il contenitore Docker usa Linux sotto il cofano, quindi vedrai un prompt di Linux dove puoi
immettere i comandi.

L'app in questa sezione utilizzerà le funzionalità delle librerie NLTK e TextBlob che hai utilizzato in
" capitolo sull'elaborazione del linguaggio naturale ”. Nessuno dei due è preinstallato negli stack Jupyter Docker.
Per installare NLTK e TextBlob, inserisci il comando:

C
N
Pagina 778
conda install c condaforge nltk textblob

Arresto e riavvio di un contenitore Docker


Ogni volta che avvii un container con docker run, Docker ti offre una nuova istanza che
non non contiene le librerie installate in precedenza. Per questo motivo, dovresti tenerne traccia
del nome del contenitore, in modo da poterlo utilizzare da un altro prompt dei comandi di Anaconda,
Terminale o finestra della shell per arrestare il contenitore e riavviarlo. Il comando

finestra mobile fermata CONTAINER_NAME

spegnerà il contenitore. Il comando

finestra mobile riavvio CONTAINER_NAME

riavvierà il contenitore. Docker fornisce anche un'app GUI chiamata Kitematic che puoi usare per
gestire i container, compreso l'arresto e il riavvio. Puoi scaricare l'app da

ttps: //kitematic.com/ e accedi tramite il menu Docker. Il seguente utente


panoramiche della guida su come gestire i contenitori con lo strumento:

ttps: //docs.docker.com/kitematic/userguide/

16.6.3 Conteggio parole con Spark

In questa sezione, utilizzeremo le funzionalità di filtro, mappatura e riduzione di Spark per implementare un file
semplice esempio di conteggio delle parole che riassume le parole di Romeo e Giulietta. Puoi lavorare
con il taccuino esistente denominato RomeoAndJulietCounter.ipynb in
Cartella SparkWordCount (in cui copiare il file RomeoAndJuliet.txt da
il " capitolo sull'elaborazione del linguaggio naturale ”), oppure puoi creare un nuovo taccuino, quindi entrare
ed eseguire gli snippet che mostriamo.

Caricamento delle parole di arresto NLTK


In questa app, utilizzeremo le tecniche che hai appreso nel " capitolo sull'elaborazione del linguaggio naturale "a
eliminare le parole di arresto dal testo prima di contare le frequenze delle parole.Innanzitutto, scarica
le parole d'arresto NLTK:

lecca qui per visualizzare l'immagine del codice


[1]: import nltk
nltk.download ( 'stopwords' )
[nltk_data] Download delle stopwords del pacchetto in / home / jovyan / nltk_data ...
[nltk_data] Le parole chiave del pacchetto sono già aggiornate!
[1]: Vero

Quindi, carica le parole di arresto:

lecca qui per visualizzare l'immagine del codice

[2]: da nltk.corpus importare parole non significative

C
hN
h

stop_words = stopwords.words ( 'inglese' )


Pagina 779

Configurazione di SparkContext

Un oggetto SparkContext (dal modulo pyspark) ti dà accesso alle funzionalità di Spark in


Pitone. Molti ambienti Spark creano SparkContext per te, ma in Jupyter
pysparknotebook Docker stack, è necessario creare questo oggetto.

Innanzitutto, specifichiamo le opzioni di configurazione creando un oggetto SparkConf (da module

pyspark). Il frammento di codice seguente chiama il metodo setAppName dell'oggetto per specificare Spark
nome dell'applicazione e chiama il metodo setMaster dell'oggetto per specificare il cluster Spark
URL. L'URL "local [*]" indica che Spark è in esecuzione sul tuo computer locale (come
opposto a un cluster basato su cloud) e l'asterisco indica che Spark deve eseguire il nostro codice
utilizzando lo stesso numero di thread quanti sono i core sul computer:

lecca qui per visualizzare l'immagine del codice

[3]: da pyspark importa SparkConf


configurazione = SparkConf (). setAppName ( 'RomeoAndJulietCounter' ) \
.setMaster ( 'local [*]' )

Thread consentono un cluster singolo nodo di eseguire porzioni dei compiti Spark contemporaneamente a
simulare il parallelismo fornito dai cluster Spark. Quando diciamo che due compiti sono
operando contemporaneamente, intendiamo che stanno entrambi facendo progressi contemporaneamente, in genere da
eseguire un'attività per un breve periodo di tempo, quindi consentire l'esecuzione di un'altra attività.Quando diciamo
che due attività operano in parallelo , intendiamo che vengono eseguite contemporaneamente,
che è uno dei principali vantaggi dell'esecuzione di Hadoop e Spark su cluster basati su cloud di
computer.

Successivamente, crea SparkContext, passando SparkConf come argomento:

lecca qui per visualizzare l'immagine del codice

[4]: da pyspark importa SparkContext


sc = SparkContext (conf = configurazione)

Leggere il file di testo e associarlo alle parole


Lavori con SparkContext utilizzando tecniche di programmazione in stile funzionale, come
filtraggio, mappatura e riduzione, applicati a un dataset distribuito resiliente (RDD) . Un
RDD prende i dati archiviati in un cluster nel file system Hadoop e ti consente di farlo
specificare una serie di fasi di elaborazione per trasformare i dati nell'RDD.Queste fasi di elaborazione
sono pigri ( capitolo 5 ) —non eseguono alcun lavoro finché non indichi che Spark dovrebbe farlo
elaborare l'attività.

Il frammento di codice seguente specifica tre passaggi:

Il metodo SparkContext textFile carica le righe di testo da RomeoAndJuliet.txt


e lo restituisce come un RDD (dal modulo pyspark) di stringhe che rappresentano ogni riga.

La mappa del metodo RDD utilizza il suo argomento lambda per rimuovere tutta la punteggiatura con TextBlob

C
Pagina 780
funzione strip_punc e per convertire ogni riga di testo in minuscolo. Questo metodo restituisce
un nuovo RDD su cui è possibile specificare attività aggiuntive da eseguire.

Il metodo RDD flatMap usa il suo argomento lambda per mappare ogni riga di testo nelle sue parole
e produce un unico elenco di parole, anziché le singole righe di testo. Il risultato di
flatMap è un nuovo RDD che rappresenta tutte le parole di Romeo e Giulietta .

lecca qui per visualizzare l'immagine del codice

[5]: da textblob.utils importa strip_punc


tokenized = sc.textFile ( 'RomeoAndJuliet.txt' ) \
.map ( lambda line: strip_punc (line, all = True ) .lower ()) \
.flatMap ( riga lambda : line.split ())

Rimozione delle parole d'arresto


Successivamente, utilizziamo il filtro del metodo RDD per creare un nuovo RDD senza parole di interruzione rimanenti:

lecca qui per visualizzare l'immagine del codice

[6] : filtered = tokenized.filter ( lambda word: word not in stop_words)

Contando ogni parola rimanente


Ora che abbiamo solo le parole non-stop, possiamo contare il numero di occorrenze di ciascuna
parola. Per fare ciò, prima mappiamo ogni parola su una tupla contenente la parola e un conteggio di 1. Questo
è simile a quello che abbiamo fatto in Hadoop MapReduce. Spark distribuirà l'attività di riduzione
attraverso i nodi del cluster. Sul RDD risultante, chiamiamo quindi il metodo reduceByKey ,
passando la funzione add del modulo operatore come argomento. Questo dice il metodo

reduceByKey per aggiungere i conteggi per le tuple che contengono la stessa parola (la chiave):

lecca qui per visualizzare l'immagine del codice

[7]: da importazione operatore aggiungi


word_counts = filtered.map ( lambda word: (word, 1 )). reduceByKey (add)

Individuazione di parole con conteggi maggiori o uguali a 60


Poiché ci sono centinaia di parole in Romeo e Giulietta , filtriamo l'RDD per mantenere solo quelle
parole con 60 o più occorrenze:

lecca qui per visualizzare l'immagine del codice

[8]: filtered_counts = word_counts.filter ( lambda item: item [ 1 ]> = 60 )

Ordinamento e visualizzazione dei risultati


A questo punto, abbiamo specificato tutti i passaggi per contare le parole. Quando chiami il metodo RDD

collect , Spark avvia tutti i passaggi di elaborazione che abbiamo specificato sopra e restituisce un elenco
contenente i risultati finali, in questo caso le tuple di parole e il loro conteggio.Dal tuo
prospettiva, tutto sembra funzionare su un computer. Tuttavia, se SparkContext

è configurato per utilizzare un cluster, Spark dividerà le attività tra i nodi di lavoro del cluster per
Pagina 781
tu. Nel frammento seguente, ordina in ordine decrescente (reverse = True) l'elenco delle tuple per
i loro conteggi (itemgetter ( 1 )).

Il seguente snippet chiama il metodo collect per ottenere i risultati e li ordina


ordine decrescente per numero di parole:

lecca qui per visualizzare l'immagine del codice

[9]: da operatore import itemgetter


oggetti_ordinati = ordinati (conteggio_filtros.collect (),
key = itemgetter ( 1 ), reverse = True )

Infine, visualizziamo i risultati. Innanzitutto, determiniamo la parola con il maggior numero di lettere in modo che possiamo
allinea a destra tutte le parole in un campo di quella lunghezza, quindi visualizziamo ogni parola e il suo conteggio:

lecca qui per visualizzare l'immagine del codice

[10]: max_len = max ([len (word) for word, count in Sort_items])


per parola, conta in oggetti_ordinati:
print (f ' {word:> {max_len}} : {count} ' )
[10]: romeo: 298
tu: 277
giulietta: 178
tuo: 170S
infermiera: 146
capuleti: 141
amore: 136
te: 135
deve: 110
signora: 109
frate: 104
vieni: 94
mercutio: 83
buono: 80
benvolio: 79
entrare: 75
vai: 75
io: 71
tybalt: 69
morte: 69
notte: 68
lawrence: 67
uomo: 65
ha: 64
uno: 60

16.6.4 Conteggio parole Spark su Microsoft Azure

Come abbiamo detto in precedenza, vogliamo esporvi a entrambi gli strumenti che puoi utilizzare gratuitamente e al mondo reale
scenari di sviluppo. In questa sezione, implementerai l'esempio di conteggio parole Spark su un file
Cluster Microsoft Azure HDInsight Spark.

Creare un cluster Apache Spark in HDInsight usando il portale di Azure

Il collegamento seguente spiega come configurare un cluster Spark utilizzando il servizio HDInsight:

ttps: //docs.microsoft.com/enus/azure/hdinsight/spark/apachesparkjupytersparksqlus

C
Pagina 782

Mentre si seguono i passaggi per la creazione di un cluster HDInsight Spark, tenere presente gli stessi problemi che abbiamo
elencato nella configurazione del cluster Hadoop precedentemente in questo capitolo e per il tipo di cluster selezionare
Scintilla.

Anche in questo caso, la configurazione del cluster predefinita fornisce più risorse di quelle necessarie per il nostro
esempi. Quindi, nel riepilogo del cluster, esegui i passaggi mostrati nel cluster Hadoop
setup per modificare il numero di nodi di lavoro a 2 e per configurare i nodi di lavoro e head
per utilizzare i computer D3 v2. Quando si fa clic su Crea, sono necessari da 20 a 30 minuti per configurare e
distribuisci il tuo cluster.

Installa le librerie in un cluster


Se il codice Spark richiede librerie che non sono installate nel cluster HDInsight, lo farai
è necessario installarli. Per vedere quali librerie sono installate per impostazione predefinita, puoi usare ssh per accedere
il tuo cluster (come abbiamo mostrato in precedenza nel capitolo) ed esegui il comando:

/ usr / bin / anaconda / envs / py35 / bin / conda list

Poiché il codice verrà eseguito su più nodi del cluster, le librerie devono essere installate su ogni
nodo. Azure richiede la creazione di uno script della shell Linux che specifichi i comandi da installare
biblioteche. Quando si invia lo script ad Azure, esso convalida lo script, quindi lo esegue
ogni nodo. Gli script della shell di Linux vanno oltre lo scopo di questo libro e lo script deve essere ospitato su
un server Web da cui Azure può scaricare il file. Quindi, abbiamo creato uno script di installazione per te
che installa le librerie che usiamo negli esempi Spark. Eseguire i seguenti passaggi per l'installazione
queste biblioteche:

1. Nel portale di Azure, seleziona il tuo cluster.

2. Nell'elenco di elementi sotto la casella di ricerca del cluster, fare clic su Azioni script.

3. Fare clic su Invia nuovo per configurare le opzioni per lo script di installazione della libreria. Per il
Tipo di script selezionare Personalizzato, per il nome specificare le librerie e per lo script Bash
Uso dell'URI:
ttp: //deitel.com/bookresources/IntroToPython/install_libraries.sh

4. Selezionare sia Head che Worker per assicurarsi che lo script installi le librerie su tutti i file
nodi.

5. Fare clic su Crea.


Quando il cluster termina di eseguire lo script, se è stato eseguito correttamente, vedrai un verde
selezionare accanto al nome dello script nell'elenco delle azioni di script. In caso contrario, Azure ti avviserà
c'erano errori.

Copia di RomeoAndJuliet.txt nel cluster HDInsight

Come hai fatto nella demo di Hadoop, usiamo il comando scp per caricare nel cluster il file
RomeoAndJuliet.txt che hai utilizzato nel file " capitolo sull'elaborazione del linguaggio naturale ”. In un
Prompt dei comandi, terminale o shell, passa alla cartella contenente il file (assumiamo questo

N
h
Pagina 783
cartella ch16 del capitolo), quindi immettere il seguente comando.Sostituisci YourClusterName con
il nome specificato durante la creazione del cluster e premere Invio solo dopo aver digitato
l'intero comando. I due punti sono obbligatori e indicano che fornirai il tuo cluster
password quando richiesto. A quel prompt, digita la password che hai specificato durante la configurazione
il cluster, quindi premere Invio :

scp RomeoAndJuliet.txt sshuser @ YourClusterName ssh.azurehdinsight.net:

Quindi, usa ssh per accedere al tuo cluster e accedere alla sua riga di comando.In un prompt dei comandi,
Terminale o shell, esegui il seguente comando. Assicurati di sostituire YourClusterName con
il nome del tuo cluster. Ancora una volta, ti verrà richiesta la password del cluster:

ssh sshuser @ YourClusterName ssh.azurehdinsight.net

Per lavorare con il file RomeoAndJuliet.txt in Spark, usa prima la sessione ssh per copiare il file
file nel file system Hadoop del cluster eseguendo il seguente comando.Di nuovo,
useremo la cartella / esempi / dati già esistenti che Microsoft include per l'uso con
Esercitazioni su HDInsight. Di nuovo, premi Invio solo dopo aver digitato l'intero comando:

hadoop fs copyFromLocal RomeoAndJuliet.txt


/example/data/RomeoAndJuliet.txt

Accesso ai notebook Jupyter in HDInsight


Al momento della stesura di questo documento, HDInsight usa la vecchia interfaccia Jupyter Notebook, anziché
la nuova interfaccia JupyterLab mostrata in precedenza. Per una rapida panoramica della vecchia interfaccia vedere:

ttps: //jupyternotebook.readthedocs.io/en/stable/examples/Notebook/Notebook%20 asics.ht

o accedere a Jupyter Notebooks in HDInsight, nel portale di Azure selezionare Tutte le risorse, quindi
il tuo cluster. Nella scheda Panoramica, seleziona Notebook Jupyter in Dashboard del cluster.
Si apre una finestra del browser web e ti chiede di accedere. Usa il nome utente e la password
specificato durante la configurazione del cluster. Se non hai specificato un nome utente, il valore predefinito è
admin. Una volta effettuato l'accesso, Jupyter mostra una cartella contenente PySpark e Scala
sottocartelle. Questi contengono tutorial su Python e Scala Spark.

Caricamento del taccuino RomeoAndJulietCounter.ipynb

Puoi creare nuovi taccuini facendo clic su Nuovo e selezionando PySpark3, oppure puoi caricarli
taccuini esistenti dal computer. Per questo esempio, carichiamo il file della sezione precedente

RomeoAndJulietCounter.ipynb notebook e modificarlo per farlo funzionare con Azure. Fare così,
fare clic sul pulsante Carica, accedere alla cartella SparkWordCount della cartella di esempio ch16,
selezionare RomeoAndJulietCounter.ipynb e fare clic su Apri. Questo visualizza il file in
cartella con un pulsante Carica alla sua destra. Fare clic su quel pulsante per posizionare il blocco note nel file
cartella corrente. Quindi, fai clic sul nome del taccuino per aprirlo in una nuova scheda del browser. Jupyter lo farà
mostra una finestra di dialogo Kernel non trovato. Seleziona PySpark3 e fai clic su OK. Non eseguire alcuna cella
ancora.

M
T
h
odificare il notebook per lavorare con Azure

Modifica del notebook per lavorare con Azure Pagina 784

Eseguire i passaggi seguenti, eseguendo ogni cella mentre si completa il passaggio:

1. Il cluster HDInsight non consentirà a NLTK di memorizzare le parole di interruzione scaricate in NLTK
cartella predefinita perché fa parte delle cartelle protette del sistema.Nella prima cella, modifica
la chiamata nltk.download ('stopwords') come segue per memorizzare le parole di stop nel file
cartella corrente ('.'):

nltk.download ( 'stopwords' , download_dir = '.' )

Quando esegui la prima cella, l'applicazione Avvio Spark viene visualizzata sotto la cella
mentre HDInsight configura un oggetto SparkContext denominato sc per te. Quando questo compito è
completato, il codice della cella viene eseguito e scarica le parole di arresto.

2. Nella seconda cella, prima di caricare le parole di arresto, devi dire a NLTK che si trovano
nella cartella corrente. Aggiungi la seguente dichiarazione dopo l'istruzione import da dire
NLTK per cercare i suoi dati nella cartella corrente:

nltk.data.path.append ( '.' )

3. Poiché HDInsight configura l'oggetto SparkContext per te, la terza e la quarta cella
del blocco note originale non sono necessari, quindi è possibile eliminarli. Per farlo, fai clic su
al suo interno e seleziona Elimina celle dal menu Modifica di Jupyter, oppure fai clic sul margine bianco
a sinistra della cella e digita dd.

4. Nella cella successiva, specificare la posizione di RomeoAndJuliet.txt nell'Hadoop sottostante


file system. Sostituisci la stringa "RomeoAndJuliet.txt" con la stringa

"wasb: ///example/data/RomeoAndJuliet.txt"

La notazione wasb: /// indica che RomeoAndJuliet.txt è archiviato in Windows

BLOB di archiviazione di Azure (WASB): l'interfaccia di Azure per il file system HDFS.

5. Poiché Azure attualmente utilizza Python 3.5.x, non supporta fstring. Quindi, nell'ultimo
cella, sostituire la stringa f con la seguente formattazione della stringa Python vecchio stile utilizzando il
formato del metodo stringa :

print ( ' {:> {width}} : {} ' .format (word, count, width = max_len))

Vedrai gli stessi risultati finali della sezione precedente.

Attenzione: assicurati di eliminare il tuo cluster e altre risorse quando hai finito
con loro, in modo da non incorrere in spese. Per ulteriori informazioni, vedere:

ttps: //docs.microsoft.com/enus/azure/azureresourcemanager/resourcegrouppo tal

ota che quando si eliminano le risorse di Azure, verranno eliminati anche i notebook . tu

N
h

può scaricare il blocco appunti appena eseguito selezionando File> Scarica come>
Pagina 785

Notebook (.ipynb) in Jupyter.

16.7 SPARK STREAMING: CONTEGGIO GLI HASHTAG DI TWITTER


UTILIZZO DEL PYSPARK-NOTEBOOK DOCKER STACK
In questa sezione creerai ed eseguirai un'applicazione di streaming Spark in cui riceverai un file
flusso di tweet sugli argomenti specificati e riassumere gli hashtag principali 20 in un grafico a barre
che si aggiorna ogni 10 secondi. A questo scopo di questo esempio, utilizzerai Jupyter Docker
container dal primo esempio Spark.

Ci sono due parti in questo esempio. In primo luogo, utilizzando le tecniche del "Data Mining
Twitter ”, creerai uno script che trasmette i tweet da Twitter. Quindi, useremo Spark
streaming in un Jupyter Notebook per leggere i tweet e riassumere gli hashtag.

Le due parti comunicheranno tra loro tramite socket di rete, una vista di basso livello
di rete client / server in cui un'app client comunica con un'app server su un file
rete utilizzando tecniche simili all'I / O di file. Un programma può leggere da un socket o scrivere su un file
socket in modo simile alla lettura da un file o alla scrittura su un file. Il socket rappresenta un endpoint
di una connessione. In questo caso, il client sarà un'applicazione Spark e il server sarà un file
script che riceve tweet in streaming e li invia all'app Spark.
Avvio del Docker Container e installazione di Tweepy
Per questo esempio, installerai la libreria Tweepy nel contenitore Docker di Jupyter.Seguire
ection 16.6.2 istruzioni per avviare il contenitore e installare le librerie Python in
esso. Usa il seguente comando per installare Tweepy:

pip installa tweepy

16.7.1 Streaming di tweet su un socket


Lo script starttweetstream.py contiene una versione modificata di TweetListener
classe dal capitolo "Data mining Twitter". Trasmette il numero specificato di tweet e
li invia a un socket sul computer locale. Quando viene raggiunto il limite di tweet, lo script
chiude la presa. Hai già utilizzato lo streaming di Twitter, quindi ci concentreremo solo sulle novità.
Assicurati che il file keys.py (nella sottocartella SparkHashtagSummarizer della cartella ch16)
contiene le tue credenziali Twitter.

Esecuzione dello script nel Docker Container


In questo esempio, utilizzerai la finestra del terminale di JupyterLab per eseguire
starttweetstream.py in una scheda, quindi usa un taccuino per eseguire l'attività Spark in
un'altra scheda. Con il contenitore Docker di Jupyter pysparknotebook in esecuzione, apri

http: // localhost: 8888 / lab

nel tuo browser web. In JupyterLab, seleziona File> Nuovo> Terminale per aprire una nuova scheda
contenente un terminale. Questa è una riga di comando basata su Linux. Digitando il comando ls e
premendo Invio vengono elencati i contenuti della cartella corrente. Per impostazione predefinita, vedrai il lavoro del contenitore

S
Pagina 786
cartella.

Per eseguire starttweetstream.py, devi prima accedere al file


8
SparkHashtagSummarizer cartella con il comando:

8
Gli utenti Windows dovrebbero notare che Linux usa / invece di \ per separare le cartelle e quel file
e i nomi delle cartelle fanno distinzione tra maiuscole e minuscole.

cd work / SparkHashtagSummarizer

È ora possibile eseguire lo script con il comando del modulo

ipython starttweetstream.py number_of_tweets search_terms

dove number_of_tweets specifica il numero totale di tweet da elaborare e search_terms


una o più stringhe separate da spazi da utilizzare per filtrare i tweet. Ad esempio, il seguente
il comando invia in streaming 1000 tweet sul calcio:

ipython starttweetstream.py 1000 football

A questo punto, lo script mostrerà "Waiting for connection" e aspetterà fino a Spark
si connette per avviare lo streaming dei tweet.

starttweetstream.py import Statements


A scopo di discussione, abbiamo diviso starttweetstream.py in pezzi. Primo, noi
importare i moduli utilizzati nello script. Il modulo socket della libreria standard Python
fornisce le funzionalità che consentono alle app Python di comunicare tramite socket.

lecca qui per visualizzare l'immagine del codice

1 # starttweetstream.py
2 "" "Script per ottenere tweet sugli argomenti specificati come argomenti dello script
3 e invia il testo del tweet a un socket per l'elaborazione da parte di Spark. "" "
4 chiavi di importazione
5 socket di importazione
6 import sys
7 import tweepy
8
Classe TweetListener
Ancora una volta, hai visto la maggior parte del codice nella classe TweetListener, quindi ci concentriamo solo su
cosa c'è di nuovo qui:

Il metodo __init__ (righe 12-17) ora riceve un parametro di connessione che rappresenta il
socket e lo memorizza nell'attributo self.connection. Usiamo questo socket per inviare il file
hashtag all'applicazione Spark.

Nel metodo on_status (righe 24–44), le righe 27–32 estraggono gli hashtag da Tweepy

Oggetto di stato, convertili in minuscolo e crea una stringa separata dallo spazio del file

4C

Pagina 787
hashtag da inviare a Spark. La dichiarazione chiave è la riga 39:

self.connection.send (hashtags_string.encode ( 'utf8' ))

che utilizza il metodo send dell'oggetto connessione per inviare il testo del tweet a qualunque cosa
l'applicazione sta leggendo da quel socket. Il metodo send prevede come argomento una sequenza di
byte. La chiamata al metodo stringa encode ('utf8') converte la stringa in byte.Spark lo farà
legge automaticamente i byte e ricostruisce le stringhe.

lecca qui per visualizzare l'immagine del codice

TweetListener di 9 classi (tweepy.StreamListener):


10 "" "Gestisce il flusso di Tweet in arrivo." ""
11
12 def __init __ (self, api, connection, limit = 10000 ):
13 "" "Crea variabili di istanza per tenere traccia del numero di tweet." ""
14 self.connection = connessione
15 self.tweet_count = 0
16 auto. TWEET_LIMIT = limite # 10.000 per impostazione predefinita
17 super () .__ init __ (api) # chiama l'init della superclasse
18
19 def on_connect (self):
20 "" "Chiamato quando il tentativo di connessione ha esito positivo, abilitazione
21 per eseguire le attività dell'applicazione appropriate a quel punto. "" "
22 print ( "Connessione a Twitter \ n" riuscita )
23
24 def on_status (self, status):
25 "" "Chiamato quando Twitter ti invia un nuovo tweet." ""
26 # ottieni gli hashtag
27 hashtag = []
28
29 per hashtag_dict in status.entities [ 'hashtags' ]:
30 hashtags.append (hashtag_dict [ 'text' ] .lower ())
31
32 hashtags_string = '' .join (hashtags) + '\ n'
33 print (f 'Screen name: {status.user.screen_name}: ' )
34 print (f 'Hashtag: {hashtags_string} ' )
35 self.tweet_count + = 1 # numero di traccia dei tweet elaborati
36
37 prova :
38 # send richiede byte, quindi codifica la stringa nel formato utf8
39 self.connection.send (hashtags_string.encode ( 'utf8' ))
40 eccetto Eccezione come e:
41 print (f 'Errore: {e} ' )
42
43 # se viene raggiunto TWEET_LIMIT, restituisci False per terminare lo streaming
44 return self.tweet_count! = Self. TWEET_LIMIT
45
46 def on_error (self, status):
47 stampa (stato)
48 return True
49

Applicazione principale

Le righe 50–80 vengono eseguite quando si esegue lo script. Ti sei connesso a Twitter per trasmettere i tweet
in precedenza, quindi qui discutiamo solo delle novità in questo esempio.

La riga 51 ottiene il numero di tweet da elaborare convertendo l'argomento della riga di comando

C
Pagina 788
sys.argv [1] su un numero intero. Ricorda che l'elemento 0 rappresenta il nome dello script.

lecca qui per visualizzare l'immagine del codice


50 if __name__ == '__main__' :
51 tweet_limit = int (sys.argv [ 1 ]) # ottiene il numero massimo di tweet

La riga 52 chiama la funzione socket del modulo socket , che restituisce un oggetto socket che

useremo per attendere una connessione dall'applicazione Spark.

lecca qui per visualizzare l'immagine del codice

52 client_socket = socket.socket () # crea un socket


53

La riga 55 chiama il metodo bind dell'oggetto socket con una tupla contenente il nome host o l'IP
indirizzo del computer e il numero di porta su quel computer. Insieme questi rappresentano
dove questo script attenderà una connessione iniziale da un'altra app:

lecca qui per visualizzare l'immagine del codice

L' app 54 # utilizzerà la porta localhost (questo computer) 9876


55 client_socket.bind (( 'localhost' , 9876 ))
56

La riga 58 chiama il metodo di ascolto del socket , che fa sì che lo script attenda fino a una connessione
viene ricevuto. Questa è l'affermazione che impedisce l'avvio del flusso di Twitter fino al
L'applicazione Spark si connette.

lecca qui per visualizzare l'immagine del codice

57 print ( 'Waiting for connection' )


58 client_socket.listen () # aspetta che il client si connetta
59

Una volta che l'applicazione Spark si connette, la linea 61 chiama il metodo socket accept , che accetta l'estensione
connessione. Questo metodo restituisce una tupla contenente un nuovo oggetto socket che lo script farà
utilizzare per comunicare con l'applicazione Spark e l'indirizzo IP dell'applicazione Spark
computer.

lecca qui per visualizzare l'immagine del codice

60 # quando si riceve la connessione, ottenere la connessione / l'indirizzo del client


61 connessione, indirizzo = client_socket.accept ()
62 print (f "Connessione ricevuta da {address} " )
63

Successivamente, ci autenticiamo con Twitter e avviamo lo streaming. Le righe 73-74 configurano lo stream,
passando la connessione dell'oggetto socket a TweetListener in modo che possa utilizzare il socket
per inviare hashtag all'applicazione Spark.

lecca qui per visualizzare l'immagine del codice


Pagina 789

64 # configura l'accesso a Twitter


65 auth = tweepy.OAuthHandler (keys.consumer_key, keys.consumer_secret)
66 auth.set_access_token (keys.access_token, keys.access_token_secret)
67
68 # configura Tweepy in modo che attenda se vengono raggiunti i limiti di frequenza di Twitter
69 api = tweepy.API (auth, wait_on_rate_limit = True ,
70 wait_on_rate_limit_notify = True )
71
72 # crea lo Stream
73 twitter_stream = tweepy.Stream (api.auth,
74 TweetListener (api, connessione, tweet_limit))
75
76 # sys.argv [2] è il primo termine di ricerca
77 twitter_stream.filter (track = sys.argv [ 2 :])
78

Infine, le righe 79–80 chiamano il metodo close sugli oggetti socket per rilasciare le loro risorse.

lecca qui per visualizzare l'immagine del codice

79 connection.close ()
80 client_socket.close ()
16.7.2 Riepilogo degli hashtag dei Tweet; Presentazione di Spark SQL
In questa sezione, utilizzerai lo streaming Spark per leggere gli hashtag inviati tramite un socket dallo script
starttweetstream.py e riassumi i risultati. Puoi creare un nuovo taccuino
e inserisci il codice che vedi qui o carica il notebook hashtagsummarizer.ipynb we
fornire nella cartella degli esempi ch16 la sottocartella SparkHashtagSummarizer.

Importazione delle librerie


Per prima cosa, importiamo le librerie utilizzate in questo blocco note. Spiegheremo le classi di pyspark come noi
usali. Da IPython, abbiamo importato il modulo di visualizzazione, che contiene classi e
funzioni di utilità che puoi usare in Jupyter.In particolare, useremo clear_output
funzione per rimuovere un grafico esistente prima di visualizzarne uno nuovo:

lecca qui per visualizzare l'immagine del codice

[1]: da pyspark importa SparkContext


da pyspark.streaming import StreamingContext
da pyspark.sql import Row, SparkSession
dalla visualizzazione dell'importazione IPython
importa matplotlib.pyplot come plt
importare seaborn come sns
% matplotlib inline

Questa applicazione Spark riassume gli hashtag in batch di 10 secondi. Dopo l'elaborazione di ciascuno
batch, mostra un barplot di Seaborn. La magia di IPython

% matplotlib inline

C
Pagina 790
indica che la grafica con Matplotlibbas dovrebbe essere visualizzata nel notebook anziché in formato
le proprie finestre. Ricorda che Seaborn usa Matplotlib.

Abbiamo utilizzato diversi magici IPython in tutto il libro.Ci sono molte magie in particolare
per l'utilizzo nei notebook Jupyter. Per l'elenco completo delle magie vedi:

ttps: //ipython.readthedocs.io/en/stable/interactive/magics.html

Funzione di utilità per ottenere SparkSession

Come vedrai presto, puoi usare Spark SQL per eseguire query sui dati in set di dati distribuiti resilienti
(RDD). Spark SQL usa Spark DataFrame per ottenere una visualizzazione tabella degli RDD sottostanti. UN
SparkSession (modulo pyspark.sql) viene utilizzato per creare un DataFrame da un RDD.

Può esserci un solo oggetto SparkSession per applicazione Spark. La seguente funzione,
9
che abbiamo preso in prestito dalla Spark Streaming Programming Guide , definisce il file
modo per ottenere un'istanza SparkSession se esiste già o per crearne una se non ancora
0
esistere:

9
ttps: //spark.apache.org/docs/latest/streamingprogramming
# dataframeandsqloperations uide.html .

0
Poiché questa funzione è stata presa in prestito dalla Spark Streaming Guida di programmazione s
Sezione DataFrame e operazioni SQL
( ttps: //spark.apache.org/docs/latest/streamingprogramming

uide.html # dataframeandsqloperations), non l'abbiamo rinominato per usare Python s


lo stile di denominazione delle funzioni standard e non abbiamo utilizzato virgolette singole per delimitare le stringhe.

lecca qui per visualizzare l'immagine del codice

[2]: def getSparkSessionInstance (sparkConf):


"" "Metodo consigliato da Spark Streaming Programming Guide
per ottenere una SparkSession esistente o crearne una nuova. "" "
if ( "sparkSessionSingletonInstance" non in globals ()):
globals () [ "sparkSessionSingletonInstance" ] = SparkSession \
.builder \
.config (conf = sparkConf) \
.getOrCreate ()
return globals () [ "sparkSessionSingletonInstance" ]

Funzione di utilità per visualizzare un grafico a barre basato su un DataFrame Spark


Chiamiamo la funzione display_barplot dopo che Spark ha elaborato ogni batch di hashtag.Ogni chiamata
cancella il precedente barplot di Seaborn, quindi ne visualizza uno nuovo basato su Spark DataFrame
riceve. Innanzitutto, chiamiamo il metodo toPandas di Spark DataFrame per convertirlo in un panda

DataFrame da utilizzare con Seaborn. Successivamente, chiamiamo la funzione clear_output da


Modulo IPython.display. L'argomento della parola chiave wait = True indica che la funzione
dovrebbe rimuovere il grafico precedente (se ce n'è uno), ma solo quando il nuovo grafico è pronto
Schermo. Il resto del codice nella funzione utilizza le tecniche standard di Seaborn che abbiamo mostrato
in precedenza. La chiamata di funzione sns.color_palette ('cool', 20) seleziona venti colori
dalla tavolozza dei colori "cool" di Matplotlib:

hC
g45h
Pagina 791
lecca qui per visualizzare l'immagine del codice

[3]: def display_barplot (spark_df, x, y, time, scale = 2.0 , size = ( 16 , 9 )):


"" "Visualizza il contenuto di uno Spark DataFrame come grafico a barre." ""
df = spark_df.toPandas ()

# rimuove il grafico precedente quando il nuovo è pronto per essere visualizzato


display.clear_output (wait = True )
print (f "TIME: {time} " )

# crea e configura una figura contenente un barplot di Seaborn


plt.figure (figsize = size)
sns.set (font_scale = scale)
barplot = sns.barplot (data = df, x = x, y = y
palette = sns.color_palette ( 'cool' , 20 ))

# ruota le etichette dell'asse x di 90 gradi per la leggibilità


per l' elemento in barplot.get_xticklabels ():
item.set_rotation ( 90 )

plt.tight_layout ()
plt. mostra ()

Funzione di utilità per riepilogare i primi 20 hashtag finora


In Spark streaming, un DStream è una sequenza di RDD, ognuno dei quali rappresenta un minibatch di dati
processare. Come vedrai presto, puoi specificare una funzione che viene chiamata per eseguire un'attività
ogni RDD nel flusso. In questa app, la funzione count_tags riepiloga l'hashtag
conta in un dato RDD, aggiungili ai totali correnti (gestiti da SparkSession),
quindi visualizzare un grafico a barre top20 aggiornato in modo da poter vedere come sono gli hashtag top20
1
cambiando nel tempo. A scopo di discussione, abbiamo suddiviso questa funzione in parti più piccole.
Innanzitutto, otteniamo SparkSession chiamando la funzione di utilità
getSparkSessionInstance con le informazioni di configurazione di SparkContext. Ogni
RDD ha accesso a SparkContext tramite l'attributo context:

1
Quando questa funzione viene chiamata per la prima volta, potresti vedere un messaggio di errore di eccezione
mostra se non sono stati ancora ricevuti tweet con hashtag. Questo perché semplicemente mostriamo
il messaggio di errore nello standard output. Quel messaggio scomparirà non appena ci saranno
tweet con hashtag.

lecca qui per visualizzare l'immagine del codice

[4]: def count_tags (time, rdd):


"" "Conta gli hashtag e mostra i primi 20 in ordine decrescente." ""
provare :
# ottieni SparkSession
spark = getSparkSessionInstance (rdd.context.getConf ())

Successivamente, chiamiamo il metodo map dell'RDD per mappare i dati nell'RDD agli oggetti Row (da

pacchetto pyspark.sql). Gli RDD in questo esempio contengono tuple di hashtag e conteggi.
Il costruttore Row usa i nomi degli argomenti delle sue parole chiave per specificare i nomi delle colonne
per ogni valore in quella riga. In questo caso, il tag [0] è l'hashtag nella tupla e il tag [1] è il
conteggio totale per quell'hashtag:

lecca qui per visualizzare l'immagine del codice

5C

Pagina 792
# mappa hashtag stringcount tuple a Rows
righe = rdd.map (
tag lambda : riga (hashtag = tag [ 0 ], total = tag [ 1 ]))
L'istruzione successiva crea un Spark DataFrame contenente gli oggetti Row. Lo useremo
con Spark SQL per interrogare i dati per ottenere i primi 20 hashtag con i loro conteggi totali:

lecca qui per visualizzare l'immagine del codice

# crea un DataFrame dagli oggetti Row


hashtags_df = spark.createDataFrame (righe)

Per eseguire una query su un DataFrame Spark, creare prima una visualizzazione tabella , che consente a Spark SQL di eseguire query su
DataFrame come una tabella in un database relazionale. Spark DataFrame metodo

createOrReplaceTempView crea una vista tabella temporanea per DataFrame e


assegna un nome alla vista da utilizzare nella clausola from di una query:

lecca qui per visualizzare l'immagine del codice

# crea una vista tabella temporanea da utilizzare con Spark SQL


hashtags_df.createOrReplaceTempView ( 'hashtags' )

2
Una volta che hai una visualizzazione tabella, puoi eseguire query sui dati usando Spark SQL.Il seguente
l'istruzione utilizza il metodo sql dell'istanza SparkSession per eseguire una query SQL Spark
che seleziona l'hashtag e le colonne totali dalla vista della tabella hashtag, ordina il file
righe selezionate per totale in ordine decrescente (decrescente), quindi restituisce le prime 20 righe del file
risultato (limite 20). Spark SQL restituisce un nuovo Spark DataFrame contenente i risultati:

2
o dettagli sulla sintassi di Spark SQL, vedere ttps: //spark.apache.org/sql/ .

lecca qui per visualizzare l'immagine del codice

# usa Spark SQL per ottenere i primi 20 hashtag in ordine decrescente


top20_df = spark.sql (
"" "seleziona hashtag, totale
dagli hashtag
ordina per totale, hashtag disc
limite 20 "" " )

Infine, passiamo Spark DataFrame alla nostra funzione di utilità display_barplot.Il


hashtags e totali vengono visualizzati sulle X e Y assi, rispettivamente. Visualizziamo anche il file
ora in cui è stato chiamato count_tags:

lecca qui per visualizzare l'immagine del codice

display_barplot (top20_df, x = 'hashtag' , y = 'total' , time = time)


tranne Eccezione come e:
print (f ' Eccezione: {e} ' )

G
C
F
5h
etting il SparkContext

Recupero di SparkContext Pagina 793

Il resto del codice in questo blocco appunti configura lo streaming di Spark per leggere il testo da

starttweetstream.py e specifica come elaborare i tweet. Innanzitutto, creiamo il file


SparkContext per la connessione al cluster Spark:

[5]: sc = SparkContext ()

Recupero di StreamingContext

Per lo streaming Spark, devi creare un StreamingContext (module


pyspark.streaming), fornendo come argomenti SparkContext e quanto spesso in
secondi per elaborare batch di dati in streaming.In questa app elaboreremo batch ogni 10
secondi: questo è l' intervallo batch :

lecca qui per visualizzare l'immagine del codice

[6]: ssc = StreamingContext (sc, 10 )

A seconda della velocità con cui arrivano i dati, potresti voler accorciare o allungare il tuo batch
intervalli. Per una discussione su questo e altri problemi relativi alle prestazioni, vedere Performance
Sezione Tuning della Guida alla programmazione di Spark Streaming :

ttps: //spark.apache.org/docs/latest/streamingprogrammingguide.html#performan etuning

Creazione di un punto di controllo per il mantenimento dello stato


Per impostazione predefinita, lo streaming Spark non conserva le informazioni sullo stato durante l'elaborazione del flusso di
RDD. Tuttavia, puoi usare il checkpoint di Spark per tenere traccia dello stato dello streaming.
Il checkpoint consente:

tolleranza agli errori per il riavvio di un flusso in caso di nodo cluster o applicazione Spark
fallimenti e

trasformazioni stateful, come il riepilogo dei dati ricevuti finora, come stiamo facendo in
questo esempio.

Il checkpoint del metodo StreamingContext imposta la cartella del checkpoint:

lecca qui per visualizzare l'immagine del codice

[7]: ssc.checkpoint ( "hashtagsummarizer_checkpoint" )

Per un'applicazione di streaming Spark in un cluster basato su cloud, devi specificare una posizione all'interno
HDFS per archiviare la cartella del punto di arresto. Stiamo eseguendo questo esempio nella finestra mobile Jupyter locale
image, quindi abbiamo semplicemente specificato il nome di una cartella, che Spark creerà nel file
cartella (nel nostro caso, SparkHashtagSummarizer della cartella ch16).Per maggiori dettagli su
checkpoint, vedi

S
C
h

Pagina 794
ttps: //spark.apache.org/docs/latest/streamingprogrammingguide.html#checkpoin ing

collegamento al flusso tramite un socket

Il metodo StreamingContext socketTextStream si connette a un socket da cui un file


flusso di dati verrà ricevuto e restituirà un DStream che riceve i dati. Il metodo
gli argomenti sono il nome host e il numero di porta a cui deve accedere StreamingContext
connect: devono corrispondere al punto in cui lo script starttweetstream.py è in attesa del file
connessione:

lecca qui per visualizzare l'immagine del codice

[8]: stream = ssc.socketTextStream ( 'localhost' , 9876 )

Tokenizzare le linee di hashtag


Usiamo chiamate di programmazione in stile funzionale su un DStream per specificare le fasi di elaborazione
eseguire sui dati in streaming. La seguente chiamata al metodo flatMap di DStream tokenizza
una linea di hashtag separati dallo spazio e restituisce un nuovo DStream che rappresenta l'individuo
tag:

lecca qui per visualizzare l'immagine del codice

[9]: tokenized = stream.flatMap ( riga lambda : line.split ())

Mappatura degli hashtag su tuple di coppie di conteggio hashtag

Successivamente, in modo simile al mappatore Hadoop precedentemente in questo capitolo, utilizziamo lamappa del metodo DStream per
ottenere un nuovo DStream in cui ogni hashtag è mappato a una coppia di conteggio hashtag (in questo caso come un

tupla) in cui il conteggio è inizialmente 1:

lecca qui per visualizzare l'immagine del codice

[10]: mapped = tokenized.map ( lambda hashtag: (hashtag, 1 ))

Il totale degli hashtag conta finora

Il metodo DStream updateStateByKey riceve un lambda a due argomenti che ammonta a


conta per una determinata chiave e li aggiunge al totale precedente per quella chiave:

lecca qui per visualizzare l'immagine del codice

[11]: hashtag_counts = tokenized.updateStateByKey (


lambda counts, prior_total: sum (counts) + (prior_total o 0 ))

Specificare il metodo da chiamare per ogni RDD


Infine, utilizziamo il metodo DSteam foreachRDD per specificare che ogni RDD elaborato dovrebbe essere
passato alla funzione count_tags, che riassume quindi i primi 20 hashtag finora e

C
C
h

Pagina 795
mostra un grafico a barre:

lecca qui per visualizzare l'immagine del codice

[12]: hashtag_counts.foreachRDD (count_tags)

Avvio dello Spark Stream


Ora che abbiamo specificato i passaggi di elaborazione, chiamiamo l' inizio di StreamingContext
metodo per connettersi al socket e avviare il processo di streaming.

lecca qui per visualizzare l'immagine del codice

[13]: ssc.start () # avvia lo streaming di Spark

Quanto segue mostra un grafico a barre di esempio prodotto durante l'elaborazione di un flusso di tweet su
"calcio." Perché il calcio è uno sport diverso negli Stati Uniti e nel resto del mondo
gli hashtag riguardano sia il football americano che quello che chiamiamo calcio: ne abbiamo disattivati ​tre in grigio
hashtag che non erano appropriati per la pubblicazione:

16.8 INTERNET OF THINGS E DASHBOARD


Alla fine degli anni '60, Internet iniziò come ARPANET, che inizialmente ne collegava quattro
3
università ed è cresciuto fino a 10 nodi entro la fine del 1970. Negli ultimi 50 anni, questo numero è cresciuto fino a
miliardi di computer, smartphone, tablet e una vasta gamma di altri tipi di dispositivi
connesso a Internet in tutto il mondo. Qualsiasi dispositivo connesso a Internet è una "cosa" in
Internet of Things (IoT).

3
ttps: //en.wikipedia.org/wiki/ARPANET#History ..

Ogni dispositivo ha un indirizzo di protocollo Internet univoco (indirizzo IP) che lo identifica.Il
l'esplosione di dispositivi collegati ha esaurito i circa 4,3 miliardi di IPv4 disponibili
4
(Internet Protocol versione 4) indirizzi e ha portato allo sviluppo di IPv6, che supporta
38 5
circa 3,4 × 10 indirizzi (sono molti zeri).

4
C
5h

4 Pagina 796
ttps: //en.wikipedia.org/wiki/IPv4_address_exhaustion .

5
ttps: //en.wikipedia.org/wiki/IPv6 .
“Le migliori società di ricerca come Gartner e McKinsey prevedono un balzo dai 6 miliardi
6
dispositivi connessi che abbiamo oggi in tutto il mondo, a 20-30 miliardi entro il 2020 ".Varie previsioni
diciamo che il numero potrebbe essere 50 miliardi. Dispositivi controllati da computer e collegati a Internet
continuano a proliferare. Di seguito è riportato un piccolo sottoinsieme di tipi di dispositivi e applicazioni IoT.

6
ttps: //www.pubnub.com/developers/tech/howpubnubworks/ .

Dispositivi IoT

attività
tracker—
Mela
Orologio,
FitBit,

Amazon
Dash
ordinazione
casa intelligente: luci, garage
pulsanti
apri, videocamere,

Amazon assistenza sanitaria: monitor della glicemia campanelli, irrigazione

Eco per i diabetici, la pressione sanguigna controllori, dispositivi di sicurezza,

(Alexa), monitor, elettrocardiogrammi serrature intelligenti, prese intelligenti,

Mela (ECG / ECG), elettroencefalogrammi rilevatori di fumo,

HomePod (EEG), cardiofrequenzimetri, ingeribili termostati, prese d'aria

(Siri), sensori, pacemaker, rilevatori del sonno,


sensori di tsunami
Google
Casa sensori: chimici, gas, GPS,
dispositivi di localizzazione
(Google umidità, luce, movimento, pressione,

Assistente) temperatura,
frigoriferi per cantine

elettrodomestici— dispositivi di rete wireless


forni, caffè
creatori,
frigoriferi,

senza conducente
macchine

terremoto
sensori

Problemi di IoT
5h

Pagina 797
Anche se c'è molto entusiasmo e opportunità nell'IoT, non tutto è positivo. Là
sono molti problemi di sicurezza, privacy ed etica. Sono stati utilizzati dispositivi IoT non protetti
7
eseguire attacchi Distributeddenialofservice (DDOS) sui sistemi informatici. Sicurezza domestica
le telecamere che intendi proteggere la tua casa potrebbero essere potenzialmente violate per consentire ad altri
accesso al flusso video. I dispositivi controllati dalla voce sono sempre "in ascolto" per ascoltarli
parole chiave. Questo porta a problemi di privacy e sicurezza. I bambini hanno ordinato accidentalmente
prodotti su Amazon parlando con i dispositivi Alexa e le aziende hanno creato annunci TV che
attiverebbe i dispositivi Google Home pronunciando le loro parole di attivazione e provocando Google
8
Assistente per leggere le pagine di Wikipedia su un prodotto per te. Alcune persone temono che questi
i dispositivi potrebbero essere usati per origliare. Proprio di recente, un giudice ha ordinato ad Amazon di consegnare Alexa
9
registrazioni da utilizzare in un procedimento penale.

7
ttps: //threatpost.com/iotsecurityconcernspeakingwithnoendinsight/131308/ .

8.
ttps: //www.symantec.com/content/dam/symantec/docs/securitycenter/white
apers / istrsecurityvoiceactivatedsmartspeakersen.pdf .

9
ttps: //techcrunch.com/2018/11/14/amazonechorecordingsjudge
urdercase / .

Esempi di questa sezione


In questa sezione, discuteremo il modello di pubblicazione / sottoscrizione dell'IoT e di altri tipi di
le applicazioni usano per comunicare. Innanzitutto, senza scrivere alcun codice, creerai un file webbased
dashboard utilizzando Freeboard.io e iscriviti a un live streaming di esempio da PubNub
servizio. Successivamente, simulerai un termostato connesso a Internet che pubblica messaggi a
il servizio gratuito Dweet.io utilizzando il modulo Python Dweepy, quindi crea una dashboard
visualizzazione di esso con Freeboard.io. Infine, costruirai un client Python che sottoscrive un file
campione live streaming dal servizio PubNub e visualizza dinamicamente lo streaming con
Seaborn e una funzione Matplotlib.

16.8.1 Pubblica e sottoscrivi

I dispositivi IoT (e molti altri tipi di dispositivi e applicazioni) comunicano comunemente con
l'un l'altro e con applicazioni tramite sistemi pub / sub (editore / abbonato) . UN
editore è qualsiasi dispositivo o applicazione che invia un messaggio a un servizio basato su cloud, che
a sua volta invia quel messaggio a tutti gli abbonati . In genere ogni editore specifica un argomento o
canale e ogni iscritto specifica uno o più argomenti o canali per i quali desidera
per ricevere messaggi. Oggigiorno sono in uso molti pub / sottosistemi. Nel resto di questo
sezione, useremo PubNub e Dweet.io. Dovresti anche indagare su Apache Kafka: a
Componente dell'ecosistema Hadoop che fornisce un servizio di pubblicazione / sottoscrizione ad alte prestazioni,
elaborazione del flusso in tempo reale e archiviazione dei dati in streaming.

16.8.2 Visualizzazione di un live streaming di esempio PubNub con un bordo libero


Pannello di controllo

PubNub è un servizio pub / sub orientato alle applicazioni in tempo reale in cui qualsiasi software e
il dispositivo connesso a Internet può comunicare tramite piccoli messaggi. Alcuni di loro
i casi d'uso comuni includono IoT, chat, giochi multiplayer online, app social e collaborativo
app. PubNub fornisce diversi live streaming per scopi di apprendimento, incluso uno che
simula sensori IoT ( la sezione 16.8.5 elenca gli altri).

T
p5S
hm
Pagina 798
Un uso comune dei flussi di dati in tempo reale è visualizzarli a scopo di monitoraggio.In questo
sezione, collegherai il flusso di sensori simulato dal vivo di PubNub a un webbased di Freeboard.io
pannello di controllo. Il cruscotto di un'auto visualizza i dati dai sensori dell'auto, mostrando le informazioni
come la temperatura esterna, la velocità, la temperatura del motore, il tempo e la quantità di
gas rimanente. Una dashboard basata sul Web fa la stessa cosa per i dati provenienti da varie fonti,
compresi i dispositivi IoT.

Freeboard.io è uno strumento di visualizzazione del dashboard dinamico basato su cloud.Lo vedrai, senza
scrivendo qualsiasi codice, puoi facilmente connettere Freeboard.io a vari flussi di dati e visualizzare
i dati come arrivano. La dashboard seguente visualizza i dati di tre dei quattro
sensori simulati nel flusso di sensori IoT simulato di PubNub:

Per ogni sensore, abbiamo utilizzato un indicatore (le visualizzazioni semicircolari) e uno Sparkline (il
linee frastagliate) per visualizzare i dati. Una volta completata questa sezione, vedrai gli indicatori e
I grafici sparkline si spostano frequentemente quando nuovi dati arrivano più volte al secondo.

Oltre al loro servizio a pagamento, Freeboard.io fornisce una versione opensource (con meno file
opzioni) su GitHub. Forniscono anche tutorial che mostrano come aggiungere plug- in personalizzati , quindi
puoi sviluppare le tue visualizzazioni da aggiungere ai loro dashboard.
Iscriversi a Freeboard.io
Per questo esempio, registrati per una prova di 30 giorni di Freeboard.io all'indirizzo

ttps: //freeboard.io/signup

Dopo esserti registrato, viene visualizzata la pagina I miei bordi liberi.Se lo desideri, puoi fare clic su
Prova un pulsante Tutorial e visualizza i dati dal tuo smartphone.

Creazione di una nuova dashboard

Pagina 799
Nell'angolo in alto a destra della pagina My Freeboards, accedere a Sensor Dashboard nel file
inserisci un campo nome, quindi fai clic sul pulsante Crea nuovo per creare una dashboard. Questo viene visualizzato
il designer di dashboard.

Aggiunta di un'origine dati


Se aggiungi le tue origini dati prima di progettare la dashboard, sarai in grado di configurare
ogni visualizzazione mentre la aggiungi:

1. In DATASOURCES, fare clic su AGGIUNGI per specificare una nuova origine dati.

2. L'elenco a discesa TYPE della finestra di dialogo DATASOURCE mostra i dati attualmente supportati
0
sorgenti, sebbene sia possibile sviluppare plugin anche per nuove sorgenti dati.Seleziona PubNub.
La pagina web per ogni live streaming di esempio PubNub specifica il canale e l'iscrizione
chiave. Copia questi valori dalla pagina Sensor Network di PubNub all'indirizzo
ttps: //www.pubnub.com/developers/realtimedatastreams/sensor
etwork / , quindi inserire i loro valori nei campi di dialogo DATASOURCE corrispondenti.
Fornisci un NOME per la tua origine dati, quindi fai clic su SALVA.

0
Alcune delle origini dati elencate sono disponibili solo tramite Freeboard.io, non tramite il
Freeboard open source su GitHub.

Aggiunta di un riquadro per il sensore di umidità


Una dashboard di Freeboard.io è divisa in riquadri che raggruppano le visualizzazioni.Più riquadri possono
essere trascinato per riorganizzarli. Fare clic sul pulsante + Aggiungi riquadro per aggiungere un nuovo riquadro. Ogni riquadro
può avere un titolo. Per impostarlo, fare clic sull'icona della chiave inglese nel riquadro, specificare Umidità per
TITLE, quindi fai clic su SALVA.

Aggiunta di un indicatore al riquadro dell'umidità


Una dashboard di Freeboard.io è divisa in riquadri che raggruppano le visualizzazioni.Più riquadri possono
essere trascinato per riorganizzarli. Fare clic sul pulsante + Aggiungi riquadro per aggiungere un nuovo riquadro. Ogni riquadro
può avere un titolo. Per impostarlo, fare clic sull'icona della chiave inglese nel riquadro, specificare Umidità per
TITLE, quindi fai clic su SALVA.

Si noti che il valore di umidità ha quattro cifre di precisione a destra del punto decimale.
PubNub supporta le espressioni JavaScript, quindi puoi utilizzarle per eseguire calcoli o
formattare i dati. Ad esempio, puoi utilizzare la funzione Math.round di JavaScript per arrotondare il file
valore di umidità al numero intero più vicino. Per farlo, passa il mouse sull'indicatore e fai clic su di esso
icona della chiave inglese. Quindi, inserisci "Math.round (" prima del testo nel campo VALORE e ")" dopo
il testo, quindi fare clic su SALVA.

Aggiunta di un grafico sparkline al riquadro dell'umidità

Un grafico sparkline è un grafico a linee senza assi tipicamente utilizzato per darti un'idea di come un file
il valore dei dati cambia nel tempo. Aggiungi un sparkline per il sensore di umidità facendo clic su
pulsante + del riquadro di umidità, quindi selezionando Sparkline dall'elenco a discesa TIPO. Per il
VALUE, seleziona nuovamente la sorgente dati e l'umidità, quindi fai clic su SALVA.

Completamento della dashboard


Usando le tecniche sopra, aggiungi altri due riquadri e trascinali a destra del primo.

hio
6n

Assegna loro un nome rispettivamente a Livello di radiazione e Temperatura ambiente e configura


Pagina 800

ogni riquadro con un indicatore e un grafico sparkline come mostrato sopra.Per l'indicatore del livello di radiazione,
specificare Millirad / ora per le UNITÀ e 400 per il MASSIMO. Per l'ambiente
Indicatore di temperatura, specificare Celsius per le UNITÀ e 50 per il MASSIMO.

16.8.3 Simulazione di un termostato connesso a Internet in Python


La simulazione è una delle applicazioni più importanti dei computer. Abbiamo usato la simulazione con
dadi che rotolano nei capitoli precedenti. Con IoT, è comune utilizzare simulatori per testare il tuo
applicazioni, soprattutto quando non si ha accesso a dispositivi e sensori effettivi mentre
sviluppo di applicazioni. Molti fornitori di cloud dispongono di funzionalità di simulazione IoT, come IBM
Piattaforma Watson IoT e IOTIFY.io.

Qui creerai uno script che simula la pubblicazione di un termostato connesso a Internet
messaggi JSON periodici, chiamati dweets, a dweet.io. Il nome "dweet" è basato su
"Tweet": un dweet è come un tweet da un dispositivo. Molte delle odierne protezioni connesse a Internet
i sistemi includono sensori di temperatura che possono emettere avvisi di bassa temperatura prima dei tubi
avvisi di congelamento o alta temperatura per indicare che potrebbe esserci un incendio. Il nostro sensore simulato
invierà dweets contenenti una posizione e una temperatura, nonché bassa e alta temperatura
notifiche. Questi saranno veri solo se la temperatura raggiunge 3 gradi Celsius o 35
gradi Celsius, rispettivamente. Nella prossima sezione, useremo freeboard.io per creare un semplice file
dashboard che mostra le variazioni di temperatura all'arrivo dei messaggi, oltre agli avvisi
luci per avvisi di bassa e alta temperatura.

Installazione di Dweepy
Per pubblicare messaggi su dweet.io da Python, installa prima la libreria Dweepy:

pip installa dweepy

La libreria è semplice da usare. È possibile visualizzare la sua documentazione su:

ttps: //github.com/paddycarey/dweepy

Invocare lo script simulator.py

Lo script Python simulator.py che simula il nostro termostato si trova nel ch16
sottocartella iot della cartella di esempio. Si richiama il simulatore con due argomenti della riga di comando
che rappresenta il numero di messaggi totali da simulare e il ritardo in secondi tra
invio di dweets:

ipython simulator.py 1000 1

Invio di Dweets
Il file simulator.py è mostrato di seguito. Utilizza la generazione di numeri casuali e Python

tecniche che hai studiato in questo libro, quindi ci concentreremo solo su poche righe di codice
che pubblicano messaggi su dweet.io tramite Dweepy. Abbiamo suddiviso lo script qui sotto per
scopi di discussione.

Pagina 801
Per impostazione predefinita, dweet.io è un servizio pubblico, quindi qualsiasi app può pubblicare o iscriversi ai messaggi.
Quando pubblichi i messaggi, ti consigliamo di specificare un nome univoco per il tuo dispositivo.
1
Abbiamo usato "Temperatureimulatordeitelpython" (riga 17). Le righe 18–21 definiscono a
Dizionario Python, che memorizzerà le informazioni correnti del sensore. Dweepy lo convertirà
in JSON quando invia il file dweet.

1
Per garantire veramente un nome univoco, dweet.io può crearne uno per te. Il Dweepy
la documentazione spiega come farlo.

lecca qui per visualizzare l'immagine del codice

1 # simulator.py
2 "" "Un simulatore di termostato connesso che pubblica JSON
3 messaggi a dweet.io "" "
4 import dweepy
5 import sys
6 tempo di importazione
7 importazione casuale
8
9 MIN_CELSIUS_TEMP = 25
10 MAX_CELSIUS_TEMP = 45
11 MAX_TEMP_CHANGE = 2
12
13 # ottieni il numero di messaggi da simulare e il ritardo tra di loro
14 NUMBER_OF_MESSAGES = int (sys.argv [ 1 ])
15 MESSAGE_DELAY = int (sys.argv [ 2 ])
16
17 dweeter = 'temperatureimulatordeitelpython' # fornisce un nome univoco
18 termostato = { "Località" : "Boston, MA, USA" ,
19 'Temperatura' : 20 ,
20 'LowTempWarning' : False ,
21 "HighTempWarning" : False }
22

Le righe 25–53 producono il numero di messaggi simulati specificato. Durante ogni iterazione di
il ciclo, noi

generare una variazione di temperatura casuale nella gamma da –2 a +2 gradi e modificare il


temperatura,

assicurarsi che la temperatura rimanga nell'intervallo consentito,

controllare se il sensore di bassa o alta temperatura è stato attivato e aggiornare il


dizionario del termostato di conseguenza,

mostra quanti messaggi sono stati generati finora,

usa Dweepy per inviare il messaggio a dweet.io (riga 52) e

utilizzare la funzione sleep del modulo time per attendere prima il periodo di tempo specificato
generare un altro messaggio.

lecca qui per visualizzare l'immagine del codice

23 print ( "Avvio del simulatore di temperatura" )


24

6C

25 per il messaggio in gamma ( NUMBER_OF_MESSAGES ):


Pagina 802
26 # genera un numero casuale nell'intervallo MAX_TEMP_CHANGE
Da 27 # a MAX_TEMP_CHANGE e aggiungerlo alla temperatura corrente
28 termostato [ "Temperatura" ] + = random.randrange (
29 MAX_TEMP_CHANGE , MAX_TEMP_CHANGE + 1)
30
31 # assicurarsi che la temperatura rimanga entro l'intervallo
32 se il termostato [ "Temperatura" ] < MIN_CELSIUS_TEMP :
33 termostato [ "Temperatura" ] = MIN_CELSIUS_TEMP
34
35 se il termostato [ "Temperatura" ]> MAX_CELSIUS_TEMP :
36 termostato [ "Temperatura" ] = MAX_CELSIUS_TEMP
37
38 # controlla l'avviso di bassa temperatura
39 se il termostato [ 'Temperatura' ] < 3 :
40 termostato [ "LowTempWarning" ] = True
41 altro :
42 termostato [ "LowTempWarning" ] = False
43
44 # controlla l'avviso di alta temperatura
45 se il termostato [ 'Temperatura' ]> 35 :
46 termostato [ "HighTempWarning" ] = True
47 altro :
48 termostato [ "HighTempWarning" ] = False
49
50 # invia il dweet a dweet.io tramite dweepy
51 print (f 'Messaggi inviati: {messaggio + 1 } \ r' , end = '' )
52 dweepy.dweet_for (dweeter, termostato)
53 time.sleep ( MESSAGE_DELAY )
54
55 print ( "Simulatore di temperatura terminato" )

Non è necessario registrarsi per utilizzare il servizio. Alla prima chiamata a dweepy's dweet_for
funzione per inviare un dweet (riga 52), dweet.io crea il nome del dispositivo. La funzione
riceve come argomenti il ​nome del dispositivo (dweeter) e un dizionario che rappresenta il messaggio

inviare (termostato). Una volta eseguito lo script, puoi iniziare immediatamente a monitorare il file
messaggi sul sito dweet.io andando al seguente indirizzo nel tuo browser web:

ttps: //dweet.io/follow/temperaturesimulatordeitelpython

Se usi un nome di dispositivo diverso, sostituisci "Temperatureimulatordeitelpython"


con il nome che hai usato. La pagina web contiene due schede. La scheda Visual ti mostra il file
singoli elementi di dati, visualizzando un grafico sparkline per qualsiasi valore numerico.Viene visualizzata la scheda Raw
tu i messaggi JSON effettivi che Dweepy ha inviato a dweet.io.
16.8.4 Creazione del dashboard con Freeboard.io
I siti dweet.io e freeboard.io sono gestiti dalla stessa azienda. Nel file dweet.io
pagina Web discussa nella sezione precedente, è possibile fare clic sul pulsante Crea personalizzato
Pulsante Dashboard per aprire una nuova scheda del browser, con già una dashboard predefinita
implementato per il sensore di temperatura. Per impostazione predefinita, freeboard.io configurerà un file data
fonte denominata Dweet e genera automaticamente un dashboard contenente un riquadro per ogni valore in
il dweet JSON. All'interno di ogni riquadro, un widget di testo visualizzerà il valore corrispondente come
arrivano i messaggi.

Se preferisci creare la tua dashboard, puoi utilizzare i passaggi in sezione 16.8.2 per creare un file
fonte dati (questa volta selezionando Dweepy) e crea nuovi pannelli e widget, oppure puoi farlo tu

S
h

Pagina 803
modificare la dashboard generata automaticamente.

Di seguito sono riportate tre schermate di una dashboard composta da quattro widget:

Un widget Indicatore che mostra la temperatura corrente. Per l'impostazione VALUE di questo widget, noi
selezionato il campo Temperatura dell'origine dati. Abbiamo anche impostato le UNITÀ su Celsius e
i valori MINIMO e MASSIMO a 25 e 45 gradi, rispettivamente.

Un widget di testo per mostrare la temperatura corrente in Fahrenheit. Per questo widget, impostiamo l'estensione
INCLUDI SPARKLINE e CAMBIAMENTI DEL VALORE DEGLI ANIMATI su SÌ. Per questo
l'impostazione VALUE del widget, abbiamo nuovamente selezionato il campo Temperature dell'origine dati, quindi
aggiunto alla fine del campo VALUE

* 9/5 + 32

per eseguire un calcolo che converte la temperatura Celsius in Fahrenheit. Anche noi
ha specificato Fahrenheit nel campo UNITÀ.

Infine, abbiamo aggiunto due widget Indicatore luminoso. Per il VALORE della prima spia
impostazione, abbiamo selezionato il campo LowTempWarning dell'origine dati, impostato il TITLE su Freeze
Avviso e impostare il valore ON TEXT su BASSA TEMPERATURA AVVISO — SU TESTO
indica il testo da visualizzare quando il valore è vero.Per il secondo indicatore luminoso
VALUE, abbiamo selezionato il campo HighTempWarning dell'origine dati, abbiamo impostato TITLE su
Avviso alta temperatura e impostare il valore TESTO ATTIVO su TEMPERATURA ALTA
AVVERTIMENTO.

16.8.5 Creazione di un abbonato a Python PubNub


PubNub fornisce il modulo Python pubnub per eseguire comodamente pub / sub
operazioni. Forniscono anche sette flussi di esempio con cui sperimentare, quattro reali
2
flussi temporali e tre flussi simulati:

2
ttps: //www.pubnub.com/developers/realtimedatastreams/ .

6h

Pagina 804
Twitter Stream: fornisce fino a 50 tweetspersecondo dal live streaming di Twitter e
non richiede le tue credenziali Twitter.
Articoli di notizie hacker: articoli recenti di questo sito.

State Capital Weather: fornisce dati meteorologici per le capitali degli Stati Uniti.

Modifiche di Wikipedia: un flusso di modifiche di Wikipedia.

Game State Sync: dati simulati da un gioco multiplayer.

Rete di sensori: dati simulati da radiazioni, umidità, temperatura e ambiente


sensori di luce.

Ordini di mercato: ordini di azioni simulati per cinque società.

In questa sezione, utilizzerai il modulo pubnub per iscriverti ai loro ordini di mercato simulati
stream, quindi visualizza le variazioni dei prezzi delle azioni come un barplot di Seaborn, come:

Ovviamente puoi anche pubblicare messaggi negli stream. Per i dettagli, vedere il modulo pubnub
documentazione su TTP: //www.pubnub.com/docs/python/pubnubpythonsdk .

Per prepararti all'uso di PubNub in Python, esegui il seguente comando per installare l'ultimo
versione del modulo pubnub: "> = 4.1.2" garantisce che almeno la versione 4.1.2
del modulo pubnub verrà installato:

pip install "pubnub> = 4.1.2"

Lo script stocklistener.py che si iscrive allo stream e visualizza i prezzi delle azioni
è definito nella sottocartella pubnub della cartella ch16.Abbiamo spezzato la sceneggiatura qui per

scopi di discussione.

M
h
formato essage

Formato messaggio Pagina 805

Il flusso simulato degli ordini di mercato restituisce oggetti JSON contenenti cinque coppie chiave-valore
con le chiavi "bid_price", "order_quantity", "symbol", "timestamp" e

"trade_type". Per questo esempio, utilizzeremo solo "bid_price" e "symbol". Il


Il client PubNub ti restituisce i dati JSON come dizionario Python.

Importazione delle librerie


Le righe 3–13 importano le librerie utilizzate in questo esempio. Discutiamo i tipi di PubNub importati
nelle righe 10-13 come li incontriamo di seguito.

lecca qui per visualizzare l'immagine del codice

1 # stocklistener.py
2 "" "Visualizzazione di un live streaming su PubNub." ""
3 da matplotlib importazione di animazione
4 importa matplotlib.pyplot come plt
5 importa i panda come pd
6 importazione casuale
7 import seaborn come sns
8 import sys
9
10 da pubnub.callbacks import IscrivitiCallback
11 da pubnub.enums importa PNStatusCategory
12 da pubnub.pnconfiguration import PNConfiguration
13 da pubnub.pubnub import PubNub
14

Elenco e DataFrame utilizzati per memorizzare nomi e prezzi delle società


L'elenco delle società contiene i nomi delle società riportate negli Ordini di Mercato
stream e le società DataFrame panda_df è dove memorizzeremo ciascuna società
ultimo prezzo. Useremo questo DataFrame con Seaborn per visualizzare un grafico a barre.

lecca qui per visualizzare l'immagine del codice

15 aziende = [ "Apple" , "Bespin Gas" , "Elerium" , "Google" , "Linen Cloth


16
17 # DataFrame per memorizzare gli ultimi prezzi delle azioni
18 aziende_df = pd.DataFrame (
19 { 'company' : companies, 'price' : [ 0 , 0 , 0 , 0 , 0 ]})
20

Classe SensorSubscriberCallback

Quando ti iscrivi a uno stream PubNub, devi aggiungere un listener che riceve lo stato
notifiche e messaggi dal canale. Questo è simile agli ascoltatori di Tweepy che hai
definito in precedenza. Per creare il tuo ascoltatore, devi definire una sottoclasse di
IscrivitiCallback (modulo pubnub.callbacks), di cui discutiamo dopo il codice:

lecca qui per visualizzare l'immagine del codice

21 classe SensorSubscriberCallback (SubscribeCallback):


22 "" "SensorSubscriberCallback riceve messaggi da PubNub." ""
23 def __init __ (self, df, limit = 1000 ):

24 "" "Crea variabili di istanza per tenere traccia del numero di tweet." ""
Pagina 806
25 self.df = df # DataFrame per memorizzare gli ultimi prezzi delle azioni
26 self.order_count = 0
27 auto. MAX_ORDERS = limite # 1000 per impostazione predefinita
28 super () .__ init __ () # richiama l'inizializzazione della superclasse
29
30 def status (self, pubnub, status):
31 if status.category == PNStatusCategory.PNConnectedCategory :
32 print ( "Connesso a PubNub" )
33 elif status.category == PNStatusCategory.PNA recognitionCategory :
34 print ( 'Disconnesso da PubNub' )
35
36 def messaggio (self, pubnub, message):
37 simbolo = messaggio.messaggio [ "simbolo" ]
38 bid_price = message.message [ "bid_price" ]
39 print (symbol, bid_price)
40 self.df.at [companies.index (symbol), 'price' ] = bid_price
41 self.order_count + = 1
42
43 # se viene raggiunto MAX_ORDERS, annulla l'iscrizione al canale PubNub
44 se self.order_count == self. MAX_ORDERS :
45 pubnub.unsubscribe_all ()
46

Il metodo __init__ della classe SensorSubscriberCallback memorizza il DataFrame in cui


ogni nuovo prezzo delle azioni verrà posizionato. Il client PubNub chiama ogni stato del metodo sottoposto a override
volta che arriva un nuovo messaggio di stato. In questo caso, stiamo controllando le notifiche che
indica che ci siamo iscritti o annullati da un canale.

Il client PubNub chiama il messaggio del metodo sovrascritto (righe 36–45) quando un nuovo messaggio
arriva dal canale. Le righe 37 e 38 ottengono il nome dell'azienda e il prezzo dal messaggio,
che stampiamo in modo che tu possa vedere che i messaggi stanno arrivando. La riga 40 utilizza DataFrame
metodo in per individuare la riga della società appropriata e la relativa colonna "prezzo", quindi assegnare
quell'elemento il nuovo prezzo. Quando order_count raggiunge MAX_ORDERS, la riga 45 chiama il
Il metodo unsubscribe_all del client PubNub per annullare l'iscrizione al canale.

Aggiornamento delle funzioni


Questo esempio visualizza i prezzi delle azioni utilizzando le tecniche di animazione che hai imparato
APITOLO 6 ‘s Introduzione alla sezione Science Data. L'aggiornamento della funzione specifica come disegnarne uno
frame di animazione e viene chiamato ripetutamente dalla FuncAnimation che definiremo a breve.Noi usiamo
Seaborn funzione barplot per visualizzare i dati dalle aziende_df DataFrame, utilizzando il suo file

valori di colonna 'aziendali' sulla x assi ei valori 'prezzo' di colonna sulla y asse.
lecca qui per visualizzare l'immagine del codice

47 aggiornamento def (frame_number):


48 "" "Configura i contenuti del grafico a barre per ogni fotogramma dell'animazione." ""
49 plt.cla () # cancella il vecchio barplot
50 assi = sns.barplot (
51 data = companies_df, x = 'company' , y = 'price' , palette = 'cool' )
52 axes.set (xlabel = 'Company' , ylabel = 'Price' )
53 plt.tight_layout ()
54

Configurazione della figura

C
Pagina 807
Nella parte principale della sceneggiatura, iniziamo impostando lo stile di trama di Seaborn e creando il
Oggetto figura in cui verrà visualizzato il grafico a barre:

lecca qui per visualizzare l'immagine del codice

55 if __name__ == '__main__' :
56 sns.set_style ( 'whitegrid' ) # sfondo bianco con griglie grigie
57 figure = plt.figure ( 'Prezzi delle azioni' ) # Cifra per l'animazione
58

Configurazione di FuncAnimation e visualizzazione della finestra

Successivamente, impostiamo FuncAnimation che chiama l'aggiornamento della funzione, quindi chiamiamo lo spettacolo di Matplotlib
metodo per visualizzare la figura. Normalmente, questo metodo impedisce allo script di continuare fino a
chiudi la figura. Qui, passiamo l'argomento della parola chiave block = False per consentire il
script per continuare in modo da poter configurare il client PubNub e iscriversi a un canale.

lecca qui per visualizzare l'immagine del codice

59 # configura e avvia l'animazione che richiama l'aggiornamento della funzione


60 stock_animation = animation.FuncAnimation (
61 cifre, aggiornamento, ripetizione = Falso , intervallo = 33 )
62 plt. Mostra (block = False ) # finestra di visualizzazione
63

Configurazione del client PubNub


Successivamente, configuriamo la chiave di sottoscrizione PubNub, che il client PubNub utilizza in
combinazione con il nome del canale per iscriversi al canale. La chiave è specificata come
attributo dell'oggetto PNConfiguration (modulo pubnub.pnconfiguration), che
la riga 69 passa al nuovo oggetto client PubNub (modulo pubnub.pubnub). Righe 70-72
creare l'oggetto SensorSubscriberCallback e passarlo al client PubNub

metodo add_listener per registrarlo per ricevere messaggi dal canale. Usiamo un file
argomento della riga di comando per specificare il numero totale di messaggi da elaborare.

lecca qui per visualizzare l'immagine del codice

64 # imposta la chiave stream del sensore pubnubmarketorders


65 config = PNConfiguration ()
66 config.subscribe_key = 'subc4377ab04f10011e3bffd02ee2ddab7fe'
67
68 # crea il client PubNub e registra un SubscribeCallback
69 pubnub = PubNub (config)
70 pubnub.add_listener (
71 SensorSubscriberCallback (df = companies_df,
72 limit = int (sys.argv [ 1 ] if len (sys.argv)> 1 else 1000 ))
73

Iscrizione al canale
La seguente dichiarazione completa il processo di iscrizione, indicando che desideriamo farlo
ricevere messaggi dal canale denominato "pubnubmarketorders". L'esecuzione
metodo avvia il flusso.

C
Pagina 808
lecca qui per visualizzare l'immagine del codice
74 # iscriviti al canale pubnubsensornetwork e inizia lo streaming
75 pubnub.subscribe (). Channels ( 'pubnubmarketorders' ) .execute ()
76

Garantire che la figura rimanga sullo schermo

La seconda chiamata al metodo show di Matplotlib assicura che la figura rimanga sullo schermo
finché non chiudi la sua finestra.

lecca qui per visualizzare l'immagine del codice

77 plt.show () # mantiene il grafico sullo schermo finché non chiudi la sua finestra

16.9 WRAP-UP
In questo capitolo abbiamo introdotto i big data, discusso su come vengono raccolti i dati di grandi dimensioni e discusso
infrastruttura hardware e software per lavorare con i big data. Abbiamo introdotto il tradizionale
database relazionali e SQL (Structured Query Language) e hanno utilizzato il modulo sqlite3 per
creare e manipolare un database di libri in SQLite. Abbiamo anche dimostrato il caricamento di query SQL
si traduce in panda DataFrames.

Abbiamo discusso i quattro tipi principali di database NoSQL: valore-chiave, documento, a colonne e
graph e ha introdotto i database NewSQL. Abbiamo archiviato gli oggetti tweet JSON come documenti in un file
MongoDB Atlas basato su cloud, quindi li ha riassunti in una visualizzazione interattiva
visualizzato su una mappa Folium.

Abbiamo introdotto Hadoop e come viene utilizzato nelle applicazioni bigdata.Hai configurato un multi
node Hadoop cluster utilizzando il servizio Microsoft Azure HDInsight, quindi creato ed eseguito
un'attività Hadoop MapReduce utilizzando lo streaming Hadoop.

Abbiamo discusso di Spark e di come viene utilizzato in applicazioni bigdata in tempo reale e ad alte prestazioni.
Hai utilizzato le funzionalità di filtro / mappa / riduzione dello stile funzionale di Spark, prima su un Docker Jupyter
stack che viene eseguito localmente sul tuo computer, quindi di nuovo usando un HDInsight di Microsoft Azure
cluster Spark multinodo. Successivamente, abbiamo introdotto lo streaming Spark per l'elaborazione dei dati in mini
lotti. Come parte di questo esempio, abbiamo utilizzato Spark SQL per eseguire query sui dati archiviati in Spark

DataFrames.

Il capitolo si è concluso con un'introduzione all'Internet of Things (IoT) e al


pubblica / sottoscrivi modello. Hai utilizzato Freeboard.io per creare una visualizzazione dashboard di un live
stream di esempio da PubNub. Hai simulato un termostato connesso a Internet che
ha pubblicato messaggi al servizio gratuito dweet.io utilizzando il modulo Python Dweepy, quindi
ha utilizzato Freeboard.io per visualizzare i dati del dispositivo simulato. Infine, ti sei iscritto a un file
PubNub campione di live streaming utilizzando il modulo Python.

Grazie per aver letto Python per programmatori . Ci auguriamo che il libro ti sia piaciuto e quello
l'hai trovato divertente e informativo. Soprattutto speriamo che ti senta autorizzato a candidarti
le tecnologie che hai imparato alle sfide che dovrai affrontare nella tua carriera.

C
Pagina 810
809

Potrebbero piacerti anche