Sunteți pe pagina 1din 296

ACADEMIA DE STUDII ECONOMICE BUCUREŞTI

FACULTATEA DE CIBERNETICĂ, STATISTICĂ ŞI INFORMATICĂ ECONOMICĂ

PA C H E T E
SO F T WARE
CURS 1
CUPRINS CURS 1
1. Introducere Pachete Software

2. Excel - Visual Basic for Application


(VBA)

3. Python

4. Programare SAS

5. SAS Enterprise Guide


INTRODUCERE
PACHETE
SOFTWARE
DEFINIȚIE

 Pachet software
Mai multe programe software care conlucrează
pentru îndeplinirea unui set de obiective şi care
sunt distribuite sau vândute împreună.

• Aplicatii economice
CADRE DIDACTICE
TITULAR CURS
• Conf.univ.dr. Simona Oprea – simona.oprea@csie.ase.ro
SEMINAR
• Conf.univ.dr. Simona Oprea – simona.oprea@csie.ase.ro
• Prof.univ.dr. Adina Uță – adina.uta@ie.ase.ro
• Drd. Oana Virgolici
• Drd. Ramona Vines
• Drd. Dragos Barbu
• Drd. Gabriela Ene

COLECTIV
• Prof.univ.dr. Adina Uță – adina.uta@ie.ase.ro
• Conf.univ.dr. Simona Oprea – simona.oprea@csie.ase.ro
• Conf.univ.dr. Anca Andreescu – anca.andreescu@ase.ro
• Conf.univ.dr. Anda Belciu – anda.velicanu@ie.ase.ro
MODALITATE EVALUARE
• Examen final – 50%
– Subiecte tip grilă, cu rezolvare
• Seminar – 50%
– Test practic pe calculator 40%
– Proiect individual 60%
– Activitate pe parcurs ( punctaj suplimentar 10%)
• Condiţii de intrare în examen: minim nota 5 la testul practic
și minim nota 5 la susținere proiect!
• Condiție de promovare a examenului: minim nota 5!
• REEXAMINARE: se susţine examen + se refac probele de
seminar nesusţinute
RESURSE

https://online.ase.ro/
Adina Uta, Anca Andreescu, Simona Oprea, Pachete software și
aplicatii SAS, editura ASE, Bucureşti, 2018, România
S. Slaughter and L. Delwiche, The Little SAS Book: A Primer, Fifth
Edition 5th Edition, SAS Press, 2012
Mark Summerfield, Programming in Python 3, A Complete
Introduction to the Python Language, , Addison-Wesley, 2010
Mark Lutz , Learning Python, O'Reilly, 2013

https://support.sas.com/en/documentation.html
PRELUCRAREA DATELOR

Optimizare • Identifică și evalueză noi


Prescriptive posibilități de operare
Ce trebuie să • Urmărește obiectivele afacerii
facem? • Echilibrează constrângerile
Dinamica sistemului
Complexitate matematică

Previziuni statistice • Realizează prognoze și treduri


Înțelegere

Predictive și simulare viitoare


Ce se poate • Identifică relații în date care nu
întâmpla? Data mining și pot fi ușor evidențiate cu
pattern recognition analizele tradiționale

Raportare • Pregătesc și analizează date


istorice
Descriptive Vizualizare • Identifică șabloane din
Ce s-a întâmplat? eșantioane pentru raportări și
Modelarea datelor treduri
DATE DE INTRARE PENTRU PRELUCRĂRI

Sursă Exemple de sursă


Date tranzacționale Date asociate cu un eveniment tranzacțional. Exemplu: o achiziție care conține detalii
ale articolului achiziționat, unde și când a fost achiziționat, prețul plătit și orice
reduceri aplicate, modul în care a plătit clientul. Date relevante din punct de vedere
contextual (de exemplu, inventarul unor articole aflate la reducere în același timp și în
aceeași locație).
Date despre clienți Date asociate clienților. Exemple: detalii demografice, istoric al interacțiunilor
(achiziții anterioare, vizite pe site-uri web, cereri către serviciul clienți).
Date de la senzori Date colectate prin instrumente electronice sau mecanice. Exemple: cookie-urile
browserului web care urmăresc activitatea clientului, senzori electronici care
monitorizează condițiile meteorologice.
Date publice Date cu acces liber de la persoane fizice, organizații și guverne. Exemplu: date
agregate culese de la recensământ.
Date nestructurate Date fără structură cunoscută. Exemple: text și imagini din social media, înregistrări
din call center, date calitative culese din studii etnografice.
Date din sondaje, Datele colectate cu scopul specific de a analiza anumite aspecte sociale, economice,
studii comerciale sau politice.
LIMBAJE DE PROGRAMARE SPECIFICE

Top 6 limbaje pentru prelucrarea


analitică a datelor (2019)

• Python - open source, versatil, de nivel general, cu o multitudine de pachete


pentru scopuri specifice
• R - open source, orientat spre prelucrări statistice
• SQL - standard pentru interogarea datelor
• Scala - extensie a Java, potrivit pentru lucrul cu volume mari de date
• SAS – proprietar, cu o gamă foarte largă de pachete și librării pentru toate
tipurile de prelucrare analitică a datelor
• Julia – open source, de nivel general, potrivit operațiilor matematice complexe
Sondaj grad de utilizare: https://www.burtchworks.com/2018/07/16/2018-sas-r-or-python-
survey-results-which-do-data-scientists-analytics-pros-prefer/
MODALITĂȚI DE LUCRU
Se pot identifica trei modalități de lucru în ceea ce privește utilizarea
pachetelor software pentru prelucrarea analitică a datelor:
1. Folosirea interfeței grafice de tipul point-and-click
Caracteristici: reducerea timpului de lucru, scăderea probabilității de
apariție a erorilor, limitări ale prelucrărilor implementate
Exemple: Microsoft Excel, SAS Enterprise Guide
2. Folosirea combinată a interfeței grafice de tipul point-and-click și a
limbajului de programare specific pachetului
Caracteristici: oferă posibilitatea extinderii capabilităților prelucrărilor
implementate, permite automatizarea operațiilor repetitive
Exemple: Microsoft Excel+limbajul VBA sau macrocomenzi, SAS
Enterprise Guide + limbajul SAS
3. Scrierea de cod în limbaje de programare specifice
Caracteristici: oferă flexibilitate ridicată, timpul de lucru poate crește,
necesită cunoștințe tehnice avansate
Exemple: limbajul Python cu PyCharm, limbajul SAS cu SAS Studio
EXCEL. VISUAL
BASIC FOR
A P P L I C AT I O N
EXCEL VBA / 1
Calcul tabelar: utilizarea referintelor absolute si relative
Functii logice
Functii financiare
Functii matriciale
Functii definite de utilizator (UDFs)
Macrocomenzi
Goal Seek
What if
Solver
Pivot Table
EXCEL VBA / 2
1) Prelucrare automată fișiere multiple
- Deschidere fisiere  Preluare date  Prelucrare  Centralizare 
Închidere fișiere
2) Prelucrări automate la nivel de fișier
- Exemplu: Eliminare valori duplicat
- Exemplu: Eliminare valori condiționat
3) Funcții definite de utilizator
- Acordarea unor discounturi în funcție de anumite criterii
- Însumare numere pare/impare
- Prelucrare șiruri de caractere
4) Funcții predefinite (VLOOKUP, IFS, SUMIFS, COUNTIF,
CONCATENATE, YEAR etc.)
5) Utilizare pivot table
1) Prelucrare automată fișiere multiple EXCEL VBA / 3
Deschidere fișiere  Preluare date  Prelucrare  Centralizare  Închidere
fișiere
EXCEL VBA / 4
2) Prelucrări automate la nivel de fișier
- Exemplu: Eliminare valori duplicat

Inițial: 499 înregistrări


Rulare subrutină: 37 înregistrări
2) Prelucrări automate la nivel de fișier EXCEL VBA / 5
- Exemplu: Eliminare valori condiționat
3) Funcții definite de utilizator EXCEL VBA / 6
- Exemplu: calcul discount
3) Funcții definite de utilizator
- Exemplu: calcul discount EXCEL VBA / 7
3) Funcții definite de utilizator EXCEL VBA / 8
- Exemplu: însumare numere pare
3) Funcții definite de utilizator EXCEL VBA / 9
- Exemplu: însumare numere pare
3) Funcții definite de utilizator
- Exemplu: extrage număr dintr-un șir de caractere EXCEL VBA / 10
https://www.ozgrid.com/VBA/Functions.htm
3) Funcții definite de utilizator EXCEL VBA / 11
- Exemplu: extrage număr dintr-un șir de caractere
EXCEL PIVOT TABLE / 12
EXCEL PIVOT TABLE / 13
EXCEL PIVOT TABLE / 14
1% 2% 0% 0% 0%
0% 0% 0% 0% 0% 0% 0% 0% 0% ALBA

0% 0%
0% Arges

0% Bacau
0% Bihor
0% 8% BISTRITA-NASAUD
Botosani
Braila
28% Buzau
CALARASI
Călărași
Cluj
CONSTANTA
COVASNA
0% Dambovita
Dolj
0% GIURGIU

0% Gorj

1% HARGHITA
Hunedoara
0% 0% IALOMITA
Iasi
ILFOV
59% Jud. Hunedoara
MURES
Neamt
Prahova
EXCEL PIVOT TABLE / 15
• Prelucare sintetică a datelor din fișierul clienti_leasing.xlsx
• 18239 înregistrări
• Să se determine:
1) Venitul mediu pe categorii de funcții
2) Suma venitului clienților în funcție de starea civilă și sex
3) Distribuția prescoringului pe sexe
VENITUL MEDIU PE CATEGORII DE FUNCȚII

19% 19%

Agent comercial 342101


Agricultor
3% Avocat
Barman 512301
Bucatar 512201
22% Economist
Medic
29%

6%
2%
SUMA VENITULUI CLIENȚILOR IN FUNCȚIE DE STAREA CIVILĂ ȘI SEX
DISTRIBUȚIA PRESCORINGULUI PE SEXE
PYTHON
PYTHON (I)

• Noțiuni introductive. Reguli


• Tipuri de date
• Colecții de date: liste, seturi, dicționare, tupluri
• Metode pentru colecții de date
• Operatori aritmetici, de apartenență, logici, de
comparaței, de atribuire
• Structuri de programare
• Funcții definite de utilizator
PYTHON (II, III)

• Accesare și prelucrare date din fișiere


• Pachetul pandas
• Prelucrare date în pandas
• Prelucrări statistice
• Joncțiunea seturilor de date în pandas
• Gruparea și agregarea datelor
• Reprezentări grafice. Pachetul
matplotlib
PYTHON (IV)

• Pachetul scikit-learn
• Clusterizare: k-means
• Predicții
• Reprezentări grafice: pachetul seaborn
• Regresie logistică
• Regresie multiplă
PYTHON (V)

• Pachetul cx-Oracle
• Încărcare și prelucrare date în pandas
• Prelucrare date din BD
- Interogări (cu parametri)
- Gestionarea tranzacțiilor
- Actualizarea datelor
PROGRAMARE
SAS
PROGRAMARE
SAS (I)
• Sistemul integrat SAS
• Reguli de sintaxă
• Crearea seturilor de date
din fișiere externe
• Tipuri de date
• Biblioteci SAS
• Crearea seturilor de date
din fișiere flat
• Asignarea de etichete
• Formate SAS de afișare
PROGRAMARE
SAS (II)

• Crearea și gestiunea variabilelor


• Subseturi de date
• Operatori logici și de comparație
• Procesare iterativă și condițională
• Transformarea datelor prin funcții
SAS
PROGRAMARE SAS (III)
• Combinarea seturilor de date
• Proceduri SAS
– Fuziune
– Concatenare
– Adăugare
– Interclasare
• Redenumirea variabilelor
• Proceduri SQL
• Comparație abordări
PROGRAMARE SAS
(IV)
• Categorii de proceduri SAS
• Sintaxa procedurilor SAS
• Analize factoriale de explorare, de
confirmare
• Metode cu ecuatii structurale
SAS
ENTERPRISE
GUIDE
SAS ENTERPRISE
GUIDE(I)
• Facilităţi şi caracteristici
• Paşii unei sesiuni tipice de lucru
• Lucrul cu date în cadrul unui proiect
• Definirea tabelelor de date SAS
• Accesarea datelor locale
• Interogarea datelor
• Joncţiunea tabelelor prin diferite
metode
• Înlocuirea valorilor datelor
• Gruparea şi agregarea datelor
• Specificarea unui parametru pentru
interogare
SAS ENTERPRISE
GUIDE(II)
• Prelucrări
• Tipuri de rapoarte
• Formate definite de utilizator
• Agregarea datelor
• Analize statistice
• Personalizarea stilurilor de afișare
• Rapoarte compuse
• Actualizarea rezultatelor
Introducere
în SAS

SAS 1
CUPRINS

1. Prelucrări analitice
2. Sistemul integrat SAS
3. Programare în limbajul SAS
Definirea conceptului

• Prelucrările analitice (Data Analytics) reprezintă punerea în


aplicare a
- tehnologiei informaţiei
- cercetărilor operaţionale
- statisticii in diverse domenii.
• Pot constitui intrări pentru deciziile umane sau pot determina
decizii complet automatizate.

• Sunt considerate o parte a ceea ce este cunoscut sub denumirea


de Inteligenţa afacerii.
Optimizări Cum este cel mai
bine?
Modelare predictivă Ce se va Prelucrări
întâmpla? analitice
Dacă tendinţa
Prognoze
continuă?
Analize
statistice De ce se întâmplă?

Alerte Ce se poate face?


Unde este
Interogări/descompuneri
problema? Accesare şi
Cât, cât de des, raportare
Rapoarte ah-hoc
unde?
Rapoarte standard Ce şi când s-a
întâmplat?

Niveluri de prelucrare a datelor


Beneficii ale aplicarii prelucrarilor analitice

• Asigura o baza pentru luarea deciziilor (fundamenteaza sau


justifica deciziile)
• Reduc costurile si imbunatatesc eficienta unei intreprinderi
• Anticipeaza schimbarile pietei, climatului macro-economic
Categorii de software pentru prelucrări analitice
• Instrumente bazate pe foi de calcul: Microsoft Excel
• Instrumente OLAP: Oracle BI, Power BI, Tableau
Software (pivot-table, roll-up, drill-down)
• Software pentru analize statistice – SAS STAT, SAS EG,
SPSS, SYSTAT, STATISTICA
• Limbaje pentru prelucrări analitice: R, Python
• Software pentru optimizări: Matlab, CPLEX
• Instrumente de data mining, text mining
Sistemul integrat SAS
• A fost dezvoltat la începutul anilor 1970 la North Carolina State
University.
• Intenţia iniţială a fost dezvoltarea unui sistem pentru
managementul şi analiza experimentelor în domeniul agricol.
• La momentul actual este cel mai utilizat software statistic.
• Iniţial a fost acronimul pentru “Statistical Analysis System”,
acum nu mai are acest sens.
• SAS este un sistem modular integrat pentru prelucrări analitice
şi nu numai.
Funcţii de bază ale SAS
• Introducerea, regăsirea şi managementul datelor
• Realizarea de rapoarte şi grafice
• Analize statistice şi matematice
• Previziuni şi suport decizional
• Cercetări operaţionale şi managementul proiectelor
• Dezvoltarea de aplicaţii
Modularizarea SAS
 SAS constă dintr-un număr mare de module, pe care
organizaţiile le pot achiziţiona şi instala separat.
 În centrul soluţiilor SAS se află modulul Base SAS, având
facilităţi pentru accesul la date, analiza datelor, crearea de
rapoarte etc.
 Base SAS beneficiază şi de suportul unui limbaj de
programare proprietar de generaţia a patra.
Exemple de module SAS
• Base SAS – managementul datelor şi proceduri de bază
• SAS/STAT – analize statistice
• SAS/GRAPH – grafice şi hărţi
• SAS/OR – cercetări operaţionale
• SAS/ETS – econometrie şi analiza seriilor de timp
• SAS/IML – limbaj specializat pentru lucrul cu matrice
• SAS/QC – controlul calităţii
• SAS/EG – prelucrarea datelor prin intermediul interfetelor
Moduri de lucru în SAS
• Programabil: SAS 9.4, SAS Studio
• Utilizand interfeţe generatoare de cod: SAS Enterprise Guide 7.1
Programe SAS
Un program SAS constă dintr-o succesiune de secțiuni (steps) distincte
trimise către execuţie motorului SAS. În SAS există două tipuri de
secțini: de date și de proceduri.

Secţiunile de date (DATA steps) sunt, de


obicei, folosite pentru a crea și modifica
Fişier tabele SAS.
Text
Secţiune de Secţiune de
date Tabelă proceduri
Raport
SAS
nouă
Tabele
SAS Secţiunile de proceduri (PROC steps) sunt, de
existente obicei, folosite pentru a efectua prelucrări şi
interogări.

12
Reguli de sintaxă
Instructiunile SAS au următoarele caracteristici:
 Încep, de obicei, cu un cuvânt cheie.

 Întotdeuna se termină cu punct şi virgulă.

libname ad_data '/home/nume.prenume';


data ad_data.comenzi;
infile '/home/nume.prenume/comenzi.txt';
input Nr_Comanda 1-5 ID_Produs $ 2-10
Cantitate 13-15 PretVanzare 17-22
Valoare 25-32;
run;
proc print data=ad_data.comenzi;
run;
proc means data=ad_data.comenzi;
title 'Analiza comenzilor';
var PretVanzare;
run;
13
Reguli de sintaxă
 Unul sau mai multe caractere de spaţiere pot fi folosite pentru
a separa cuvintele.
 Nu necesita indentare, nu este case-sensitive.
 O singură instructiune se poate scrie pe mai multe rânduri.
 Mai multe instructiuni pot fi scrise pe aceeaşi linie.

libname ad_data '/home/nume.prenume';


data ad_data.comenzi;
infile '/home/nume.prenume/comenzi.txt';
input Nr_Comanda 1-5 ID_Produs $ 2-10
Cantitate 13-15 PretVanzare 17-22
Valoare 25-32;
run;
proc print data=ad_data.comenzi;
run;
proc means data=ad_data.comenzi;
title 'Analiza comenzilor';
var PretVanzare; var valoare; run;
14
Comentarii
 Comentarii bloc: /*comentariu*/
 Comentarii care pot fi incluse in cod: * comentariu;
 cod * comentariu; cod…

*Crearea unei biblioteci;


libname ad_data '/home/nume.prenume';
data ad_data.comenzi;
*Citire date si definire coloane; infile
'/home/nume.prenume/comenzi.txt';
input Nr_Comanda 1-5 ID_Produs $ 2-10
Cantitate 13-15 PretVanzare 17-22 Valoare 25-32;
run;
/*Realizeaza un raport lista pentru ad_data.comenzi*/
proc print data=ad_data.comenzi;
run;

15
Limite ale unei secţiuni

 SAS compilează şi execută fiecare secţiune în mod


independent bazandu-se pe ceea ce poartă denumirea de
limite ale unei secţiuni.
 Limitele unei secţiuni:
 Limite explicite: RUN şi QUIT au rolul de a executa
secţiunea anterioară;
 Limite implicite: DATA şi PROC indică începutul unei
secţiuni.
 O secţiune de date sau de proceduri se termină atunci
când se întâlneşte o altă secţiune, ceea ce înseamnă că
prezenţa declaraţiilor RUN şi QUIT nu este obligatorie.

16
Crearea seturilor de date din fișiere
externe si DATALINES (sau CARDS)
Pentru a aplica proceduri specifice SAS, datele trebuie să fie
disponibile în seturi de date SAS.
Dacă datele nu se regăsesc în formatul specific SAS, atunci
există următoarele alternative de lucru:
 Crearea de seturi de date prin introducerea datelor în
codul sursă prin care se crează setul de date (cu
DATALINES).
 Citirea datelor disponibile în fișiere flat. Acestea nu sunt
fișiere proprietare, iar înregistrările conțin valori care sunt
organizate în câmpuri.
 Accesarea datelor create prin intermediul altor aplicații,
spre exemplu MS Excel, Oracle, SPSS.

17
Date incluse în codul sursă
 Datele pot fi incluse în secțiunea de date prin DATALINES (sau
CARDS – un alias al acestei declarații, provenit dintr-o versiune mai
veche a limbajului).
 Setul de date de mai jos se salvează în biblioteca WORK, aceasta
fiind temporara.

data comanda;
input varsta gen $ id_prod cantitate data mmddyy8.;
format data yymmdds10.;
datalines;
25 f 02344 2 05/27/10
37 m 08798 4 04/29/10
45 f 09876 1 05/27/10
19 m 07897 3 05/30/10
;
proc sort data=comanda; by descending data;
proc print data=comanda;
title 'Comenzi onorate';
18
PROC CONTENTS si PROC PRINT

Un set de date SAS este format din două zone:


 Zona de descriere = conține informații care caracterizează setul
de date per ansamblu, cum ar fi numele setului de date, data
creării, descrierea fiecărei variabile (nume, tip, lungime) etc.
Aceste informații poartă denumirea de metadate. Și pot fi
vizualizate cu procedura CONTENTS.
PROC CONTENTS DATA = set_date;

 Zona de date = conține datele propriu-zise ale setului de date,


care pot fi vizualizate cu o multitudine de proceduri, printre care
cea mai utillizată este PRINT.
PROC PRINT DATA = set_date;

19
Convenții de denumire specifice SAS

Denumirile specificate de către utilizatori în SAS pentru o multitudine


de elemente ale limbajului, precum seturi de date, variabile,
proceduri, referințe la biblioteci, formate etc., trebuie să respecte o
serie de convenții, cum ar fi:

 încep cu o literă sau cu caracterul ” _” underscore;


 pot conţine litere, cifre sau caracterul underscore;
 au o lungime de maximă predefinită (spre exemplu, 32 de
caractere pentru numele de variabile și seturi de date, 8
caractere pentru referințe la biblioteci);
 nu sunt case sensitive;
 nu pot conține spații.

20
Tipuri de date
SAS a simplificat lucrul cu tipuri de date, existând date de tip
numeric și de tip caracter. Implicit, variabilele unui set de date pot
fi de tip numeric sau caracter.
 Variabilele numerice pot memora și valori în format științific și
sunt implicit stocate pe 8 octeți. Variabilele de tip caracter pot
memora până la 32.767 de caractere, fiecare caracter fiind stocat
pe un octet.
 Valorile de tip dată și timp sunt stocate în SAS ca și valori
numerice. Valoarea unei date calendaristice SAS este stocată
intern sub forma numărului de zile dintre data de 1 ianuarie 1960
și data specificată, putând fi un număr pozitiv sau negativ.
Valoarea de tip timp în SAS este stocată sub forma numărului de
secunde care s-au scurs de la miezul nopții în ziua curentă, deci
este o valoare între 0 și 86400.

21
Biblioteci SAS -1
 O bibliotecă SAS este o colecţie care include unul sau mai multe
fişiere SAS.
 Sintaxa este:
LIBNAME libref ‘Biblioteca-SAS‘;
 LIBNAME – defineşte o bibliotecă.
 libref – este o referinţă la o bibliotecă, un alias pentru o locaţie fizică
unde se găsesc fişierele incluse în bibliotecă.
 ‘Bilioteca-SAS‘ – este locaţia fizică propriu-zisă
LIBNAME exemple ‘C:\curs‘;
 Libname nu este parte a unei secţiuni de date sau de proceduri şi nu
are nevoie de RUN pentru a rula.
 Referința la o bibliotecă rămâne valabilă până când aceasta se
anulează sau se schimbă sau până când se termină sesiunea SAS.

22
Biblioteci SAS -2
 Libref trebuie să refere un director existent, deoarece prin această
declarație nu se creează un nou director.
 Se pot defini oricâte declaraţii LIBNAME.
 Biblioteca Work este temporară şi se iniţializează la deschiderea
sesiunii de lucru SAS.
 Vizualizarea conținutului unei biblioteci se face cu procedura
CONTENTS.

PROC CONTENTS DATA= libref._ALL_ NODS;


RUN;

 Opțiuni: _ALL_ include toate fișierele din bibliotecă, iar NODS nu


include zona de descriere a unui set de date.

23
Crearea seturilor de date din fișiere flat
Delimitatorul spaţiu
Considerând că avem un fişier numit exemplu1.txt care conţine
numele, preţul şi categoria a șase tipuri de copaci, fiecare având
valoarea separată printr-un spaţiu, acesta ar avea următoarea
formă:
brad 40 conifer
molid 25 conifer
fag 42 foios
stejar 27 foios
liliac 33 arbust
alun 38 arbust
data exemplu1;
infile '/home/nume.prenume/exemplu1.txt';
input Nume $ Pret Categorie $;
run;
24
Delimitatorul virgulă

Pentru fişierul de date:


brad,40,conifer
molid,25,conifer
fag,42,foios
stejar,27,foios
liliac,33,arbust
alun,38,arbust

data exemplu2;
infile '/home/nume.prenume/exemplu2.txt' dsd;
input Nume $ Pret Categorie $;
run;
25
Alţi delimitatori

• Pentru orice alt tip de delimitatori, instrucţiunea infile


trebuie folosită împreună cu opţiunea dlm sau delimiter.
Au aceeaşi semnificaţie, prima fiind o abreviere.

Exemplu:
infile 'c:\date sas\produse.txt' delimiter='/';
sau
infile 'c:\date sas\produse.txt' dlm='/';.

26
Fişiere cu coloane cu lăţime fixă

• Cel de-al doilea tip de fişiere flat pe care SAS poate să


le citească sunt cele care conţin date în coloane cu
lăţime fixă. Pentru acestea există două modalităţi de
citire:
 coloane de intrare (column input)
 intrări formatate (formatted input)
• Avantajul folosirii datelor în coloane cu lăţime fixă
consta in:
- datele pot fi citite în orice ordine
- valorile lipsă pot fi specificate prin tot atâtea spaţii libere
cât are şi lăţimea coloanei.
27
Fişiere cu coloane cu lăţime fixă-exemplu

• Considerăm un fișier în care valorile din fiecare camp incep


de la o anumita poziție:

brad 40 conifer
molid 25 conifer
fag 42 foioase
stejar 27 foioase
liliac 33 arbusti
alun 38 arbusti

• Aşa cum se poate observa, numele are maxim 6 caractere,


preţul 2, iar categoria 7.

28
Fişiere cu coloane cu lăţime fixă

• Metoda 1: Coloane de intrare foloseşte instructiunea INPUT


specificând pentru fiecare variabilă numele său, semnul $ pentru
variabilele caracter, precum şi poziţia de început şi de sfârşit a
fiecărei variabile în linia de date.

*citire fisier text cu latime fixa: metoda coloane de


intrare;
data exemplu3;
infile "/home/nume.prenume/exemplu3.txt";
input Nume $ 1-6
Pret 8-9
Categorie $ 10-17;
run;

29
Fişiere cu coloane cu lăţime fixă

• Metoda 2: Intrări formatate poate citi diferite tipuri de


formate, cum ar fi monedă (numere având semnul dolar sau
euro), numere cu zecimale, date în diferite formate.
• Instructiunea INPUT are umătoarele opţiuni:
- semnul @ urmat de poziţia de început a variabilei;
- numele variabilei, formatul variabilei, dacă este necesar;
- precum şi lăţimea coloanei asociată variabilei.

INPUT @pozitie nume_variabilă [format] lăţime.

30
Exemplu metoda 2
*citire fisier text cu latime fixa, metoda intrari
formatate;
data exemplu4;
infile '/home/nume.prenume/exemplu4.txt';
input @1 Nume $6.
@8 Pret dollar3.
@12 Categorie $7.;
format Pret dollar6.0;
/*
datalines;
brad $40 conifer
molid $25 conifer
fag $42 foioase
stejar $27 foioase
liliac $33 arbusti
alun $38 arbusti */
run;

31
Atribuirea etichetelor
 Instructiunea LABEL atribuie etichete variabilelor din setul de
date de ieșire.
 Multe proceduri SAS utilizeaza etichetarea variabilelor pentru a
îmbunătăți întelegerea semnificației datelor.
 Etichetele se pot crea și în secțiunile de date, și în cele de
proceduri.
LABEL variabila = “Eticheta…”;
 Într-o singură instructiune LABEL se pot defini etichete pentru
mai multe variabile.
 Pot avea până la 256 de caractere scrise între ghilimele simple
sau duble.
 Redefinirile ulterioare suprascriu definirile inițiale ale valorilor
etichetelor.
32
Atribuirea etichetelor - exemplu
***Definire etichete in sectiunea de date;
DATA agenti;
INPUT Cod Oras$ Vanzari;
LABEL Cod = "Cod agent"
Vanzari = "Vanzari trim I";
DATALINES;
1101 BZ 100000
1102 CJ 250000
1103 BU 400000
1104 CJ 270000
1105 BU 150000
1106 BZ 80000
;
RUN;
***Utilizare etichete in sectiunea de proceduri;
PROC PRINT DATA =agenti LABEL;
RUN;
***Definire si utilizare etichete in sectiunea de proceduri;
PROC PRINT DATA =agenti LABEL;
LABEL Oras = "Filiala" Cod = "Cod agent vanzari";
33
RUN;
Formate de afișare
În SAS există formate de citire și formate de afișare.
Formatele de citire oferă instrucțiuni despre modul cum se
citesc datele din fișierele externe.
Formatele de afișare oferă instucțiuni despre modul cum se vor
afișa datele din setul de date.
 Ambele tipuri de formate pot fi predefinite în SAS sau definite de
utilizator.
 Formatele vor fi disponibile pe parcursul unei sesiuni SAS, cu
excepția cazului în care se avem formate persistente.
 După definire, formatele se pot aplica variabilelor în diferite
proceduri SAS.

34
Sintaxa formate SAS de afișare

 Definirea de formate
PROC FORMAT;
VALUE <$>nume_format
listă_valori_iniţiale1 = val_afis1
listă_valori_iniţiale2 = val_afis2
other = val_afis3;
– Se pot defini mai multe formate de afişare în aceeaşi
procedură.

 Utilizarea formatului în alte proceduri


FORMAT variabila <$> nume_format. ;

35
Utilizare formate de afișare
***Definire formate definite de utilizator;
PROC FORMAT;
VALUE $oras 'BU'='Bucuresti'
'BZ'='Buzau'
'CJ'= 'Cluj'
other='Gresit';

VALUE nivel low-<100000='Nivel1'


100000-200000='Nivel2'
200000<-high='Nivel3';
RUN;

***Aplicare formate definite de utilizator;


PROC PRINT DATA =agenti LABEL;
FORMAT oras $oras. Vanzari nivel.;
RUN;

36
Instructiunea INPUT - Omiterea locației
unei coloane
Pentru a putea omite locația unei coloane dintr-un fișier flat, la
citirea datelor în vederea creării unui set de date SAS, datele
trebuie să satisfacă următoarele condiții:
• Fiecare valoare este separată de următoarea prin cel puțin un
spațiu libar sau un delimitator (dacă folosim opțiunea DLM).
• Orice valoare lipsă este reprezentată prin spații (pentru
ambele tipuri de variabile).
• Valorile tuturor variabilelor de tip caracter au maxim 8
caractere și nu includ spații, în caz contrar se produc
trunchieri ale datelor.
Observație! În seturile de date SAS valorile lipsă sunt
reprezentate prin punct pentru variabilele numerice și spațiu
pentru cele de tip caracter. 37
Instructiunea INPUT - Plasarea mai multor
observații scurte pe aceeași linie
Pentru fișierele cu puține variabile și observații scurte, este o
practică des întâlnită plasarea mai multor observații pe
aceeași linie. Pentru a folosi această abordare, trebuie avute în
vedere următoarele aspecte:
• Datele de intrare trebuie să îndeplinească cele trei condiții
amintite în slide-ul anterior.
• Se poate folosi instructiunea INPUT fără a preciza locația
coloanei plasând la sfarșitul declarației simbolurile “@@”
înainte de “;”.

38
Plasarea mai multor observații scurte pe
aceeași linie - exemplu
*Plasarea mai multor observatii pe aceeasi linie;
DATA studenti;
INPUT cod nota @@;
DATALINES;
1101 7 1102 9 1103 10 1104 7 1105 5 1106 8 1107 6 1108 10
1109 9 1110 7 1111 8 1112 5 1113 9 1114 10 1115 8 1116 7
;
RUN;

39
De lucru!
 Dorim să importăm datele din fișierul exemplu5.txt:
brad 40 conifere
molid 25 conifere
fag 42 foiaose
stejar 27 foiaose
liliac 33 arbusti
alun 38 arbusti
cires 39 fructifere
mar 25 fructifere
 Rulăm codul:
LIBNAME date "/home/nume.prenume";
data date.exemplu5;
infile '/home/nume.prenume/exemplu5.txt';
input Nume $ Pret Categorie $;
run; 40
De lucru!
Ce observați în rezultate?
Care credeți că este cauza?
O soluție o reprezintă stabilirea lățimii unei variabile prin
instructiunea LENGTH, având următoarea sintaxă:
LENGTH variabil_1 ... variabila_n <$> latime
Rulăm din nou codul:
data date.exemplu5;
infile '/home/nume.prenume/exemplu5.txt';
length Categorie $ 10;
input Nume $ Pret Categorie $;
run;

41
Să recapitulăm!
1. Ce tipuri de fișiere pot reprezenta intrări pentru
crearea unui set de date SAS?
2. Care sunt sectiunile care formează un set de date SAS
și cu ce proceduri pot fi vizualizate?
3. Cum se memorează valorile de tip dată?
4. Pentru ce folosim formatele de afișare?
5. Prin ce metodă se citesc din fișierele flat datele care
au formate speciale, cum ar fi monedă?
6. Ce este este o referinţă la o bibliotecă SAS și de ce se
folosesc bibliotecile?
7. Ce rol are instructiunea DATALINES?
42
Programarea în
limbajul SAS

SAS 2
CUPRINS

 Subseturi de date
 Procesarea condițională și iterativă a datelor
 Transformarea datelor prin funcții SAS
Crearea seturilor de date SAS din seturi de
date existente -1

Sintaxa:

DATA set-de-date-SAS-de-iesire;
SET set-de-date-SAS-de-intrare;
WHERE expresie-conditionala;
DROP listă-variabile;
KEEP listă-variabile;
LABEL var1=‘eticheta1’ var2=‘eticheta2’;
FORMAT variabila(le) format.;
RUN;

3
Crearea seturilor de date SAS din
seturi de date existente -2
 Implicit toate întregistrările dintr-un set de date de intrare
sunt preluate în setul de date rezultat.
 Instructiunea WHERE are rolul de a selecta observaţiile
dintr-un set de date.
 O secţiune de date poate include o singură instructiune
WHERE.

Exemple:
where gen EQ ‘M’;
where salariu NE .;
where pozitie CONTAIN ‘Vanzari’;
where nume LIKE ‘T_M%’;
where cod IS MISSING;
4
Crearea seturilor de date SAS din
seturi de date existente -3
 Selectarea variabilelor din setul rezultat se realizează cu
ajutorul instructiunilor DROP şi KEEP:
 DROP listă-variabile; {cu spaţiu între ele} indica
variabilele care se exclud din setul rezultat.
 KEEP listă-variabile; {cu spaţiu între ele} indica
variabilele care se păstrează în setul rezultat.
 LABEL schimbă modul în care apare numele variabilei în
diverse proceduri. Spre exemplu, PROC PRINT poate afişa
numele etichetei în loc de numele variabilei:
PROC PRINT DATA = set-de-date-SAS LABEL;
 FORMAT este un format de afişare care schimbă modul de
afişare a variabilelor: <$>format <w>.<d>

5
Procesare condiţională în programele SAS

• Forma generală a acestei instructiuni este:


IF conditie THEN expresie1;
ELSE expresie2;
• ELSE IF:
IF conditie1 THEN expresie1;
ELSE IF conditie2 THEN expresie2;
ELSE IF conditie3 THEN expresie3;
......

6
Operatorii logici și de comparaţie din SAS
Operator Operator SAS Operație
& AND ȘI
| OR SAU
^ NOT Negație
= EQ Equal to
^= NE Not equal to
> GT Greater than
< LT Less then
>= GE Greater than or equal to
<= LE Less than or equal to
IN IN Equal to one in a list
Exemplu
Considerăm următorul setul de date:

DATA produse;
LENGTH Categorie $9;
INFILE'/home/nume.prenume/produse.txt';
INPUT Cod Pret_achizitie Pret_vanzare Categorie $;
RUN;
PROC PRINT DATA=produse;
VAR Cod Pret_achizitie Pret_vanzare Categorie;

8
Exemplu - creare de noi variabile
Pornind de la setul de date din exemplu, se definesc două noi variabile:
 Variabila Profit_unitar prin calcul

 Variabila Grup prin procesare condițională

LIBNAME exemple '/home/nume.prenume/';


DATA exemple.produse;
SET produse;

Profit_unitar=Pret_vanzare-Pret_achizitie;

if missing(Pret_vanzare) or Pret_vanzare lt 10
then Grup=1;
else if Pret_vanzare le 20 then Grup=2;
else Grup=3;

DROP Pret_achizitie;
RUN; 9
Subseturi de date
• Intr-o sectiune de date, observatiile pot fi regrupate intr-un subset de date
SAS folosind instructiunile WHERE, DELETE sau IF.
• DELETE oprește procesarea observației curente.
• Se poate utiliza următoare sintaxă:
IF conditie THEN DELETE;
• Exemplu de crearea a unui subset de date pentru categoria de produse
“perisabile”:
data perisabile;
set exemple.produse;
where Categorie IN ("legume", "fructe", "brutarie");
• Daca am dori un subset de date pentru grupul 1, conditia ar fi: where Grup
EQ 1;
• În secţiunile de proceduri se foloseşte numai WHERE, nu şi IF;
• WHERE în secțiunea de date trebuie să refere numai variabile din setul de
date de intrare;
• WHERE nu se poate folosi în expresii condiţionale bazate pe variabile
create în secţiunea de date prin declaraţii de atribuire. 10
Subseturi de date - exemplu
DELETE este utilizata pentru a elimina anumite observatii în subsetul de
date.
Se dorește crearea unui subset de date care să conțină toate produsele
neperisabile:
Varianta 1: IF cu DELETE
data neperisabile;
set exemple.produse;
if Categorie NOT IN ("cosmetice", "curatenie") then
delete;
run;
Varianta 2: WHERE
data neperisabile;
set exemple.produse;
WHERE Categorie IN ("cosmetice", "curatenie");
run;
Varianta 3: IF fără THEN
data neperisabile;
set exemple.produse;
if Categorie IN ("cosmetice", "curatenie");
11
run;
Acumularea de totaluri-1
Pornim de la datele referitoare la un test medical de efort efectuat de
pacienți pe o bandă de alergare.

data efort;
input Cod $ 1-4 Nume $ 6-19 RCRep 23-24 RCMax 29-31
RCRec 35-37 TimpMin 43-44 TimpSec 51-52
Toleranta $ 58;
datalines;
2458 Murray, W 72 185 128 12 38 D
2462 Almers, C 68 171 133 10 5 I
……
run;

12
Acumularea de totaluri-2
 Pentru a adăuga rezultatul unei expresii la o variabilă acumulator se
poate utiliza urmatoarea sintaxa:
variabila + expresie;
 variabilă = numele variabilei acumulator, care trebuie să fie
numerică. Variabila este inițializată automat cu 0 înainte de
citirea primei observații. Valoarea variabilei este păstrată între
două execuții ale secțiunii de date.
 expresie = orice expresie SAS validă.
 + adaugă rezultatul expresiei la variabila numerică din stânga
semnului plus.

13
Acumularea de totaluri-3
 Dorim să aflăm care este timpul total, măsurat în secunde, în care s-
a folosit banda de alergare.

data efort1;
set efort;
TimpTotal = (TimpMin*60)+TimpSec;
SumSec + TimpTotal;

run;
Atenție!!! Dacă expresia de evaluat produce o valoare lipsă, declarația
de adunare o ignoră. Prin comparație, declarația de atribuire atribuie
o valoare lipsă dacă expresia produce o valoare lipsă.

Operație Expresie Rezultat


variabila+expresie; NULL Valoarea variabilei
variabila=variabila+expresie; NULL NULL
SUM(variabila, expresie); NULL Valoarea variabilei

14
KEEP și DROP – opțiuni vs. declarații
 Atât KEEP, cât și DROP pot apărea sub forma unor opțiuni ale
setului de date sau ca instructiuni în secțiunea de date.
DATA set_date (DROP = variabil(e) | KEEP = variabil(e));
……
DROP variabil(e);
KEEP variabil(e);
RUN;
 În principiu, ambele variante au același scop (păstrarea sau
eliminarea variabilelor), diferențele dintre cele două fiind:
 Nu se pot folosi KEEP și DROP în secțiunile de proceduri;
 KEEP și DROP se aplică tuturor seturilor de date care sunt
denumite în declarația DATA. Pentru a exclude variabile dintr-un
set, dar nu și din altele, se folosesc opțiunile DROP= și KEEP=.

15
De lucru - Analizați exemplele!
 Exemplu utilizare opțiunea DROP cu două seturi de date
LIBNAME exemple '/home/nume.prenume/';
DATA perisabile (DROP = Pret_achizitie) neperisabile;
SET produse;
Profit_unitar=Pret_vanzare-Pret_achizitie;
if Categorie NOT IN ("cosmetice", "curatenie") then
output perisabile;
else output neperisabile;
RUN;
 Exemplu utilizare opțiunea DROP cu un set de date
data efort2 (drop = TimpMin TimpSec);
set efort;
if Toleranta ="D";
TimpTotal = (TimpMin*60)+TimpSec;
SumSec + TimpTotal;
length DurataTest $ 6.;
if TimpTotal >800 then DurataTest = "Lung";
else if 750<=TimpTotal<=800 then DurataTest =
"Normal";
else if TimpTotal<750 then DurataTest = "Scurt";
run; 16
Stabilirea lățimii unei variabile noi
 În timpul compilării, atunci când se creează o nouă variabilă de tip
caracter în urma unei declarații de atribuire, SAS alocă atâția octeți
ca spațiu de stocare câte caractere are prima valoare pe care o
întâlnește pentru acea variabilă.

Întrebare
Câți octeți credeți că rezervă programul anterior pentru variabila
DurataTest în absența declarației LENGTH?

Rulăm programul anterior comentând declarația LENGTH.

 În cadrul programului, s-a inclus declarația LENGTH pentru a


asigna variabilei o lățime suficientă pentru a stoca cea mai lungă
valoare pentru variabila DurataTest, și anume șase caractere.

17
Procesarea condițională cu SELECT
 O altă modalitate de a realiza procesare condițională în SAS o
reprezintă folosirea instructiunii SELECT, cu sintaxa:
SELECT <(expresie-select)>;
WHEN (conditie1 <…, conditie>) expresie1;
WHEN (conditie2 <…, conditie>) expresie2;
<OTHERWISE expresie3;>
END;

• expresie-select este opțională și reprezintă orice expresie a cărei


evaluare produce o singură valoare.
• WHEN include o expresie care se execută atunci când o anumită
condiție este adevărată.
• conditie specifică orice conditie SAS, inclusiv un set de conditii.
• Opțiunea OTHERWISE arată ce expresie se execută dacă nu este
îndeplinită niciuna dintre condițiile specificate in WHEN.
• END semnifică sfârșitul grupului de selecție.
18
Instructiunea SELECT – exemple 1
 SELECT fără crearea unui set de date:
DATA _NULL_; *nu se defineste un set de date;
a=7; x=2;
SELECT (a);
WHEN (2,4,6,8) x=x*10;
WHEN (1,3,5,7) x=x*100;
OTHERWISE;
END;
put x= ; RUN;
 SELECT cu expresie de selectare:
DATA salariati;
SET exemple.salarii; length grup $ 20;
SELECT(Pozitie);
WHEN ("FA1") grup ="Flight Attendant I";
WHEN ("FA2") grup ="Flight Attendant II";
WHEN ("FA3") grup ="Flight Attendant III";
WHEN ("ME1", "ME2", "ME3") grup ="Mechanic";
WHEN ("NA1", "NA2", "NA3") grup ="Navigator";
WHEN ("PT1") grup ="Pilot I";
WHEN ("PT2") grup ="Pilot II";
WHEN ("PT3") grup ="Pilot III";
WHEN ("TA1", "TA2", "TA3") grup ="Ticket Agents";
OTHERWISE grup="Other"; END;
RUN; 19
Instructiunea SELECT – exemple 2
 Declarație OTHERWISE care trimite un mesaj către SAS log:
DATA _null_;
jucarie="Elefant";
SELECT (jucarie);
WHEN ("Urs") pret=37.00;
WHEN ("Vioara") pret=125.00;
WHEN ("Pisica", "Rata", "Crocodil") pret=22.00;
OTHERWISE put "Jucarie necunoscuta: " jucarie= ;
END;
RUN;
 SELECT fără expresie de selectare: numai primul WHEN care are
conditia adevărată va fi folosit, celelalte nu sunt evaluate.
DATA produse_procent_profit;
SET produse;luna=MONTH(TODAY());
SELECT;
WHEN (Categorie="fructe" and luna in (10,11,12))
Procent_profit=0.4;
WHEN (Categorie="fructe" and luna in (1,2,3))
Procent_profit=0.6;
WHEN (Categorie="fructe") Procent_profit=0.3;
OTHERWISE;
END;
IF Categorie="fructe" THEN
Pret_vanzare=Pret_achizitie*Procent_profit; 20
RUN;
Structuri repetitive - DO
DO;
instructiuni SAS
END;

Este permisă imbricarea instrucțiunilor DO:

DO;
instructiuni;
DO;
instructiuni;
DO;
instructiuni;
END;
END;
END;

21
DO - exemplu
DATA produse_reduceri;
SET produse;
SELECT(Categorie);
WHEN ("legume", "fructe", "brutarie")
DO;
Reducere=0.25;
IF Pret_vanzare le 10 THEN reducere=0.2;
END;
WHEN ("cosmetice") Reducere=0.3;
OTHERWISE;
END;
IF not missing (Reducere) THEN Pret_nou=Pret_vanzare
*(1-Reducere);
ELSE Pret_nou=Pret_vanzare;
RUN;

Valorile care apar în conditii/expresii WHEN sunt case


sensitive.

22
Procesarea iterativă în SAS-1
1. Bucla cu număr cunoscut de iterații
DO contor= inceput TO sfarsit BY incrementare;
instructiuni SAS;
END;
Valorile inceput, sfarsit și incrementare:
• sunt setate la începutul intrării în buclă;
• nu pot fi schimbate pe parcursul procesării buclei;
• pot fi numere, variabile sau expresii SAS.
 Dacă valoarea de incrementare este omisă, atunci aceasta implicit
este 1.
 Atunci când valoarea de incrementare este un număr negativ,
contorul va realiza o actualizare descrescătoare.
 Valoarea variabilei contor poate fi schimbată în interiorul buclei.

23
Procesarea iterativă în SAS-2
2. Bucla condițională, cu număr necunoscut de iterații
DO UNTIL (expresie); DO WHILE (expresie);
instructiuni SAS; instructiuni SAS;
END; END;
DO UNTIL execută bucla până când expresie devine adevărată.
Expresia nu se evaluează până la finalul buclei, ceea ce însemnă că
aceasta întotdeuna se execută cel puțin o dată.
DO WHILE evaluează expresie înainte de intrarea în buclă, cu
posibilitatea ca aceasta să nu se execute niciodată.
Exemplu de combinare a celor două variante de procesare iterativă:

DATA investitie;
DO an=1 to 10 UNTIL (Capital>=50000);
Capital +4000;
Capital+Capital*.10;
END;
RUN;
24
Funcții SAS
 Funcțiile SAS sunt rutine predefinite care permit efectuarea unei
multitudini de operații de prelucrare a datelor rapid și cu ușurință.
 Există multe categorii de funcții SAS, cum ar fi: aritmetice,
financiare, de tip caracter, pentru calculul probabilităților, de tip dată
și timp etc.
 Argumentele unei funcții pot fi variabile, constante sau expresii.
 Există funcții care pot folosi ca argumente și liste de variabile sau
masive (pe lângă numele argumentelor separate prin virgulă), caz în
care argumentele sunt precedate de cuvântul OF:
 mean (x1,x2,x3) este echivalentă cu mean(of x1-x3)

Care va fi rezultatul afișat de codul de mai jos

DATA _NULL_;
x1=1; x2=4; x3=10;
medie= mean(of x1-x3);
put medie= ;
RUN; 25
PUT și INPUT -1
 Există situații în care datele de care dispunem nu sunt în formatul
necesar efectuării transformărilor sau calculelor de care avem
nevoie. Spre exemplu, avem de efectuat o operație matematică între
o variabilă de tip caracter și una de tip numeric.
 Chiar dacă SAS va detecta nepotrivirea dintre tipurile variabilelor și
va realiza o conversie implicita caracter-numeric sau numeric-
caracter, este întotdeuna o bună practică să se realizeze o conversie
explicită folosind funcțiile INPUT sau PUT.
 Funcția INPUT convertește valorile de tip caracter la valori numerice:
INPUT (sursa, informat);
unde
 sursa reprezintă orice variabilă de tip caracter, constantă sau
expresie care va fi convertită la o valoare numerică.
 informat este un format de citire potrivit pentru formatul datelor
respective.
26
PUT și INPUT -2
 Funcția PUT convertește valorile de tip numeric la valori de tip
caracter:
PUT (sursa, format);
unde
 sursa reprezintă orice variabilă de tip numeric, constantă sau
expresie care va fi convertită la o valoare de tip caracter.
 format este un format de afișare potrivit pentru datele care se citesc,
deci în acest caz un format numeric.
 Funcția returnează întotdeauna un șir de caractere.
 Exemplu utilizare funcția INPUT:
DATA _NULL_;
c_data= "2/24/2019";
c_num= "1234";
Data_SAS= INPUT(c_data,mmddyy10.);
Numar = INPUT(c_num,10.);
PUT Data_SAS= Numar=;
RUN;
27
Exemple funcția PUT
DATA _NULL_;
Data_SAS= 1;
Numar = 1234;
SS_numar= 123456789;*/Social Security number;
Data_car= PUT(Data_SAS,mmddyy10.);
Moneda = PUT(Numar,dollar8.2);
SS_car= PUT(SS_numar,ssn.);
PUT Data_car= Moneda= SS_car=;
RUN;
-------------------------------------------------------
PROC FORMAT;
VALUE grup 0-10='0 la 10'
11-20='11 la 20'
21-40='21 la 40'
41-high='41+';
RUN;
DATA Exemplu_PUT;
INPUT Varsta @@;
GrupVarsta= PUT(Varsta,grup.);
DATALINES;
9 15 25 60
28
; RUN;
LENGTH, LENGTHN, LENGTHC
 Funcțiile LENGTH și LENGTHN returnează lungimea unui șir de
caractere, fără a lua în considerare eventualele spații de la sfârșitul
șirului:
LENGHTN (valoare_caracter);
 Dacă valoare_caracter este o valoare lipsă, atunci funcția LENGTHN
returnează 0, iar versiunea acesteia mai veche, LENGTH, va returna
1 în acest caz.
 Funcția LENGTC returnează numărul de octeți pe care este stocat
intern un șir de caractere.
DATA _NULL_;
String = ' ';
Latime1=LENGTH(String);
Latime2=LENGTHN(String);
put "Latime cu LENGHT: " Latime1 = ;
put "Latime cu LENGHTN: " Latime2 = ;
Cuvant1 = "abc ";
Latime=LENGTHN(Cuvant1);
Put Cuvant1= Latime = ;
Cuvant2 = "a b c";
Latime=LENGTHN(Cuvant2); 29
Put Cuvant2= Latime = ;RUN;
LENGTHN, LENGTHC - exemple
DATA caractere1;
LENGTH String $ 7;
String = 'curs';
Stocare= LENGTHC(String);
Lungime = LENGTHN(String);
Afisare = ":" || String || ":";
PUT Stocare= /
Lungime = /
Afisare=;
RUN;
-------------------------------------------------------
DATA caractere2;
String = 'curs';
LENGTH String $ 7;
Stocare= LENGTHC(String);
Lungime = LENGTHN(String);
Afisare = ":" || String || ":";
PUT Stocare= /
Lungime = /
Afisare=;
RUN;
30
MISSING și CALL MISSING
 Funcția MISSING preia o valoare numerică sau de tip caracter și
returnează “adevărat” dacă valoarea este lipsă și “fals” în caz contrar.
 CALL MISSING reprezintă o rutină care setează toate argumentele
sale (numerice sau de tip caracter) cu valoarea nulă.
 Verificare valoare lipsă:
*Fără MISSING;
IF Numar = . then . . .
IF Sir = '' then . . .
*Cu MISSING;
IF missing(Numar) then . . .
IF missing(Sir) then . . .
-------------------------------------------------------
DATA _NULL_;
array a[10] a1-a10;
array car[3] x y z;
do i= 1 to 10;
a[i] = .;
end;
do i= 1 to 3; call missing(of a1-a10,x,y,z);
car[i] = ' ';
end;
drop i; 31
RUN;
COMPRESS
 Funcția COMPRESS returnează un șir de caractere prin
îndepărtarea anumitor caractere specificate din șirul pe care îl
primește ca argument.
COMPRESS (sir <,lista> <,modificatori>);
 Atunci când primește un singur argument, funcția va îndepărta
spațiile libere din sir.
 lista specifică o listă de caractere care trebuie îndepărtate din sir (cu
excepția cazului în care se folosește modificatorul “k”).
 Modificatorii permit îndepărtarea unei clase de caractere, cum ar fi
numerele sau literele. Exemple de modificatori:
 a – litere mari sau mici
 d – cifre
 i – ignora dacă acele caractere care se păstrează sau elimină
sunt mari sau mici
 k – păstrează caracterele listate, în loc de a le îndepărta
 s – spații
 p – semne de punctuație
32
COMPRESS - exemple
Considerăm variabilele sir = “XY 01234ABC”
mobil = “(004)0788-51-43-23”
Funcție Valoarea returnată
COMPRESS (“X Y ABCD” ) XYABCD
COMPRESS(mobil," (-)") 0040788514323
COMPRESS(sir,"0123456789") XY ABC
COMPRESS(sir,"1234", "k") 1234
COMPRESS(mobil,,"kd") 0040788514323
DATA Unitati;
INPUT @1 Inaltime $10.;
Inaltime_cm=INPUT(COMPRESS(Inaltime,,'kd'),8.);
IF FIND(Inaltime,'in','i') THEN
Inaltime_cm= 2.54*Inaltime_cm;
FORMAT Inaltime_cm 8.0;
DATALINES;
185cm
64inch
160cm
76inch
; RUN; 33
SUBSTR
 Funcția SUBSTR returnează un subșir de caractere din sir, pornind
de la poziția specificată în start și cu o lungime menționată în ultimul
argument al funcției. Atunci când lungimea nu este specificată,
subșirul se termină la ultimul caracter nenul din sir.
SUBSTR (sir , start, lungime);
 În situația în care nu se stabilește anterior, lungimea variabilei
rezultate va fi aceeași cu lungimea șirului.
data parti_cod;
input Cod $9.;
length Judet $ 2;
Judet = substr(Cod,3,2);
Numar= input(substr(Cod,5),4.);
datalines;
YXVL765
YXIF8765
;
-------------------------------------------------------
data ascundere_cont;
input ID Cont $9. @@;
Cont2 = Cont; substr(Cont2,1,5) = '*****';
datalines;
101 987037051 102 085701417 103 680865368 34
;
UPCASE LOWCASE și PROPCASE
DATA litere;
INPUT Nume $15.;
Mari = UPCASE(Nume);
Mici = LOWCASE(Nume);
Potrivit = PROPCASE(Nume," '");
DATALINES;
poPEscU IOANA
D'Angelo
;
TRIM și STRIP
 Funcția TRIM returnează un șir de caractere din care s-au îndepărtat
spațiile de la sfârșitul șirului.
 Funcția STRIP returnează un șir de caractere din care s-au
îndepărtat spațiile de la începutul și sfârșitul șirului.
 Pentru ambele funcții, dacă argumentul conține valoarea lipsă,
atunci lungimea rezultatului este egală cu 0.
 Se folosesc frecvent împreună cu operatorul de concatenare.

35
CATS, TRIM și STRIP - exemplu
 Funcția CATS preia mai multe argumente de tip șir de caractere,
îndepărtează spațiile de la începutul și sfârșitul șirurilor și
concatenează rezultatele.

DATA _NULL_;
length Concatenare$ 8;
Unu = ' ABC ';
Doi = 'XYZ';
Unu_doi= ':' || Unu || Doi || ':';
Trim = ':' || trimn(Unu) || Doi || ':';
Strip = ':' || strip(Unu) || strip(Doi) ||
':';
Concatenare= cats(':',Unu,Doi,':');
put Unu_Doi= / Trim= / Strip= /
Concatenare=;
RUN;

36
N, NMISS, SUM și MEAN
 N(lista_valori) returnează numărul de valori nenule din listă.
 NMISS(lista_valori) returnează numărul de valori nule din listă.
 SUM(lista_valori) returnează suma valorilor, ignorând valorile lipsă.
 MEAN(lista_valori) returnează media valorilor, ignorând valorile
lipsă.

DATA descriptive;
INPUT a1-a10;
Suma = sum(of a1-a10);
if n(of a1-a10) ge 3 then
Media1 = mean(of a1-a5);
if nmiss(of a1-a10) le 5 then
Media2 = mean(of a1-a10);
DATALINES;
1 2 . . 3 4 5 . 6 7
. . . 8 . . 9 . . 10
;

37
Funcții de tip dată
 MDY(Luna, Zi, An) – returnează o dată SAS.
 Weekday(Data) – returneaza ziua din saptămână (1-duminică, 2-luni
etc.)
 Day(Data) – returnează ziua din lună (1-31)
 Year(Data) – returnează anul
 Yrdif(Data1,Data2) – returnează numărul de ani dintre Data1 și
Data2

DATA Functii_Data;
INPUT (Data1 Data2)(:mmddyy10.) M D Y;
Data_SAS= MDY(M,D,Y);
ZiSaptamana= weekday(Data1);
ZiLuna= day(Data1);
An = year(Data1);
Varsta = yrdif(Data1,Data2);
FORMAT Data: mmddyy10.;
datalines;
02/24/1992 02/24/2019 7 28 2018
;
38
Sintaxă recapitulativă
LIBNAME libref ‘Biblioteca-SAS‘;
DATA set_date (DROP = variabil(e) | KEEP = variabil(e));
SET Set_date;/ INFILE ...; INPUT ...;
DROP variabil(e);
KEEP variabil(e);
LENGTH variabil_1 ... variabila_n <$> latime;
IF expresie THEN declarație;
ELSE declarație;
IF expresie THEN DELETE;
LABEL variabila1 = “Eticheta1”….. ;
FORMAT variabila <$> nume_format. ;
SELECT <(expresie-select)>;
WHEN (conditie1 <…, conditie-n>) expresie1;
WHEN (conditie2 <…, conditie-n>) expresie2;
<OTHERWISE expresie3;>
END;
RUN; 39
Să recapitulăm!
1. Câte declarații WHERE poate include o secțiune de
date SAS?
2. Procesarea condițională cu IF se poate folosi în
secțiunile de proceduri?
3. Ce efect are variabila+expresie; ?
4. În PUT(Numar,dollar8.2); ce tip de format se aplică
parametrului numar și de ce?
5. Explicați SELECT fără expresie de selectare!
6. De ce este recomandată folosirea LENGTH în cazul
variabilelor definite prin atribuire?

40
Programarea în
limbajul SAS

SAS3
CUPRINS

Combinarea seturilor de date


 Proceduri SAS
 Proceduri SQL
 Comparație între cele două abordări
Combinarea seturilor de date
Abordarea SAS
 În programarea SAS, una dintre prelucrările comune constă în
combinarea observațiilor din două sau mai multe seturi de date într-
un set de date nou.
 SAS oferă următoarele metode de combinare a seturilor de date:

Metodă Modalitate de realizare


Fuziune unu-la-unu instrucțiunea SET
Concatenare instrucțiunea SET
Adăugare procedura APPEND
Interclasare instrucțiunea SET
Fuziune pe baza unei corespondențe procedura MERGE

3
Fuziune unu-la-unu -1
 În secțiunea de date se pot folosi mai multe instrucțiuni SET pentru a
combina seturi de date. Această metodă poartă denumirea de
fuziune unu-la-unu.
 În fuziunea unu-la-unu se pot citi seturi de date diferite sau se poate
citi același set de date de mai multe ori, ca și cum ar fi citit din fișiere
separate.
 Sintaxa generală este:
DATA set-date-iesire;
SET set-date-1;
SET set-date-2;
RUN;
 Metoda genereaza în setul de ieșire observații care conțin toate
variabilele din seturile de date sursă.
 Observațiile se combină pornind de la poziția lor relativă în fiecare
set de date.

4
Fuziune unu-la-unu -2

Set de date A Set de date B


NR VarA NR VarB

1 A1 2 B1

3 A2 4 B2

5 A3

Fuziune

Setul de date combinat


NR VarA VarB

2 A1 B1

4 A2 B2

5
Fuziune unu-la-unu -3

 Setul de date nou creat va conține toate variabilele din toate seturile
de date de intrare. Dacă acestea conțin variabile care au același
nume, valorile care sunt citite din ultimul set de date vor rescrie
valorile care au fost citite din seturile de date anterioare.

 Numărul de observații din noul set de date este egal cu numărul de


observații din cel mai mic set de date.

6
Pașii parcurși în fuziunea unu-la-unu- 1
1. Prima instrucțiune SET citește prima observație din setul de date A.

2. A doua instrucțiune SET citește prima observație din setul de date


B. Valoarea pentru variabila NR din setul de date A se va suprascrie
cu cea din setul de date B.

Setul de date nou


NR VarA VarB

2 A1 B1

7
Pașii parcurși în fuziunea unu-la-unu- 2
3. Prima instrucțiune SET citește a doua observație din setul de date
A.
4. A doua instrucțiune SET citește a doua observație din setul de date
B. Se procedează similar ca la punctul 2.
5. Prima instrucțiune SET citește a treia observație din setul de date
A.
Setul de date nou
NR VarA VarB

2 A1 B1

4 A2 B2

6. A doua instrucțiune SET citește sfârșitul fișierului în setul de date B,


ceea ce oprește procesarea fără a mai scrie ceva în setul de date
nou.

8
Fuziune unu-la-unu - exemplu
 Se consideră umătoarele seturi de date:

DATA unu_la_unu;
SET persoane;
IF varsta<50;
SET masuratori;
RUN;

9
Concatenare -1
 O altă modalitate de a combina seturi de date SAS folosind
instrucțiunea SET o reprezintă concatenarea, prin care se adaugă
obsevații dintr-un set de date în altul.
 Pentru aceasta, într-o singură instrucțiune SET, se va specifica o
listă de seturi de date de intrare.
 Sintaxa generală este:
DATA set-date-iesire;
SET set-date-1 set-date-2;
RUN;
 Atunci când se concatenează seturi de date, vor fi citite toate
observațiile din fiecare set de date listat în instrucțiunea SET.
 Noul set de date va conține toate variabilele și observațiile din toate
seturile de date de intrare.

10
Concatenare -2
Set de date a Set de date c
NR VarA NR VarB

1 A1 1 B1

2 A2 2 B2

3 A3 4 B3

Concatenare

Setul de date combinat


NR VarA VarB

1 A1

2 A2

3 A3

1 B1

2 B2

4 B3
Concatenare: exemplu -1
DATA pret1;
INPUT COD pret;
DATALINES; • Observăm că seturile de date au o
124 23.5
variabilă comună numită COD.
178 35.0
197 44.6 Ambele variabile COD trebuie să fie
;RUN; de acelasi tip, altfel SAS poate
DATA pret2; intrerupe procesarea secțiunii de
INPUT COD $ pret; date și va afișa un mesaj de eroare:
DATALINES;
234 53.7 variabila COD are două tipuri de
356 75.5 date.
367 84.0
;RUN;
DATA concatenare;
SET pret1 pret2;
RUN;

12
Concatenare: exemplu -2
DATA nume1;
INPUT ID$ nume$;
DATALINES;
0123 Mihai
0134 Delia
0162 Ionela
• Dacă lățimea atributelor diferă,
; RUN; SAS preia lățimea primului set
DATA nume2; de date din listă.
LENGTH nume $ 10.;
INPUT ID$ nume$;
DATALINES;
0124 Alexandra
0138 Georgiana
0189 Sebastian
; RUN;
DATA concatenare;
SET nume1 nume2;
RUN;

13
Adăugare -1
 Adăugarea este similară concatenării, în cazul aceasta folosindu-se
procedura APPEND.
 Există câteva diferențe importante între concatenare și adăugare:
 În timp ce secțiunea de date defineste un set de date nou la
concatenare, procedura APPEND doar adaugă observațiile unui
set de date la sfârșitul unui set de date de bază (master data
set).
 SAS nu citește datele din setul de date de bază atunci când
execută procedura APPEND.
 Sintaxa generală este:
PROC APPEND BASE= set-date
DATA= set-date;
RUN;
 Numai două seturi de date pot fi folosite în cadrul procedurii
APPEND.

14
Adăugare -2
 Pentru a folosi procedura APPEND cu seturi de date care au
structuri diferite, se utilizează opțiunea FORCE a procedurii, cu
sintaxa:
PROC APPEND BASE= set-date
DATA= set-date FORCE;
RUN;
 Această opțiune este necesară atunci când setul de date care
trebuie adăugat conține variabile care:
 nu sunt în setul de date de bază.
 au alt tip decât cele din setul de date de bază.
 sunt mai late decât cele din setul de date de bază.

15
Adăugare -exemplu
persoane2
persoane1
Cod Gen Judet
Cod Gen
4 Masculin Il
1 M
5 Feminin DB
2 F
6 Masculin VL
3 M
7 Feminin CJ

PROC APPEND BASE=persoane1


DATA= persoane2
persoane1 FORCE; RUN;
Cod Gen
1 M
2 F
3 M
4 M
5 F
6 M 16
7 F
Interclasare -1
 Dacă se folosește instrucțiunea BY la concatenarea seturilor de
date, rezultatul îl reprezintă interclasarea acestora.
 Sintaxa generală este:
DATA set-date-iesire;
SET set-date-1 set-date-2;
BY variabil(e);
RUN;
 Fiecare set de date de intrare trebuie să fie sortat sau indexat în
ordine crescătoare după variabilele din BY.
 Când SAS interclasează seturi de date, observațiile sunt citite în
mod secvențial, în ordinea în care sunt specificate seturile de date și
variabilele BY, până când toate observațiile au fost procesate.
 Setul de date rezultat include toate variabilele și toate observațiile
din seturile de date de intrare.
17
Interclasare -2
Set de date c Set de date d
NR Var NR Var

1 C1 2 D1

2 C2 3 D2

2 C3 3 D3

3 C4
Interclasare

Setul de date
combinat
NR Var
1 C1
2 C2
2 C3
2 D1
3 C4
3 D2 18
3 D3
Interclasare -3
DATA persoane1;
INPUT cod Gen $;
DATALINES;
1 M
2 F
3 M
;
RUN;
DATA persoane2;
INPUT cod Gen $ Judet $;
DATALINES;
4 Masculin IL
5 Feminin DB
6 Masculin VL
7 Feminin CJ
;
RUN;
data interclasare;
set persoane1 persoane2;
by Cod;
RUN; 19
PROC PRINT DATA = interclasare;
Fuziune pe baza unei corespondențe -1
 Metodele de combinare anterioare au fost bazate pe ordinea
observațiilor din seturile de date de intrare.
 Există și situații când este necesară combinarea observațiilor din
două sau mai multe seturi de date într-o singură observație dintr-un
set de date nou în funcție de valorile unei variabile comune.
 Sintaxa generală este:
DATA set-date-iesire;
MERGE set-date-1 set-date-2;
BY variabil(e);
RUN;
 Fiecare set de date de intrare trebuie sortat sau indexat după
variabila(e) din clauza BY.

20
Fuziune pe baza unei corespondențe -2
Set de date A Set de date C
NR VarA NR VarB

1 A1 1 B1

2 A2 2 B2

3 A3 4 B3

Fuziune

Setul de date combinat


NR VarA VarB

1 A1 B1

2 A2 B2

3 A3

4 B3
DATA persoane1;
INPUT cod Gen $;
DATALINES;
1 M
2 F
3 M
4 F
;
RUN;
DATA persoane2;
INPUT cod Gen $ Judet $;
DATALINES;
2 Masculin IL
3 Feminin DB
6 Masculin VL
7 Feminin CJ
;
RUN;
data jonctiune;
merge persoane1 persoane2;
by /* descending*/ Cod;
RUN;
PROC PRINT DATA = jonctiune;
Fuziune pe baza unei corespondențe -3
 La modul general, SAS verifică în mod secvențial dacă fiecare
observație a fiecărui set de date se potrivește cu valoarea din clauza
BY și apoi scrie observația combinată în noul set de date.
 Fără alte instrucțiuni suplimentare sau opțiuni, setul de date de ieșire
va conține valori din toate observațiile tuturor seturilor de date de
intrare.
 Totuși, în multe situații dorim să selectăm doar observațiile care au
corespondent în două sau mai multe seturi de date.
 Pentru a exclude observațiile care nu au corespondent din setul de
date de ieșire, se poate folosi opțiunea IN= a secțiunii de date
împreună cu instrucțiunea condițională IF pentru a genera un subset
de date.
 Opţiunea IN= asociată unui set de date poate fi folosită pentru a
urmări care din seturile de date de intrare a contribuit la fiecare
observaţie din setul de date nou creat.

23
Fuziune pe baza unei corespondențe -4
 Opţiunea IN= se specifică după numele fiecărui set de date şi este
urmată de un nume de variabilă temporară ales de utilizator, sintaxa
fiind: (IN=variabila). Variabila nu va fi inclusă în setul de date rezultat.
 Variabilele temporare definite prin IN= iau valoarea 1 (adevărat) dacă
setul de date la care se referă contribuie la observaţia curentă din
setul de date nou şi 0 (fals) în caz contrar.
A. Realizăm o fuziune între observațiile care au corespondent.
DATA fuziune_corespondenta;
MERGE persoane (IN=inpers)
masuratori (IN=inmasura);
BY ID;
IF inpers=1 and inmasura=1;
* cod echivalent;
* IF inpers and inmasura;
RUN;

24
Fuziune pe baza unei corespondențe -5
B. Selectăm persoanele care nu au efectuat măsurători.
DATA persoane_fara_masuratori;
MERGE persoane (IN=inpers)
masuratori (IN=inmasura);
BY ID;
IF inpers=1 and inmasura=0;
* cod echivalent;
* IF inpers and NOT inmasura;
RUN;
 La fel ca la definirea seturilor de date SAS din fișiere externe sau alte
seturi de date, se pot specifica variabilele pe care dorim să le păstrăm
sau să le excludem folosind opțiunile DROP= și KEEP=.
DATA fuziune_inaltime (DROP=ID);
MERGE persoane (IN=inpers) masuratori (DROP=Greutate
IN=inmasura);
BY ID;
IF inpers=1 and inmasura=1;
RUN;

25
Unde specificăm DROP= și KEEP= ?
 În cazul fuziunii, opțiunile DPOP= și KEEP= se pot specifica fie în
instrucțiunea DATA, fie în MERGE, în funcție de modul în care dorim
să referim variabilele în setul de date:
 Dacă nu dorim să referim anumite variabile și ca acestea să
apară în noul set de date, atunci acestea vor fi specificate în
opțiunea DROP = a instrucțiunii MERGE.
masuratori (DROP=Greutate IN=inmasura);
 Dacă avem nevoie să referim o variabilă din seturile de date de
intrare (spre exemplu, într-o instrucțiune IF), atunci variabila va fi
specificată în opțiunea DROP a instrucțiunii DATA. În sens
contrar, este posibil să obținem rezultate nedorite și ca variabila
să fie neinițializată.
DATA fuziune_inaltime (DROP=ID);
Atenție!!! Atunci când este folosită în instrucțiunea DATA, opțiunea
DROP= doar elimină variabilele din noul set de date, acestea sunt în
continuare citite și disponibile pentru procesare în secțiunea de date.26
Redenumirea variabilelor
 Dacă există mai multe variabile care au același nume în seturile de
date de intrare, atunci fuziunea seturilor de date în secțiunea de date
va duce la suprascrierea valorilor variabilelor din primul set de date cu
valorile variabilelor cu același nume din seturile de date care îl succed.
 Pentru a preveni suprascrierea, se pot redenumi variabilele folosind
opțiunea RENAME= în instrucțiunea MERGE.
 Sintaxa generală este:
(RENAME=(nume_variabila_vechi=nume_variabila_nou));
 Se pot redenumi oricâte variabile într-o singură instrucțiune
RENAME.
 De asemenea, putem folosi RENAME= și pentru a redenumi variabile
în instrucțiunea SET sau în setul de date de ieșire din instrucțiunea
DATA.

27
Redenumirea variabilelor: exemplu -1
 Cazul 1 – evitarea suprascrierii datelor
 Se consideră seturile de date listate mai jos referitoare la persoanele
care s-au înscris pentru susținerea unui test de certificare. Se dorește
realizarea unei jonctiuni între aceste două seturi de date.

DATA examene_certificare;
MERGE inscrisi (RENAME=(data=data_inscriere))
sustineri (RENAME=(data=data_sustinere));
BY Cod;
FORMAT data_inscriere data_sustinere DDMMYY10.;
RUN;

28
Redenumirea variabilelor: exemplu -2
 Cazul 2 – facilitarea combinării datelor
DATA produse1;
INPUT COD Pret Disponibil;
DATALINES;
124 23.5 50
178 35.0 43
197 44.6 12
;
RUN;
DATA produse2;
INPUT COD Cost Stoc;
DATALINES;
234 53.7 10
356 75.5 12
367 84.0 34
;
RUN;
DATA concatenare;
SET produse1 (RENAME=(Disponibil=Stoc))
produse2 (RENAME=(Cost=Pret));
RUN;

29
Proceduri specifice SQL -1
 Procedura SQL reprezintă implementarea în SAS a limbajului
Structured Query Language (SQL), un standard utilizat pe scară
largă pentru regăsirea și utilizarea datelor din tabele.
 Procedura SQL este folosită, în mod frecvent, ca o alternativă la alte
proceduri SAS sau la secțiunea de date.
 Se poate folosi procedura SQL pentru a:
 Regăsi și manipula date din tabele SAS
 Adăuga și modifica valori într-o tabelă
 Adăuga, modifica și șterge coloane într-o tabelă
 Crea tabele și view-uri
 Crea joncțiuni între mai multe tabele
 Genera rapoarte

30
Proceduri specifice SQL -2
 Asemenea altor proceduri SAS, procedura SQL permite combinarea
datelor din două sau mai multe surse diferite și prezentarea acestora
ca o singură tabelă. Spre exemplu, se pot combina date din două
tipuri de baze de date externe sau din baze de date externe și seturi
de date SAS.
 Procedura SQL diferă de multe alte proceduri prin aceea că
majoritatea din instrucțiunile sale includ clauze.
PROC SQL;
SELECT Cod,Pozitie,Salariu,
Salariu*.06 as Bonus
FROM biblioteca.salarii
WHERE Salariu<32000
ORDER BY Cod;
QUIT;
 În exemplul de mai sus apar două instrucțiuni: PROC SQL și
SELECT. Instrucțiunea SELECT include clauzele: SELECT, FROM,
WHERE și ORDER BY.

31
Proceduri specifice SQL -3
 Procedura SQL nu necesită o instrucțiune RUN, iar fiecare
interogare este executată imediat. Dacă se folosește instrucțiunea
RUN la sfârșitul unei proceduri SQL, SAS o ignoră, execută toate
instucțiunile în mod obișnuit și generează în SAS log nota de mai
jos.
NOTE: PROC SQL statements are executed immediately; The
RUN statement has no effect
 Pentru a termina procedura, se trimite spre rulare altă secțiune de
date sau de proceduri sau se folosește instrucțiunea QUIT.

 Spre exemplu, ca măsură de precauție, SAS Enterprise Guide


adaugă automat o instrucțiune QUIT la codul trimis către SAS.
Pentru procedura SQL aceasta este o bună practică de programare.

32
Combinarea datelor cu PROC SQL -1
 O joncțiune în procedura SQL reprezintă o interogare în care se
specifică mai multe tabele care trebuie combinate și care, de cele
mai multe ori, arată ce condiții trebuie să îndeplinească rândurile
care vor fi combinate și returnate către setul de date rezultat.
 Se pot utiliza cele patru tipuri de joncțiuni din limbajul SQL: inner
join, left join, right join si full outer join.
 Sintaxa generală pentru joncțiunea internă este:
SELECT coloana-1<,...coloana-n>
FROM tabela-1 | view-1, tabela-2 | view-2<,...tabela-n | view-n>
WHERE conditie(i)-jonctiune
<AND alte conditii suplimentare)>
<alte clauze>;
 Joncțiunea internă vs. produsul cartezian.

33
Combinarea datelor cu PROC SQL -2
 O joncțiune externă combină și afișează toate rândurile care au
corespondent între tabele, plecând de la criteriul de corespondență
specificat (numit și condiție de joncțiune), plus o parte sau toate
rândurile care nu au corespondent. Aceasta poate fi privită ca o
augmentare a joncțiunii interne.
 Sintaxa generală pentru joncțiunile externe este:
SELECT coloana-1<,...coloana-n>
FROM tabela-1 | view-1
LEFT JOIN | RIGHT JOIN | FULL JOIN
tabela-2 | view-2
ON conditie(i)-jonctiune
<alte clauze>;
 Dacă se dorește folosirea unei sintaxe asemănătoare pentru toate
tipurile de joncțiune, atunci și pentru joncțiunea internă se poate
folosi aceeași sintaxă ca și la joncțiunile externe specificând INNER
JOIN ca tip de joncțiune.
 Diferența dintre cele două modalități de descriere a unei joncțiuni
interne este aceea că în prima variantă se pot combina până la 256
de tabele sau view-uri, iar în cea de-a doua doar două. 34
Comparație SAS-SQL: exemplu
 Considerăm pentru exemplificare cele două seturi de date de mai
jos. Rândurile evidențiate sunt cele care nu au corespondent în
celălalt set de date.

 Vom exemplifica cele patru tipuri de joncțiuni, comparativ, folosind


abordarea specifică SAS și abordarea SQL.

35
Exemple INNER JOIN
PROC SQL; PROC SORT DATA =
CREATE TABLE inner_SQL as exemple.Vanzari;
SELECT b.Tranzactie BY Cod_vanzare;
, b.Cod_produs RUN;
, b.Cantitate PROC SORT DATA = exemple.Agenti;
, b.DATA_vanzare BY Cod_vanzare;
, a.Cod_vanzare RUN;
, a.Nume DATA inner_join;
FROM exemple.Vanzari b, MERGE exemple.Vanzari ( in = s )
Exemple.Agenti a exemple.Agenti ( in = p );
WHERE a.Cod_vanzare = BY Cod_vanzare;
b.Cod_vanzare IF s and p;
ORDER BY Cod_vanzare; RUN;
QUIT;

Ambele abordări furnizează rezultate identice.

36
Exemple LEFT JOIN
PROC SQL; PROC SORT DATA =
CREATE TABLE left_SQL as exemple.Vanzari;
SELECT s.Tranzactie BY Cod_vanzare;
, s.Cod_produs RUN;
, s.Cantitate PROC SORT DATA = exemple.Agenti;
, s.DATA_vanzare BY Cod_vanzare;
, p.Cod_vanzare RUN;
, p.Nume DATA left_MERGE;
FROM exemple.Vanzari s MERGE exemple.Vanzari ( in = s )
left join Exemple.Agenti ( in = p );
exemple.Agenti p BY Cod_vanzare;
ON s.Cod_vanzare = IF s;
p.Cod_vanzare RUN;
ORDER BY Cod_vanzare;
QUIT;

37
Exemple RIGHT JOIN
PROC SQL; PROC SORT DATA =
CREATE TABLE right_SQL as exemple.Vanzari;
SELECT p.Cod_vanzare BY Cod_vanzare;
, p.Nume RUN;
, s.Tranzactie PROC SORT DATA = exemple.Agenti;
, s.Cod_produs BY Cod_vanzare;
, s.Cantitate RUN;
, s.DATA_vanzare DATA right_MERGE;
FROM exemple.Vanzari s MERGE exemple.Vanzari ( in = s )
right join exemple.Agenti ( in = p );
exemple.Agenti p BY Cod_vanzare;
ON s.Cod_vanzare = IF p;
p.Cod_vanzare RUN;
ORDER BY Cod_vanzare;
QUIT;

38
Exemple FULL OUTER JOIN
PROC SQL; PROC SORT DATA =
CREATE TABLE full_SQL as exemple.Vanzari;
SELECT p.Cod_vanzare BY Cod_vanzare;
, p.Nume RUN;
, s.Tranzactie PROC SORT DATA = exemple.Agenti;
, s.Cod_produs BY Cod_vanzare;
, s.Cantitate RUN;
, s.DATA_vanzare DATA full_MERGE;
FROM exemple.Vanzari s MERGE exemple.Vanzari ( in = s )
full outer join exemple.Agenti ( in = p );
exemple.Agenti p BY Cod_vanzare;
ON s.Cod_vanzare = RUN;
p.Cod_vanzare
ORDER BY Cod_vanzare;
QUIT;

39
Avantaje comparative ale abordărilor
SQL
 Seturile de date nu trebuie sortate în mod explicit, doarece SQL
sortează datele în mod implicit;
 Se poate realiza, în aceeași interogare, o joncțiune între mai
multe tabele după mai multe chei (chiar dacă tipurile de variabile
diferă);
 Interogările care realizează joncțiuni pot, de asemenea, să
realizeze agregări ale datelor.
SAS
 Pentru jonctiuni interne, externe, utilizeaza variabilele temporare
IN=;
 Construcțiile limbajului sunt mai ușor de înțeles și aplicat.

40
Să recapitulăm!
1. Care dintre metodele de combinare a seturilor de
date folosesc instrucțiunea SET?
2. Ce diferențe sunt între concatenare și adăugare?
3. Ce fel de variabilă este cea definită prin IN=variabila?
4. De ce este uneori necesară redenumirea variabilelor
la combinarea seturilor de date?
5. În declarația MERGE date1(DROP=Nume) variabila Nume
va putea fi folosită în continuare în secțiunea de date?
6. Câte seturi de date pot participa, în procedura SQL,
la o joncțiune internă ?
Programarea în
limbajul SAS

SAS4
CUPRINS
 Proceduri SAS
 Procesarea variabilelor cu ajutorul masivelor
Proceduri SAS -1
 Majoritatea prelucrărilor asupra datelor sunt realizate în SAS prin
intermediul procedurilor sale predefinite. Acestea reprezintă
secțiunile de proceduri în cadrul programelor SAS.
 Prin intermediul procedurilor SAS se pot realiza, rapoarte de detaliu
și agregate, reprezentări grafice, analize statistice elementare sau
complexe, rezolvarea unor probleme de optimizare și analiză
decizională etc.
 Există o mare varietate de proceduri SAS incluse în toate pachetele
oferite de limbaj.
Proceduri pentru prezentarea datelor
Scop: Rapoarte Pachetul: BASE SAS
PRINT Realizează rapoarte detaliate și este principala modalitate de afișare de
datelor. (optiuni IN, BY etc.)
TABULATE Crează rapoarte în formă tabelară care afișează frecvențe, procente și
statistici descriptive.
REPORT Oferă o modalitate de realizare a rapoartelor care combină
caracteristice oferite de procedurile PRINT, MEANS și TABULATE. 3
Proceduri SAS -2
Proceduri pentru agregarea datelor:
Scop: Agregare Pachetul: BASE SAS
MEANS Realizează agregarea datelor prin generarea de indicatori statistici
pentru datele numerice. Generează seturi de date agregate. (N, Min,
Max, STD)
FREQ Generează tabele care arată frecventa de aparitie a datelor.
UNIVARIATE Calculează, realizează evaluarea normalității datelor și distribuția
unidimensională a datelor, identifică valorile extreme.
SUMMARY Este similară procedurii MEANS, având câteva opțiuni diferite.

Proceduri pentru analize statistice elementare:


Scop: Statistici Pachetul: BASE SAS
CORR Calculează coeficienții de corelație Pearson, măsoară statistici
nonparametrice de asociere și probabilitățile asociate acestora.
RANK Calculează rangurile pentru una sau mai multe variabile numerice în
cadrul observațiilor unui set de date și creează un set de date de ieșire.
STANDARD Genereaza un set de date de ieșire care conține variabile care sunt
standardizate la o anumită medie și deviație standard.
4
Proceduri SAS -3
Proceduri pentru analize statistice avansate:
Scop: Statistici Pachetul: SAS/STAT
ANOVA Realizează analize dispersionale pe date echilibrate.
REG Este folosită pentru mai multe modele de regresie și aplică metoda celor
mai mici pătrate.
LOGISTIC Se folosește pentru modelele cu variabile dependente binare, ordinale sau
nominale.
CLUSTER Realizează grupări ierarhice ale observațiilor dintr-un set de date.

Proceduri pentru realizarea de grafice:


Scop: Grafice Pachetul: SAS/GRAPH
GCHART Produce șase tipuri de grafice care pot reprezenta valoarea unei statistici
calculate pentru una sau mai multe variabile.
GPLOT Construiește o diagramă de corelație pentru două variabile.

Proceduri pentru probleme de optimizare :


Scop: Optimizare Pachetul: SAS/OR
Proceduri Sunt specifice pentru arbori decizionali, grafice GANTT, probleme de
transport, alocare, planificare etc.
Solvere Aplică diferiți algoritmi pentru rezolvarea problemelor de tip
5
programare liniară, non-liniară, teoria grafurilor etc.
Sintaxa procedurilor SAS -1
 Sintaxa generală a procedurilor SAS poate fi destul de complexă.
Spre exemplu, procedura MEANS are următoarea sintaxă completă:
PROC MEANS <option(s)> <statistic-keyword(s)>;
BY <DESCENDING> variable-1 <... <DESCENDING> variable-
n><NOTSORTED>;
CLASS variable(s) </ option(s)>;
FREQ variable;
ID variable(s);
OUTPUT <OUT=SAS-data-set> <output-statistic-specification(s)>
<id-group-specification(s)> <maximum-id-specification(s)>
<minimum-id-specification(s)> </ option(s)> ;
TYPES request(s);
VAR variable(s) < / WEIGHT=weight-variable>;
WAYS list;
6
WEIGHT variable
Sintaxa procedurilor SAS –2
 În practică, rareori se folosește varianta completă a procedurii.
Modalități de utilizare a sintaxei procedurilor:
1. Folosirea unei proceduri fără opțiuni
În mod implicit, SAS folosește ultimul set de date creat și calculează
medii pentru toate variabilele numerice din acel set de date.
PROC MEANS;
RUN;
2. Folosirea opțiunilor
Opțiunea data= specifică setul de date pe care se va aplica procedura.
Este recomandat să se folosească întotdeauna. Opțiunile
n, mean și std stabilesc indicatorii statistici care se vor calcula.
PROC MEANS DATA=auto N MEAN STD ;
RUN;
3. Folosirea de instructiuni suplimentare
Declarația var arată ce variabile se vor folosi pentru calculul
indicatorilor, iar class determină defalcarea statisticilor în funcție de
valorile variabilei specificate.
PROC MEANS DATA=auto;
CLASS provenienta;
VAR pret; 7
RUN;
Exemplu – statistici pe salariu pe departamente

PROC MEANS DATA=ad_data.angajati;


CLASS departament;
VAR salariu;
RUN;

8
Procesarea variabilelor cu ajutorul masivelor
 În secțiunea de date, de multe ori, este necesar să se repete
aceeași secvență de cod pentru mai mult de o singură variabilă.
 Chiar dacă variabilele pot fi procesate individual, este mai eficient să
le gestionăm grupate.
 Acest lucru poate fi realizat în SAS cu ajutorul masivelor.
 Exemplu: Dorim să transformăm din grade Fahrenheit în grade
Censius temperaturile înregistrate în fiecare zi din luna martie.

DATA temperaturi;
SET temp_martie;
ARRAY temp {31} ziua1-ziua31;
DO i=1 to 31;
temp{i}=5*(temp{i}-32)/9;
END;
RUN;

9
Crearea masivelor unidimensionale
 Definire
ARRAY nume_masiv {dimensiune} <elemente>;
unde:
• nume_masiv specifică numele masivului
• dimensiune descrie numărul de elemente ale masivului
• elemente listează variabilele care sunt incluse în masiv.
Elementele trebuie să fie ori de tip numeric, ori de tip caracter.
Dacă nu se specifică elementele, atunci se crează variabile noi
având nume implicite.
Observații
 Un masiv nu trebuie să aibă același nume cu o variabilă din
secțiunea de date sau cu numele unei funcții.
 Nu se pot folosi pentru denumire cuvinte rezervate pentru instucțiuni.
 Un masiv există doar pe durata secțiunii de date.

10
Crearea masivelor unidimensionale -2
 Specificarea dimensiunii
Considerăm setul de date Vanzari2018, în care este necesar să
procesăm variabilele Trim1, Trim2, Trim3 și Trim4 în același fel.
Există mai multe modalități de specificare a dimensiunii:
 specificarea directă a numărului de elemente
ARRAY vanzari{4} trim1 trim2 trim3 trim4;
 Specificarea unui interval de valori
ARRAY vanzari{96:99} totalv96 totalv97 totalv98 totalv99;
 Folosirea semnului asterisc (*), iar SAS va determina dimensiunea
prin numărarea elementelor
ARRAY vanzari{*} trim1 trim2 trim3 trim4;
• Dimensiunea poate fi inclusă între paranteze rotunde, pătrate sau
acolade.
 Specificarea elementelor
Elementele masivului se pot specifica individual, separate prin spațiu,
sau ca listă de variabile care grupează mai multe variabile.
ARRAY vanzari{4} trim1-trim4; 11
Crearea masivelor unidimensionale -3
 Liste de variabile ca elemente ale masivului
Se pot specifica listele de variabile în formatele următoare:
 O serie numerotată de variabile: Var1-Varn;
 variabilele trebuie să aibă același nume, cu excepția ultimului
sau ultimelor caractere
 ultimul caracter al variabilelor trebuie să fie numeric
 variabilele trebuie numerotate consecutiv
 Listele cu domeniu denumit: a--d;
 depind de ordinea internă sau de poziţia variabilelor în setul de
date.
 lista abreviată a--d referă variabilele numerice care au fost
definite prin declaraţia INPUT a b c d; .
 Listele cu valori speciale: _NUMERIC_ _CHARACTER_ _ALL_
 Au semnificația de a specifica, în grup, toate variabilele de tip numeric,
caracter și respectiv, de orice tip, care au fost deja definite în secțiunea
de date curentă.
ARRAY vanzari {*}_all_;
12
Crearea masivelor unidimensionale -4
 Referirea elementelor
nume_masiv (subscript)
Unde subscript:
• este inclus în paranteze rotunde, pătrate sau acolade
• specifică o variabilă, o expresie SAS sau un întreg
• este inclus între limitele dimensiunii masivului

Exemplu: crearea unui set de date care conține vânzările exprimate în USD.

DATA vanzari18_usd (drop=i);


SET vanzari18;
ARRAY vanzari(4) trim1-trim4;
DO i=1 to 4;
vanzari(i)= round(vanzari(i)/4.75,1);
END;
RUN;

13
Liste de variabile - exemplu
DATA chestionar;
INPUT q1 $ q2 $ q3 $ q14 $ q5 $ q6 $ q7 $ q8 $ q9 $ q10
$;
DATALINES;
0 1 DA nu Da 2 6 NS 0 1
2 da nu 3 2 1 0 ns 0 NU
2 1 2 0 Ns DA 0 1 4 NU
;
DATA chestionar_cor;
SET chestionar;
ARRAY intrebari(*) _CHARACTER_;
DO i=1 TO DIM (intrebari);
SELECT(upcase (intrebari(i)));
WHEN ('0', 'NU') intrebari(i)='0';
WHEN ('1', 'DA') intrebari(i)='1';
WHEN ('2', 'NS') intrebari(i)='2';
OTHERWISE call missing (intrebari(i));
END;
END;
DROP i;
RUN; 14
Crearea de variabile în masive
 În instrucțiunea ARRAY se pot crea variabile prin omiterea
specificării elementelor masivului din declarație.
 Dacă nu se referă variabile deja existente, SAS crează variabile noi
în mod automat cărora le asignează și nume implicite.
 Aceste nume sunt formate prin concatenarea numelui masivului cu
numerele de la 1 la numărul de elemente.

Exemplu: calculăm pierderea sau creșterea în greutate, de la o săptămână la


alta, a membrilor unei clase de fitness.

DATA diferente;
SET greutate;
ARRAY gr{6} greutate1-greutate6;
ARRAY difGr {5};
DO i=1 to 5;
difGr{i}=gr{i+1}-gr{i};
END;
RUN;
15
Alocarea de valori inițiale
 Se realizează prin declarații de genul:
ARRAY obiectiv{4} o1 o2 o3 o4 {300 340 350 390};
ARRAY var{4} {1 2 3 4};
Exemplu: calculam nivelul de realizare a unui indicator financiar.
DATA Vanzari_anuale;INPUT RepVanzari $ Vanz1 Vanz2 Vanz3 Vanz4;
DATALINES;
Dinca 8400 8800 9300 9800
Irimia 9500 9300 9800 8900
Mihai 9150 9200 9650 11000
; RUN;
DATA raport(DROP=i);
SET Vanzari_anuale;
ARRAY vanzari{4} vanz1-vanz4;
ARRAY tinta {4} (9000 9300 9600 9900);
ARRAY realizat {4};
DO i=1 TO 4;
realizat {i} =100* vanzari{i}/tinta{i};
END;RUN;
 Pentru a nu stoca variabilele tinta1-tinta4, definim masivul ca temporar:
ARRAY tinta {4} _temporary_ (9000 9300 9600 9900);

16
Crearea masivelor bidimensionale
 Masivele bidimensionale simulează o structură de tip tabelă.
 Sintaxa generală este:
ARRAY nume_masiv {randuri, coloane} <elemente>;
ARRAY an {3,4} x1-x12;
X1 X2 X3 X4

X5 X6 X7 X8

X9 X10 X11 X12

Spre exemplu, X7 se referă ca an {2,3}


 Se folosesc, de obicei, împreună cu bucle DO imbricate.
 Aplicații frecvente în SAS:
 Restructurarea variabilelor unui set de date (similară agregării)
 Transpunerea unui set de date
17
Aplicații cu masive bidimensionale - 1
 Restructurarea unui grup de variabile - Exemplu: Vânzările anuale ale unei
companii au fos stocate lunar. Se dorește generarea unui nou set de date
care conține vânzările trimestriale.
DATA trimestriale (DROP= i j);
SET lunare;
ARRAY l {4,3} luna1-luna12; ARRAY trim {4};
DO i=1 to 4;
trim {i}=0;
DO j=1 to 3;
trim{i}+l{i,j};
END;
END;
RUN;
 Transpunerea (rotirea) unui set de date prin schimbarea variabillor cu
observațiile sau viceversa. - Exemplu: Transpunerea setului Vanzari_anuale.
DATA Vanzari_anuale_timestru (DROP=vanz1-vanz4);
SET Vanzari_anuale;
ARRAY finante{4} vanz1-vanz4;
DO trim=1 to 4;
Vanzari=finante{trim};
output;
END;
18
RUN;
Exemplu transpunere

19
Exemple masive 1

Se doreşte realizarea unui sondaj prin intermediul căruia să se măsoare gradul de


satisfacţie al cursurilor din domeniul economic oferite de o platformă e-learning.
Respondenţii pot acorda calificative de la 1 la 5, iar în situaţia în care nu au urmat un
curs sau nu doresc să acorde un calificativ, se va introduce valoarea 0.
Se cere să se înlocuiască valoarea 0 cu valoarea lipsă.
*Calcule repetitive cu masive;
DATA cursuri;
INFILE '/home/nume.prenume/Cursuri.txt';
Length Oras $9;
INPUT Oras$ Varsta ECON MRKT FINA CONT STAT MATE INFO;
ARRAY curs (7) ECON MRKT FINA CONT STAT MATE INFO;
DO i = 1 TO 7;
IF curs(i) = 0 THEN curs(i) = .;
END;
RUN;
PROC PRINT DATA = cursuri;
TITLE 'Sondaj cursuri economice';
RUN;

20
Exemple masive 2
Se cere ca pornind de la datele de la anterior, să se înlocuiască toate valorile 0 cu
valoare lipsă, fără a afecta datele originale, prin crearea unor noi variabile denumite
Curs1-Curs7. Totodată, se cere să se determine media punctajelor acordate de fiecare
respondent.
*****Aplicatii cu liste abreviate si masive;
DATA cursuri;
INFILE '/home/nume.prenume/Cursuri.txt';
Length Oras $9;
INPUT Oras$ Varsta ECON MRKT FINA CONT STAT MATE INFO;
ARRAY nou (7) Curs1 - Curs7;
ARRAY vechi (7) ECON -- INFO;
DO i = 1 TO 7;
IF vechi(i) = 0 THEN nou(i) = .;
ELSE nou(i) =vechi(i);
END;
MedieCalif = MEAN (OF Curs1 - Curs7);
RUN;
PROC PRINT DATA = cursuri;
TITLE 'Sondaj cursuri economice cu media calificativelor';
RUN;
21
Exemple masive 3
Au fost memorate răspunsurile date de studenţi la un test. Se cere să se
înlocuiască toate răspunsurile care nu corespund caracterelor a, b, c, d (litere
mari sau mici) cu valoarea lipsă şi să se transforme toate valorile variabilelor de
tip caracter în litere mari.

*Aplicatii cu nume speciale de liste SAS;


libname ad_data "/home/nume.prenume";
DATA raspunsuri;
SET ad_data.RASPUNSURI;
ARRAY var_caracter {*} _character_;
DO i = 1 TO dim (var_caracter);
IF var_caracter(i) NOT IN ('a' 'b' 'c' 'd' 'A' 'B' 'C' 'D') then
call missing(var_caracter(i));
ELSE var_caracter(i)= upcase (var_caracter(i));
END;
DROP i;
RUN;
PROC PRINT DATA = raspunsuri;
TITLE 'Raspunsurile studentilor la test';
RUN;

22
Întrebări recapitulative -1
1. Care instrucțiune DO nu va procesa toate elementele din masivul
factori, definit mai jos?
ARRAY factori {*} varsta inaltime greutate;
a. do i=1 to dim(factori);
b. do i=1 to dim(*);
c. do i=1, 2, 3, 4;
d. do i=1 to 4;
2. Plecând de la instrucțiunea ARRAY de mai jos, identificați referința
elementului q50 al masivului:
ARRAY elemente{3,25} q1-q75;
a. elemente {q50}
b. elemente {1,50}
c. elemente {2,25}
d. elemente {3,0}

23
Întrebări recapitulative -2
3. Care dintre următoarele referințe la o bibliotecă este corectă?
a. 2010Date
b. date/2010
c. Date_2012
d. 1_sau_a
4. Următorul program SAS este trimis spre execuție:
PROC FORMAT;
VALUE PUNCTAJ 1 - 50 = “ADMIS”;
51 - 100 = “RESPINS”;
RUN;
Care dintre următoarele proceduri PRINT aplică în mod corect
formatul?
a. PROC PRINT DATA = exemplu;
VAR test; FORMAT test PUNCTAJ; RUN;
b. PROC PRINT DATA = exemplu;
VAR TEST; FORMAT test PUNCTAJ.; RUN;
c. PROC PRINT DATA = exemplu FORMAT = PUNCTAJ;
VAR test; RUN;
d. PROC PRINT DATA = exemplu FORMAT = PUNCTAJ.;
24
VAR test; RUN;
Întrebări recapitulative -3
5. Plecăm de la următoarea eroare apărută în SAS log:
44 data WORK.OUTPUT;
45 set SASHELP.CLASS;
46 BMI=(Greutate*703)/Inaltime**2;
47 where bmi ge 20;
ERROR: Variable bmi is not on file SASHELP.CLASS.
48 run;
Ce schimbare în program va corecta eroarea?
a. Adăugarea opțiunii (Keep=BMI) în instrucțiunea SET
b. Schimbarea ** in formula BMI cu un singur character *
c. Schimbarea bmi cu BMI în instrucțiunea WHERE
d. Înlocuirea instrucțiunii WHERE cu o instrucțiune IF

6. Identificați procedura prin care pot fi vizualizate etichetele și


formatele permanente asociate unui set de date:
a. PROC PRINT
b. PROC FORMAT
c. PROC CONTENTS
d. PROC UNIVARIATE 25
Întrebări recapitulative -4
7. Avem ca intrare două seturi de date referitoare la manageri și la angajații aflați
în subordinea acestora. Ce raport se poate realiza pe baza setului de date
rezultat din jonctiune?
DATA rezultat;
MERGE manageri (in=M)angajati (in=A);
BY IDAngajat;
IF M=0 and A=1;
RUN;

26
PYTHON

PYTHON I
• Sintaxa, reguli cod Python;
• Tipuri de date;
• Colectii de date: Liste, Dictionare, Seturi, Tupluri;
• Functii Python, UDF, anonime (lamda);
CUPRINS • Structuri de programare;
• Citirea datelor din fisiere.
INTRODUCERE (I)
• A fost inventat în 1991 de Guido van Rossum;
• Python este limbaj de programare de ultimă generație, ușor de
învățat, ca urmare a sintaxei simple similare cu limba engleză;
• Necesită mai puține linii de cod în comparație cu alte limbaje;
• Python rulează pe diferite sisteme de operare: Windows, Mac,
Linux, Ubuntu, Raspbian etc.;
• Limbajul poate fi utilizat în mai multe medii (IDE): Eclipse,
PyCharm, Thonny, Netbeans, Spyder etc.;
• Conține o bibliotecă vastă de pachete: numpy, pandas, matplotlib,
seaborn, scikit-learn etc.;
• Python se poate conecta la baze de date. Citește și modifică
fișiere;
• Poate gestiona volume mari de date (big data) și efectua operații
matematice complexe.
INTRODUCERE (II)
o Numpy seturi de date omogene,
o Pandas seturi de date neomogene,
o Scipy, Scikit Learn machine learning, IA,
o Keras rețele neuronale, deep learning, IA,
o Matplotlib, Seaborn, Bokeh reprezentare
grafică,
o PyPSA pachete specializate pe domenii de
activitate, de exemplu funcționarea optimă pe
principii de piața a generatoarelor electrice,
o BeautifulSoup web-scraping,
o Flask (API-uri) etc.
ELEMENTE DE SINTAXA
• Spre deosebire de alte limbaje (R, C++,
Java, Perl etc.) care utilizeaza paranteze,
Python utilizeaza indentarea (tab sau
spatii);

• Doua puncte (:) denota necesitatea unei


indentari;

• Nu solicita punct si virgula (;), dar sunt


necesare atunci cand utilizam mai multe
declaratii pe aceeasi linie;

• Comentariu pe linie (#), pe mai multe linii


(’ ’ ’).
TIPURI DE DATE
• int, float, complex. Functia type() verifica tipul de data;
• Specificarea tipului de dată pentru o variabilă: int(), float(), complex(), str();
• Siruri de caractere marcate cu ‘ ’ sau “ ”;
• Extragerea elementelor dintr-un sir: sir[ ];
• Cateva metode pentru siruri de caractere: sir.strip(), sir.strip(‘caractere’),
len(sir), sir.lower(), sir.upper(), sir.replace(“ ”, “”);
• Variabilele nu necesita declarare explicita si sunt case-sensitive.
COLECTII DE DATE – LISTE (ARRAY)
• Colecții de date care pot fi neomogene, ordonate și modificate, permit elemente identice si sunt
reprezentate utilizând [ ];
• Modificare element: lista[index] = valoare  index incepe de la 0;
• Numar elemente: len(lista);
• Adaugare element la sfarsitul listei: lista.append(element);
• Adaugare element la un anumit index: lista.insert(index,element);
• Eliminare element:
- lista.remove(element)elimina primul element daca in lista exista mai multe elemente
identice;
- lista.pop(index)  elimina ultimul element daca nu se specifica indexul;
- del lista[index];
• Golire lista: lista.clear();
• Sterge lista: del lista.
ACCESARE LISTE
seq = [7, 2, 3, 7, 5, 6, 0, 1]
Index 0 1 2 3 4 5 6 7
-7 -6 -5 -4 -3 -2 -1 0
print(seq[1:5])
# [2, 3, 7, 5]
seq[3:4] = [6, 3]
print(seq)
# [7, 2, 3, 6, 3, 5, 6, 0, 1]
seq[3:] = [6, 3]
print(seq)
# [7, 2, 3, 6, 3]
print(seq[:3])
# [7, 2, 3]
print(seq[3:])
# [6, 3]
print(seq[-4:])
# [2, 3, 6, 3]
print(seq[::2])
# [7, 3, 3]
print(seq[::-1])
# [3, 6, 3, 2, 7]
Metoda Descriere
append() Adaugă un element la sfârșitul listei
clear() Elimină toate elementele listei
copy() Crează o copie a listei
count() Returnează numărul de apariții al elementului în listă
extend() Adăugă elemente la sfârșitul unei liste b = ['saw', 'small', 'He', 'foxes', 'six']
b.sort(reverse = True)
Ex: seq = [7, 2, 3, 6, 3]; seq.extend([1,2,3]); print(seq) print(b)
 [7, 2, 3, 6, 3, 1, 2, 3] #['small', 'six', 'saw', 'foxes', 'He’]
index() Returnează indexul unui element
insert() Adaugă un element la poziția specificată b.sort(key=len)
print(b)
pop() Elimină elementul de la poziția specificată
#['He', 'six', 'saw', 'small', 'foxes']
remove() Elimină primul element specificat
reverse() Inversează ordinea elementelor în listă
sort() Sortează lista

COLECTII DE DATE
LISTE METODE
FUNCTII BUILD-IN RANGE (GENERARE LISTE)
#range([start], stop[, step])
print(list(range(18))) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]
print(list(range(5,18))) [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]
print(list(range(5,18,2))) [5, 7, 9, 11, 13, 15, 17]
print(list(reversed(range(10))))
#[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

b = ['saw', 'small', 'He', 'foxes', 'six'] saw


b_len = len(b) small
for i in range(0, b_len): He
print(b[i]) foxes
six
def frange(start, stop, step):
0.5
i = start
0.6
while i <= stop:
yield round(i,2)
0.7
i += step
0.8
for i in frange(0.5, 1, 0.1): 0.9
print(i) 1.0
FUNCTII BUILD-IN ZIP
#zip realizeaza perechi din elementele unor liste, tupluri sau
secvente pentru a genera o lista de tupluri
#Exercitiu 1
seq1 = ['one', 'two', 'three']
seq2 = ['cat', 'dogs', 'mice']
zipped = zip(seq1, seq2)
print(list(zipped))
# [('one', 'cat'), ('two', 'dogs'), ('three', 'mice')]

#Exercitiu 2
seq3 = [False, True]
print(list(zip(seq1, seq2, seq3)))
#[('one', 'cat', False), ('two', 'dogs', True)]
COLECTII DE DATE - TUPLURI
• Colecții de date neomogene, ordonate și nemodificabile, permit elemente identice si sunt
reprezentate utilizând ( ) t = tuple(['four', [1, 2], True])

• Accesare element: tuplu[index] t = ((7,1), [1, 2], 'mar', False)


lista = list(t)
• Utilizand tuple, pot fi transformate liste in tupluri gen = range(10)
• Utilizand list, pot fi transformate tupluri in liste print(tuple(gen))
print(list(gen))
• Listele si tuplurile pot fi concatenate cu + t = tuple(['four', [1, 2], True])
gen =tuple(range(10))
Metoda Descriere print(t+gen)

count() Returnează numărul de apariții al l = ['four', [1, 2], True]


gen1 =list(range(10))
elementului în tuplu print(l+gen1)
index() Returnează poziția unui element în tuplu
COLECTII DE DATE - DICTIONARE
• Colecții de date neordonate, modificabile și indexate. Nu sunt admise elemente duplicate.
Dicționarele sunt reprezentate prin { }, având elemente cheie-valoare;
• Accesare si modificare valoare: dictionar[cheie] = valoare noua.
Metoda Descriere
clear() Elimină toate elementele din dicționar
copy() Returnează o copie a dicționarului
fromkeys() Returnează un dicționar cu chei valori specificate
get() Returnează valoarea pentru o anumită cheie
items() Returnează o listă conținând un tuplu pentru fiecare pereche cheie-valoare
keys() Returnează o listă conținând cheile dicționarului
pop() Elimină elementul având o anumită cheie specificată
popitem() Elimină ultima pereche adăugată cheie-valoare
setdefault() Returnează valoarea pentru o cheie specificată. Dacă cheia nu există, o adaugă
update() Actualizează dicționarul cu perechile cheie-valoare specificate
values() Returnează o listă cu toate valorile dicționarului
Exemple dictionare
d1 = {'a' : 'some value', 'b' : [1, 2, 3, 4]}; print(d1)
# Afiseaza d1 {'a': 'some value', 'b': [1, 2, 3, 4]}
d1[7] = 'an integer'
print(d1)
# Adauga un element la d1 {'a': 'some value', 'b': [1, 2, 3, 4], 7: 'an integer’}
print(d1['b'])
# Afiseaza valoarea pentru cheia respectiva [1, 2, 3, 4]
print('b' in d1)
# Verifica daca cheia respectiva face parte din dictionar True
d1[5] = 'some value’; d1['dummy'] = 'another value’ # Adauga noi elemente {'a': 'some
value','b': [1, 2, 3, 4],7: 'an integer',5: 'some value','dummy': 'another value’}
del d1[5] # Sterge elementul corespunzator {'a': 'some value','b': [1, 2, 3, 4],7: 'an
integer','dummy': 'another value’}
ret = d1.pop('dummy’); # Sterge {'a': 'some value', 'b': [1, 2, 3, 4], 7: 'an integer’}
list(d1.keys()) # Pune cheile intr-o lista ['a', 'b', 7]
list(d1.values()) # Pune valorile in lista ['some value', [1, 2, 3, 4], 'an integer’]
d1.update({'b' : 'four', 'c' : 12})
# Actualizeaza d1 {'a': 'some value', 'b': 'four', 7: 'an integer', 'c': 12}
# 1) Dictionare = colectii formate din doua tupluri
col2tup=dict(zip((0,1,2,3,4),(4,3,2,1,0)))
print(col2tup)
#{0: 4, 1: 3, 2: 2, 3: 1, 4: 0}
col2tup = dict(zip(range(5), reversed(range(5))))
print(col2tup)
#{0: 4, 1: 3, 2: 2, 3: 1, 4: 0}
Exemple dictionare
# 2)
words = ['dig','apple', 'bat', 'corn', 'dog', 'bar', 'atom', 'book', 'cat', 'cattle']
by_letter = {}
for word in words:
letter = word[0]
if letter not in by_letter:
by_letter[letter] = [word]
else:
by_letter[letter].append(word)
print(by_letter)
#{'d': ['dig', 'dog'], 'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book'], 'c':
['corn', 'cat', 'cattle']}
print(dict(sorted(by_letter.items())))
#{'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book'], 'c': ['corn', 'cat', 'cattle'],
'd': ['dig', 'dog']}
COLECTII DE DATE - SETURI
• Colecții de date neordonate și neindexate. Nu sunt acceptate elemente identice. Seturile sunt
reprezentate prin { }. Se aseamana cu dictionarele, numai ca elementele nu sunt cheie-valoare.
Metoda Descriere
add() Adaugă un element
clear() Elimină toate elementele setului
copy() Returnează o copie a setului
difference() Returnează un set reprezentând diferența dintre două sau mai multe seturi
difference_update() Elimină elementele dintr-un set care sunt conținute de un alt set specificat
discard() Elimină un element specificat
intersection() Returnează un set reprezentând intersecția a două seturi
intersection_update() Elimină elementele dintr-un set care nu sunt în alt set
isdisjoint() Arată dacă două seturi se intersectează sau nu
issubset() Arată dacă un set este inclus într-un alt set sau nu
issuperset() Arată dacă un set conține un alt set sau nu
pop() Elimină un element
remove() Elimină elementul specificat
symmetric_difference() Returnează un set cu elemente necomune celor doua seturi
symmetric_difference_update() Inserează intr-un set diferențele dintre două seturi
union() Returnează un set reprezentând reuniunea a două seturi
update() Actualizează setul cu reuniunea dintre un set și altele
Exemple seturi
print(set([2, 2, 2, 1, 3, 3]))
#{1, 2, 3}
print({2, 2, 2, 1, 3, 3})
#{1, 2, 3}

a = {1, 2, 3, 4, 5}
b = {3, 4, 5, 6, 7, 8}
print(a.union(b)); print(a | b)
#{1, 2, 3, 4, 5, 6, 7, 8}

print(a.intersection(b)); print(a & b)


#{3, 4, 5}

print(a.symmetric_difference(b)); print(a^b)
#{1, 2, 6, 7, 8}

print(a.symmetric_difference_update(b))
print(a)
#{1, 2, 6, 7, 8}

my_data1 = [1, 2, 3, 4]
my_data2 = [4, 5]
my_set = {tuple(my_data1), tuple(my_data2)}
print(my_set)
#{(4, 5), (1, 2, 3, 4)}
Prelucrari colectii
1) strings = ['a', 'as', 'bat', 'car', 'dove', 'python']

# Transformarea elementelor a caror lungime > 2 in litere mari


SINTAXA [expr for val in collection if condition]
print([x.upper() for x in strings if len(x) > 2])
rezultat = []
for i in strings:
if len(i) > 2:
rezultat.append(i.upper())
print(rezultat)

#['BAT', 'CAR', 'DOVE', 'PYTHON’]

# Afisare lungime elemente. SINTAXA set = {expr for value in collection if condition}
unique_lengths = {len(x) for x in strings}
print(unique_lengths)
#{1, 2, 3, 4, 6}

# Afisare nume in care litera a apare de cel putin 2 ori #nested lists
nume = [['John', 'Emily', 'Michael', 'Mary', 'Steven'],['Maria', 'Juan', 'Javier',
'Natalia', 'Pilar']]
result = [name for names in nume for name in names if name.count('a') >= 2]
print(result)
#['Maria', 'Natalia’]
OPERATORI ARITMETICI, ATRIBUIRE,
COMPARATIE
Operator Denumire Exemplu
+ Adunare x+y Operator Exemplu Echivalent
- Scădere x-y
= x=5 x=5
* Înmulțire x*y
+= x += 3 x=x+3
/ Împărțire x/y
% Restul împărțirii x%y -= x -= 3 x=x-3
** Exponențial x ** y *= x *= 3 x=x*3
// Partea întreagă a x // y /= x /= 3 x=x/3
împărțirii %= x %= 3 x=x%3
Operator Denumire Exemplu //= x //= 3 x = x // 3
== Egal x == y **= x **= 3 x = x ** 3
!= Diferit x != y
> Mai mare x>y
< Mai mic x<y
>= Mai mare sau egal x >= y
<= Mai mic sau egal x <= y
OPERATORI LOGICI, IDENTITATE,
APARTENENTA
Operator Descriere Exemplu
and Returnează True dacă ambele expresii sunt adevărate x < 5 and x < 10
or Returnează True dacă cel puțin o expresie este adevărată x < 5 or x < 4
not Negația, inversează rezultatul returnând False dacă rezultatul este not(x < 5 and x < 10)
adevărat

Operator Descriere Exemplu


is Returnează True dacă ambele variabile sunt același obiect x is y
is not Returnează True dacă ambele variabile nu sunt același obiect x is not y

Operator Descriere Exemplu


in Returnează True dacă o secvență cu o valoare specificată este x in y
prezentă în obiect
not in Returnează True dacă o secvență cu o valoare specificată nu este x not in y
prezentă în obiect
FUNCTII
def my_function(x, y, z=1.5):
if z > 1:
return z * (x + y)
else:
return z / (x + y)
print(my_function(1,2,3))
#9
print(my_function(1,2))
#4.5
print(my_function(z=5, y=6, x=7))
#65
print(my_function(y=6, x=5, z=7))
#77
print(my_function(y=6, x=7))
#19.5
import re
states = [' Alabama ', 'Georgia!',
'Georgia', 'georgia', 'FlOrIda','south def my_f(x):
carolina## ', 'West virginia?’] return x * 2
print(my_f(5))
def clean_strings(strings):
result = [] /
for value in strings: echivalent = lambda x: x * 2
value = value.strip()
value = re.sub('[!#?%*]', '',
print(echivalent(5))
value)
value = value.title()
result.append(value)
return result strings = ['curs', 'seminar', 'abba',
'mere', 'pachete',' ' , 'software']
print(clean_strings(states)) strings.sort(key=lambda x: len(x))
#['Alabama', 'Georgia', 'Georgia', print(strings)
'Georgia', 'Florida', 'South Carolina',
'West Virginia']
STRUCTURA ALTERNATIVA (IF)
x= 10

if x < 0:
print('It is negative')
elif x == 0:
print('Equal to zero')
elif 0 < x < 5:
print('Positive but smaller than 5')
else:
print('Positive and larger than or equal to 5')
STRUCTURI REPETITIVE (FOR)
sequence = [1, 2, None, 4, None, 5]
total = 0
for value in sequence:
if value is None:
continue
total += value
print(total)

sequence = [1, 2, 0, 4, 6, 5, 2, 1]
total_until_5 = 0
for value in sequence:
if value == 5:
break
total_until_5 += value
print(total_until_5)

for i in range(4):
for j in range(4):
if j > i:
break
print((i, j))
STRUCTURI REPETITIVE (WHILE)
i = 1
while i < 6:
print(i)
if i == 3:
break
i += 1

i = 0
while i < 6:
i += 1
if i == 3:
continue
print(i)
ACCESARE DATE DIN FISIERE (I)
Fișiere: .txt, .csv, .xlsx, .json, .sas7bdat

Fișiere text

Funcția open() returnează un obiect de tip fișier. f = open("C:\Data1.txt")


Metoda read() citește conținutul fișierului. print(f.read())
Funcția open()care doi parametri: numele fișierului sau calea și modul în care poate fi accesat:
"r" - Read - implicit. Deschide fișierul pentru citire, apare eroare dacă fișierul nu există.
"a" - Append - Deschide fișierul pentru adăugare, creează fișierul dacă nu există.
"w" - Write - Deschide fișierul pentru scriere, creează fișierul dacă nu există.
"x" - Create - creează fișierul, apare eroare dacă fișierul există.
Suplimentar, se pot specifica:
"t" - Text - Implicit. Modul text
"b" - Binary - Modul binar (de ex. imagine)

•Metoda readline()citește o singură linie


•Poate fi specificat numărul de caractere afișate: read(100)
ACCESARE DATE DIN FISIERE (II)
Fișiere comma separated values (.csv)

- In colecții de tip lista

import csv
with open('clienti_leasing.csv', 'r') as f:
reader = csv.reader(f)
for row in reader:
print (row)
print (row[0])
- In DataFrame de tip Pandas
import pandas as pd
df = pd.read_csv('clienti_leasing.csv')
print(df)

Fișiere SAS (.sas7bdat)


df = pd.read_sas('sas_data.sas7bdat')
ACCESARE DATE DIN FISIERE (III)
Fișiere .xlsx

from xlrd import open_workbook


book =
open_workbook('simple.xlsx',on_demand=True) import pandas as pd
for name in book.sheet_names(): df = pd.read_excel(io="simple.xlsx",
sheet = book.sheet_by_name(name) sheet_name="Sheet_names")
for cell in sheet.col(0): print(df.head(5))
print (cell.value)

from openpyxl import load_workbook


wb = load_workbook('simple.xlsx')
print (wb.get_sheet_names())

worksheet1 = wb['Sheet_names'] # prima varianta de deschidere a unui worksheet


#worksheet2 = wb.get_sheet_by_name('Sheet_names') # a doua varianta
print(worksheet1['A4'].value)
worksheet1['A4'] = 'Corina'
print(worksheet1['A4'].value)
for row in worksheet1.iter_rows():
print(row[1].value)
ACCESARE DATE DIN FISIERE (IV)
Prelucrarea fișierelor .json. Implicit acestea sunt încărcate în colecții de tip dicționar
import json
from pprint import pprint
with open ('clienti_daune.json') as f:
data=json.load(f)
pprint(data)

import json
from pprint import pprint
json_data=open('clienti_daune.json').read()
data = json.loads(json_data)
pprint(data)

import json
import pandas as pd
with open("clienti_daune.json") as f:
data = json.load(f)
dataframe = pd.DataFrame(data)
print(dataframe)
FUNCTII
Functii predefinite:
range(), tuple(), list(), set(), dict(), zip(), int(), str(),
complex(), float(), filter(), map(), input(), max(), min(),
sum(), open(), round(), type() etc.
Functii definite de utilizator:
def nume_functie(lista parametri):
“documentation string of the function or docstring - descrie
functia”
[return …]
#definire functie suma
def suma(*nr):
"functie cu numar variabil de parametri"
return sum(nr)
#apel
print(suma(1,2,3))
Functii anonime: lambda [param1 [,param2,.....paramn]]: expresie
Exemple functii (I)
def my_function(x): def my_function(x = def my_function(x,
result = x**2 100): n):
print (result) result = x**2 result = x**n
return result print (result) print (result)
my_function() return result return result
TypeError: my_function() my_function(5) my_function(4,2)
missing 1 required my_function(n=2,x=4)
positional argument: 'x'

FUNCTII
Exemple functii (II)
def plus(*nr): def plus(*args): double = lambda x: x*2
return sum(nr) total = 0 double(5)
for i in args:
total += i suma = lambda x, y: x + y;
print(plus(1, 2, 5, 5, 6, return total print(suma(1,2))
8))
print(plus(1,2,5,5,6,8)) my_list = [1,2,3,4,5,6,7,8,9,10]
tuplu = (1, 2, 5, 5, 6, 8) filtered_list = list(filter(lambda x: (x*2 > 10),
print(sum(tuplu)) my_list))

#[6, 7, 8, 9, 10]

FUNCTII
import pandas as pd
import matplotlib.pyplot as plt
pd.set_option("display.max_columns", 20)
df = pd.read_csv('clienti_leasing.csv')
df.boxplot(column = 'AGE', by = 'MARITAL_STATUS')
plt.show()
def discount(df, p_disc, p_age):
df['DISCOUNT']=df.loc[(df['AGE']>p_age),'VENIT_PER_YEAR']*p_disc
return df
print(discount(df,0.1,30))

FUNCTII
import pandas as pd
pd.set_option("display.max_columns",50)
pd.set_option("display.max_rows",100)

def calcul(den_f):
df = pd.read_csv(den_f)
print(df['value'].sum())
df['payment'] = 0.75*df['value']*1.05
df.loc[(df['hour'] >= 16)&(df['hour'] <23),
'payment'] = df['value']*1.25*0.95
df.sort_values(by=['day'])
print('Payment with ToU tariff')
print(df['payment'].sum())
print('Payment with flat tariff')
print(df['value'].sum())
procent = 100-
df['value'].sum()*100/df['payment'].sum()
print (procent)
print(df)

calcul(den_f='februarie_2010.csv')
BIBLIOGRAFIE

• Python for Data Analysis, DATA WRANGLING WITH PANDAS, NUMPY, AND IPYTHON,
Wes McKinney, 2nd edition, 2012, Ed. O’REILLY
• Data Science from Scratch, FIRST PRINCIPLES WITH PYTHON, Joel Grus, 2015, Ed. O’REILLY
• Python Data Science Handbook, ESSENTIAL TOOLS FOR WORKING WITH DATA, Jake
VanderPlas, 2016, Ed. O’REILLY
• Fundamentals of Python®: Data Structures, Kenneth A. Lambert, Cengage Learning PTR, 2014
PYTHON

PYTHON 2
ACCESARE DATE DIN FISIERE (I)
Fișiere: .txt, .csv, xlsx, .json
f = open("C:/Data1.txt")
Fișiere text print(f.read())

Funcția open() returnează un obiect de tip fișier.


Metoda read() citește conținutul fișierului.

Funcția open()care doi parametri: numele fișierului sau calea și modul în care poate fi accesat:
"r" - Read - implicit. Deschide fișierul pentru citire, apare eroare dacă fișierul nu există.
"a" - Append - Deschide fișierul pentru adăugare, creează fișierul dacă nu există.
"w" - Write - Deschide fișierul pentru scriere, creează fișierul dacă nu există.
"x" - Create - creează fișierul, apare eroare dacă fișierul există.
Suplimentar, se pot specifica:
"t" - Text - Implicit. Modul text
"b" - Binary - Modul binar (de ex. imagine)

•Metoda readline()citește o singură linie


•Poate fi specificat numărul de caractere afișate: read(100)
ACCESARE DATE DIN FISIERE (II)
Fișiere comma separated values

import csv
with open('clienti_leasing.csv', 'r') as f:
reader = csv.reader(f)
for row in reader:
print (row)

import pandas as pd
df = pd.read_csv('clienti_leasing.csv')
print(df)
ACCESARE DATE DIN FISIERE (III)
Fișiere .xlsx

from xlrd import open_workbook


book =
open_workbook('simple.xlsx',on_demand=True) import pandas as pd
for name in book.sheet_names(): df = pd.read_excel(io="simple.xlsx",
sheet = book.sheet_by_name(name) sheet_name="Sheet_names")
for cell in sheet.col(0): print(df.head(5))
print (cell.value)

from openpyxl import load_workbook


wb = load_workbook('simple.xlsx')
print (wb.get_sheet_names())

worksheet1 = wb['Sheet_names'] # one way to load a worksheet


#worksheet2 = wb.get_sheet_by_name('Sheet_names') # another way to load a worksheet
print(worksheet1['A4'].value)
worksheet1['A4'] = 'Corina'
print(worksheet1['A4'].value)
for row in worksheet1.iter_rows():
print(row[1].value)
ACCESARE DATE DIN FISIERE (IV)
Fișiere .json
import json
from pprint import pprint
with open ('clienti_daune.json') as f:
data=json.load(f)
pprint(data)

import json
from pprint import pprint
json_data=open('clienti_daune.json').read()
data = json.loads(json_data)
pprint(data)

import json
import pandas as pd
with open("clienti_daune.json") as f:
data = json.load(f)
dataframe = pd.DataFrame(data)
print(dataframe)
NUMPY
• NumPy prescurtarea pentru Numerical Python sau calcule numerice Python.
• NumPy contine:
- Tipul de obiect multidimensional ndarray (n-dimensional array)
- Functii pentru calcule cu vectori sau operatii matematice cu vectori
- Instrumente pentru citirea si scrierea seturilor de date bazate pe vectori
- operatii din algebra liniara, transformata Fourier si generare de numere
aleatoare
- API pentru C sau C++
MATPLOTLIB & SCIPY
• Matplotlib este cea mai populara biblioteca Python pentru realizarea reprezentarilor grafice
• SciPy reprezinta o colectie de pachete pentru rezolvarea unor probleme standard din diferite
domenii
- scipy.integrate: Ofera rutine pentru integrare numerica si calculul ecuatiilor
diferentiale;
- scipy.linalg: Rutine din algebra relationala, prelucrarea avansata matricelor, fiind
superior pachetului numpy.linalg;
- scipy.optimize. Functii de optimizare (minimizare) si algoritmi de identificare a
drumului critic;
- scipy.signal. Instrumente de procesare a semnalului;
- scipy.sparse. Calcule cu matrice si sisteme de ecuatii liniare (sparse);
- scipy.special. O biblioteca Fortran pentru implementarea celor mai populare functii
matematice, cum ar fi functia gamma;
- scipy.stats. Distributii de probabilitati, teste statistice, statistici descriptive.
SCIKIT-LEARN
• Instrumente pentru machine learning in Python, ce includ submodule pentru diverse modele:
• Clasificare: SVM, nearest neighbors, random forest, logistic regression etc.
• Regresia: Lasso, ridge regression etc.
• Clustering: k-means, spectral clustering etc.
• Reducerea dimensionalitatii (Dimensionality reduction): PCA (Principal Component Analysis),
feature selection, matrix factorization etc.
• Selectie model: GridSearch, cross-validation, metrics
• Preprocesare: Feature extraction, feature engineering, scalare, normalizare
STATSMODELS
• In comparatie cu scikit-learn, statsmodels continue algoritmi clasici din statistica si
econometrie. Include submodule, cum ar fi:
• Regresie: liniara, modele liniare generalizate , modele liniare robuste, linear mixed effects
models etc.
• ANOVA
• Analize pe serii de timp: AR, ARMA, ARIMA, VAR etc.
• Nonparametric methods: Kernel density estimation, kernel regression
• Rezultatele analizelor realizate cu statsmodels sunt axate pe indicatori statistici, p-values,
in timp ce rezultatele analizelor efectuate cu scikit-learn, se axeaza mai mult pe predictii.
PACHETUL PANDAS (I)
Contine structuri de date (Dataframe), orientate pe coloane, si instrumente pentru
manipularea datelor, proiectate pentru a realiza mai rapid si mai usor curatarea si
analiza datelor in Python;

Dataframe = container de vectori unidimensionali (Series);

Se utilizeaza deseori in tandem cu alte pachete de calcul numeric, cum ar fi NumPy


and SciPy, biblioteci analitice, cum ar fi statsmodels si scikit-learn, si instrumente
pentru vizualizarea datelor, cum ar fi matplotlib.
Pandas adaopta stilul de calcul bazat pe vectori,
in special functii pe vectori, specific NumPy,
precum si procesarea datelor in stil pythonian,
fara a utiliza structuri repetitive;

Care este cea mai mare diferenta dintre Pandas


si NumPy? Pandas lucreaza cu date tabelare,
heterogene, in timp ce NumPy este adecvat
pentru vectori de date numerice, omogene;
PACHETUL
PANDAS (II)
Pandas imbina posibilitatile specifice NumPy
de calcul la nivelul vectorilor cu manipularea
flexibila a datelor din spreadsheet-uri si baze
de date relationale, oferind functionalitati
sofisticate de indexare, care permit
rearanjarea, felierea, sectionarea, agregarea si
selectarea subseturilor de date.
Sursa: https://www.shanelynn.ie/select-pandas-dataframe-rows-and-columns-using-iloc-loc-and-ix/#iloc-selection
ILOC
• iloc integer-location based indexing: selecteaza linii si coloane dupa index/pozitie
• Sintaxa: data.iloc[<row selection>, <column selection>]
# Selectie singulara cu iloc
# Inregistrari:
data.iloc[0] # prima inregistrare
data.iloc[1] # a doua inregistrare
data.iloc[-1] # ultima inregistrare a setului de date
# Coloane:
data.iloc[:,0] # prima coloana
data.iloc[:,1] # a doua coloana
data.iloc[:,-1] # ultima coloana a setului de date

# Selectie multipla cu iloc


data.iloc[0:5] # primele cinci inregistrari
data.iloc[:, 0:2] # primele doua coloane
data.iloc[[0,3,6,24], [0,5,6]] # inregistrarile 1, 4, 7, 25, coloanele 1, 6 si 7
data.iloc[0:5, 5:8] # primele cinci inregistrari si coloanele 5, 6 si 7).
DATAFRAME SI SERIES
import pandas as pd

#setul de date de test poate fi gasit aici https://www.briandunning.com/sample-data/


si contine date fictive
data = pd.read_csv('https://s3-eu-west-1.amazonaws.com/shanebucket/downloads/uk-
500.csv’)

data.to_csv("output.csv")

print (type(data.head(5)))
print (type(data.iloc[:,1]))
LOC (I)
• loc : selecteaza linii si coloane dupa denumirea liniilor/colonelor
• Sintaxa: data.loc[<row selection>, <column selection>]
import pandas as pd
data = pd.read_csv('https://s3-eu-west-1.amazonaws.com/shanebucket/downloads/uk-500.csv')
#fixarea indexului pe coloana first_name
data.set_index("first_name", inplace=True)
#selectarea inregistrarilor, fiind afisata doar inregistrarile corespunzatoare
print(data.loc["Antonio"])
print(data.loc[["Antonio", "Peter"]])
import pandas as pd
data = pd.read_csv('https://s3-eu-west-1.amazonaws.com/shanebucket/downloads/uk-500.csv')
#fixarea indexului pe coloana first_name
data.set_index("first_name", inplace=True)
#selectarea coloanelor, implicit first_name este afisata
print(data.loc[["Antonio", "Peter"],['last_name', 'address', 'city']])
import pandas as pd
data = pd.read_csv('https://s3-eu-west-1.amazonaws.com/shanebucket/downloads/uk-500.csv')
#fixarea indexului pe coloana first_name
data.set_index("last_name", inplace=True)
print(data.loc[['Andrade', 'Veness'], 'city':'email'])
print(data.loc['Andrade':'Veness', ['first_name', 'address', 'city']])
LOC (II)
import pandas as pd
data = pd.read_csv('https://s3-eu-west-1.amazonaws.com/shanebucket/downloads/uk-500.csv')
print(data.loc[data['first_name'] == 'Antonio'])

import pandas as pd
data = pd.read_csv('https://s3-eu-west-1.amazonaws.com/shanebucket/downloads/uk-500.csv')

print(data.loc[data['first_name'] == 'Antonio', 'city':'email'])

print(data.loc[data['email'].str.endswith("hotmail.com"), 'phone1':'email'])

print(data.loc[data['first_name'].isin(['France', 'Tyisha', 'Eric'])])

print(data.loc[data['email'].str.endswith("gmail.com") & (data['first_name'] ==


'Antonio'), 'first_name':'email'])

print(data.loc[data['company_name'].apply(lambda x: len(x.split(' ')) == 1),


'company_name'])
SELECTAREA COLOANELOR
import pandas as pd • Pot fi utilizate trei metode pentru selectarea coloanelor:
df = pd.read_csv('clienti_leasing.csv')
#variante echivalente pentru selectarea – df.nume_coloana
coloanelor
print(df.SEX) – df['nume_coloana’]
print(df["SEX"]) – df.iloc[:, index_coloana]
print(df.iloc[:,3])
• Cand se selecteaza o coloana, rezulta un vector de date unidimensional
pandas.Series cu care se pot realiza mai multe operatii de:
print(df.DEPOSIT_AMOUNT.mean())
(.sum()), (.mean()), (.count()), (.median()), inlocuire valori nule
(.fillna(new_value)).
import pandas as pd
df = pd.read_csv('clienti_leasing.csv') • Prin selectarea mai multor coloane se defineste un nou set de date. Sintaxa
print(df[['SEX', 'DEPOSIT_AMOUNT']]) pentru selectarea multipla a coloanelor este:
#printeaza coloanele SEX, AGE si
DEPOSIT_AMOUNT – df[['nume_coloana_1', 'nume_coloana_2']]
print(df.iloc[:, [3,10,14]])
– df.iloc[:, [0,1,20,22]]
SELECTAREA INREGISTRARILOR

• Se poate realiza selectarea prin metodele iloc/loc sau


prin selectori logici (selectare bazata pe valoarea unei
import pandas as pd coloane sau variabile).
df =
• Metodele de baza pentru selectarea inregistrarilor sunt:
pd.read_csv('clienti_leasing.csv')
print(df.iloc[0:10, :]) – df.iloc[0:10, :], selecteaza primele 10 inregistrari;
print(df.loc[44, :])
print(df.loc[[2, 44], :]) – df.loc[44, :], selecteaza inregistrarea 44
print(df[df["SEX"] == "m"]) – df[df[“SEX"] == “m"], selecteaza inregistrarile care
indeplinesc conditia.
ACTUALIZAREA VALORILOR DIN SETUL DE DATE
import pandas
df = pandas.read_csv('clienti_leasing20.csv', nrows=6, usecols = ['NAME
CLIENT','VENIT_PER_YEAR'])
print(df)
df.loc[1,'VENIT_PER_YEAR'] = 1500
print(df.loc[1,'VENIT_PER_YEAR'])
print(df)

import pandas as pd
data = pd.read_csv('clienti_leasing.csv')

data.loc[data['VENIT_PER_YEAR'] > 10000, "PRESCORING"] = 7

print(data.loc[data['PRESCORING'] == 7,'NAME_CLIENT'])

data.loc[(data['VENIT_PER_YEAR'] > 10000) & (data['SEX'] == 'm'), "PRESCORING"] = 8


STERGEREA COLOANELOR (DROP)
• Stergerea inregistrarilor sau a coloanelor dintr-un set de date se realizeaza prin functia drop.
• Pentru stergerea unei coloane sau a mai multor coloane, se utilizeaza numele coloanelor
specificand axis=I sau se utilizeaza parametrul ‘columns’ (nemaifiind necesar ‘axis’).
– Stergerea coloanei "Area" din set:
df = df.drop("Area", axis=1)
– Stergerea coloanei cu parametrul ‘columns’:
df = df.drop(columns=“Area")
• Stergerea unei coloane duce la crearea unui alt set de date. Pentru a modifica setul original
(curent), se utilizeaza parametrul inplace = True, nefiind returnata nicio valoare.
df.drop("Area", axis=1, inplace=True).
• Stergerea multipla a coloanelor
data = data.drop(["Y2001", "Y2002", "Y2003"], axis=1)
STERGEREA INREGISTRARILOR (DROP)
• Inregistrarile pot fi sterse utilizand functia drop si specificand axis=0.
import pandas as pd
df = pd.read_csv('clienti_leasing20.csv')
df.drop([1,2], axis = 0, inplace=True)
print(df)

• Drop() poate sterge inregistrarile pe baza unor expresii. Stergerea inregistrarilor care contin “ROL“.
In cazul stergerii bazate pe expresii, se va seta mai intai coloana indexata (CURRENCY) :
import pandas as pd
df = pd.read_csv('clienti_leasing20.csv')
df = df.set_index("CURRENCY")
df = df.drop("ROL", axis=0)
print(df)
• Pentru a sterge inregistrarile in functie de pozitia sau indexul acestora, se utilizeaza iloc. Stergerea
primelor cinci inregistrari utilizand iloc
import pandas as pd
df = pd.read_csv('clienti_leasing20.csv')
df = df.iloc[5:,].drop
print(df)
REDENUMIREA COLOANELOR (RENAME)
• Redenumirea coloanelor in pandas se realizeaza in doua moduri prin intermediul functiei rename.
• Redenumirea prin maparea denumilor vechi cu denumirile noi, astfel {“denumire_veche”:
“denumire_noua”, …}
import pandas as pd
df = pd.read_csv('clienti_leasing20.csv')
df.rename(columns={"ID_CLIENT": "COD"}, inplace=True)
print(df)

import pandas as pd
df = pd.read_csv('clienti_leasing20.csv')
df.rename(columns={"ID_CLIENT": "COD","AGE": "VARSTA"}, inplace=True)
print(df)
• Redenumirea printr-o functie care sa schimbe denumirile coloanelor si care se aplica pentru fiecare
coloana.
import pandas as pd
df = pd.read_csv('clienti_leasing20.csv')
df = df.rename(columns=str.lower)
#df = df.rename(columns=lambda x: x.lower().replace(' ', '_'))
print(df)
FUNCTII SERIES
import pandas as pd
df =
pd.read_csv('clienti_leasing.csv',usecols=['NAME_CLIENT','JOB','SEX','DEPOSIT
_AMOUNT','AGE’])

print('Suma depozitelor ', df['DEPOSIT_AMOUNT'].sum(), '\nMedia depozitelor',


df['DEPOSIT_AMOUNT'].mean())

print('Valoarea mediana ', df['DEPOSIT_AMOUNT'].median())

print('Valori unice ', df['DEPOSIT_AMOUNT'].nunique())

print('Venitul maxim ', df['DEPOSIT_AMOUNT'].max())

print('Numar observatii ', df['DEPOSIT_AMOUNT'].count())


FILLNA

import pandas as pd
df =
pd.read_csv('clienti_leasing20.csv',usecols=['NAME_CLIENT','JOB','SEX','VENIT_PER_YEA
R'])
print(df['VENIT_PER_YEAR'])
print(df['VENIT_PER_YEAR'].fillna(0))

import pandas as pd
df =
pd.read_csv('clienti_leasing20.csv',usecols=['NAME_CLIENT','JOB','SEX','VENIT_PER_YEA
R'])
print(df['VENIT_PER_YEAR'])
values = df['VENIT_PER_YEAR'].mean()
print(df['VENIT_PER_YEAR'].fillna(value=values))
PRELUCRARE DATE TRADITIONAL VS. PANDAS
from pprint import pprint
import pandas as pd
df = pd.read_csv('clienti_daune.csv')
set_clienti=[]
for index, row in df.iterrows():
if row['VALOARE_DAUNA'] > 1000:
set_clienti.append(row)
pprint (set_clienti)
v_marca = input("Introduceti marca: ");
print ("Marca selectata este : ", v_marca)
total_daune=0
for row in set_clienti:
if str(row['MARCA']).find(v_marca.upper())!=-1:
total_daune=total_daune+row['VALOARE_DAUNA']
print ("Valoarea totala a daunelor pentru marca", v_marca, " este: ", total_daune)
/
print ("Valoarea totala a daunelor pentru marca", v_marca, " este: ",
df['VALOARE_DAUNA'][(df['MARCA'] == v_marca) & (df['VALOARE_DAUNA'] >1000)].sum())
EXPORTUL (SALVAREA) SETURILOR PANDAS
• Functia to_csv pentru a salva un set de date intr-un fisier .csv
• Functia to_excel pentru a salva un set de date intr-un fisier Microsoft Excel
• Salvarea prelucrarilor intr-un fisier .csv
• Eliminarea indexului implicit Pandas la nivelul inregistrarilor, se realizeaza cu optiunea index=False.
• Pentru a evita probleme de afisare a caracterelor, se poate utiliza optiunea encoding.
data.to_csv("output_filename.csv", index=False, encoding='utf8’)
• Salvarea prelucrarilor intr-un fisier Excel necesita instalarea pachetului “openpyxl” sau "xlsxwriter".
data.to_excel("output_excel_file.xlsx", sheet_name="Sheet 1", index=False)
TO_CSV
from pprint import pprint
import pandas as pd
df = pd.read_csv('clienti_daune.csv')
set_clienti=[]
for index, row in df.iterrows():
if row['VALOARE_DAUNA'] > 2000:
set_clienti.append(row['ID_CLIENT'])
pprint (set_clienti)
df = pd.DataFrame(set_clienti)
df.to_csv("output_clienti.csv")
/
df=df.loc[df['VALOARE_DAUNA']>2000,'ID_CLIENT']
print(df)
df.to_csv("output_clienti.csv")
PRELUCRARE DATE PANDAS (I)
from pprint import pprint
import pandas as pd
df = pd.read_csv('clienti_daune.csv')

pprint (df.loc[(df['AN_FABRICATIE'] < 2010) & (df['COMPONENTA'] =='BATTERY'), 'PRET_MANOPERA'])

df.loc[(df['AN_FABRICATIE'] < 2010) & (df['COMPONENTA'] =='BATTERY'), 'PRET_MANOPERA']=


df.loc[(df['AN_FABRICATIE'] < 2010) & (df['COMPONENTA'] =='BATTERY'), 'PRET_MANOPERA']*1.10

pprint(df.loc[(df['AN_FABRICATIE'] < 2010) & (df['COMPONENTA'] =='BATTERY'), 'PRET_MANOPERA'])

df.to_csv('clienti_daune_mod.csv')

from pprint import pprint


import pandas as pd
df = pd.read_csv('clienti_daune.csv’)

#crearea unei coloane PROCENT_MANOPERA


df['PROCENT_MANOPERA’] = df['PRET_MANOPERA'] / df['VALOARE_DAUNA']*100
pprint (df)

df.to_csv('clienti_daune_mod.csv')
PRELUCRARE DATE PANDAS (II)
import pandas as pd

df = pd.read_csv('clienti_leasing20.csv’)

df['coloana_noua'] = pd.Series()

df.loc[df['JOB']=='Inginer','coloana_noua']=df['VENIT_PER_YEAR']*0.1

df.loc[df['JOB']=='Profesor','coloana_noua']=df['VENIT_PER_YEAR']*0.15

df.loc[(df['JOB']!='Profesor')&(df['JOB']!='Inginer'),'coloana_noua’]=0

print(df)
RECAPITULARE
• Care este diferenta majora dintre Pandas si NumPy?
• Cum sunt stocate datele in Pandas, dar in Numpy?
• Ce rol au loc si iloc? Prin ce difera?
• Cum se realizeaza actualizarea unei valori in Pandas, dar stergerea?
• Ce functie utilizam pentru salvarea seturilor de date in fisiere csv?
• Ce rol are inplace = True?
• Cum putem trata valorile lipsa (NULL)?
• Enumerati cateva functii care pot fi utilizate pe seriile Pandas Python?
• Ce putem face cu pachetul Matplotlib?
SURSE BIBLIOGRAFICE
• https://pandas.pydata.org/pandas-docs/version/0.21/comparison_with_sql.html
• https://www.shanelynn.ie/python-pandas-read_csv-load-data-from-csv-files/
• https://www.shanelynn.ie/select-pandas-dataframe-rows-and-columns-using-iloc-loc-and-ix/
• https://pandas.pydata.org/pandas-docs/version/0.21/api.html#id2
• https://matplotlib.org/gallery/index.html
• https://www.datascience.com/blog/k-means-clustering
• Python for Data Analysis, DATA WRANGLING WITH PANDAS, NUMPY, AND IPYTHON,
Wes McKinney, 2nd edition, 2012, Ed. O’REILLY
• Data Science from Scratch, FIRST PRINCIPLES WITH PYTHON, Joel Grus, 2015, Ed. O’REILLY
• Python Data Science Handbook, ESSENTIAL TOOLS FOR WORKING WITH DATA, Jake
VanderPlas, 2016, Ed. O’REILLY
PYTHON

PYTHON 3
CONTINUT

• Gruparea si agregarea datelor


• Combinarea seturilor de date (CONCAT, MERGE)
• Prelucrarea datelor prin grupare si combinare, reprezentari grafice
GRUPAREA SI AGREGAREA DATELOR (I)
Prelucrări statistice simple
import pandas as pd
df = pd.read_csv('clienti_leasing.csv')
pd.set_option("display.max_columns",30)
print(df.head(5))

print('Numarul de clienti')
print(df['ID_CLIENT'].count())
print('Venit maxim')
print(df['VENIT_PER_YEAR'].max())

print('Suma venitului maxim pentru persoanele de sex masculin')


print(df['VENIT_PER_YEAR'][df['SEX'] == 'm'].sum())

print('Numarul valorilor distincte din coloana starea civila')


print(df['MARITAL_STATUS'].value_counts())
print('Numarul total de valori distincte din coloana starea civila')
print(df['MARITAL_STATUS'].nunique())
--alte functii: df[“nume_coloana”].nlargest() sau nsmallest()
GRUPAREA SI AGREGAREA DATELOR (II)
Statistici descriptive
count 18239
unique 126
top Muncitor necalificat
import pandas as pd
freq 5086
df = pd.read_csv('clienti_leasing.csv')
Name: JOB, dtype: object
pd.set_option("display.max_columns",30)
---------------------------------------------
print('Statistici descriptive')
count 18239.000000
mean 8344.006629
print(df['JOB'].describe())
std 11234.428174
print(df['VENIT_PER_YEAR'].describe())
min 0.070000
25% 2500.000000
50% 5000.000000
75% 10000.000000
max 408560.000000
Name:VENIT_PER_YEAR, dtype: float64
GRUPAREA SI AGREGAREA DATELOR (III)
Funcțiile max(), min(), mean(), first(), last() pot fi utilizate cu GroupBy
import pandas as pd
df = pd.read_csv('clienti_leasing.csv')
pd.set_option("display.max_columns",30)
df['DATA'] = pd.to_datetime(df['DATA'])
df['MONTH'] = pd.DatetimeIndex(df['DATA']).month

print('Prima inregistrare din coloana CURRENCY pe valori distincte')


print(df.groupby('CURRENCY').first())

print('Venitul anual insumat pentru fiecare luna')


print(df.groupby(pd.DatetimeIndex(df['DATA']).month)['VENIT_PER_YEAR'].sum())

print('Valoarea insumata a depozitului pentru ingineri pe sexe')


print(df[df['JOB'] == 'Inginer'].groupby('SEX')['VENIT_PER_YEAR'].sum())
GRUPAREA Grupări complexe
SI import pandas as pd
AGREGAREA df = pd.read_csv('clienti_daune.csv')
pd.options.display.max_rows = 999
D AT E LO R
(IV) print('Numarul de marci pentru fiecare
tara producatoare’)

print(df.groupby(['TARAPRODUCATOR',
'MARCA'])['MARCA'].count())
GRUPAREA SI AGREGAREA DATELOR (V)

Gruparea și agregarea datelor


import pandas as pd
df = pd.read_csv('clienti_daune.csv')
pd.options.display.max_rows = 999

print(df.groupby(['TARAPRODUCATOR','MARCA']).agg({'VALOARE_DAUNA':sum,
'ID_CLIENT': "count", 'MODEL': 'first'}))

df1 = df.groupby(['TARAPRODUCATOR','MARCA']).agg({'VALOARE_DAUNA':sum,
'ID_CLIENT': "count", 'MODEL': 'first’})

df1.to_csv('agregare.csv')
GRUPAREA SI AGREGAREA DATELOR (VI)
Aplicarea unor funcții multiple unei singure coloane din grup
import pandas as pd
df = pd.read_csv('clienti_daune.csv’)

df['DATA_CERERE'] = pd.to_datetime(df['DATA_CERERE’])

print(df.groupby(['TARAPRODUCATOR', 'MARCA']).agg({'PRET_MANOPERA': [min,


max, sum], 'MODEL': "count", 'DATA_CERERE': [min, 'first', 'nunique']}))
GRUPAREA SI AGREGAREA DATELOR (VII)
import pandas as pd
pd.set_option('display.max_rows', None)
pd.set_option('display.max_columns', None)
df = pd.read_csv('clienti_daune.csv’)

print('Grupare dupa MARCA, pentru fiecare marca afisam nr de modele')


print(df.groupby("MARCA")['MODEL'].count())
print("========================================")
print('Grupare dupa MARCA, pentru fiecare marca afisam nr de modele unice')
print(df.groupby("MARCA")['MODEL'].nunique())
print("========================================")

print('Afisam primele 5 marci cu cele mai multe modele')


print(df.groupby(['MARCA'])['MODEL'].count().nlargest(5))
print("========================================")

print('Grupare dupa MARCA, pentru fiecare marca afisam toate modelele')


print(df.groupby(["MARCA"])['MODEL'].apply(lambda x: ','.join(x)))
print("========================================")
CONCAT, MERGE (I)
• Prelucrarea seturilor de date cu concat, merge / join dataframes
Concat – lipire seturi cu continut similar pe verticala sau pe orizontala
pd.concat([df_a, df_b])

pd.concat([df_a, df_b], axis=1)


CONCAT, MERGE (II)
import pandas as pd
pd.options.display.max_columns = 10
df = pd.read_csv('clienti_leasing.csv')
df1 = pd.read_csv('clienti_daune.csv’)

result = pd.merge(df[['ID_CLIENT','NUME_CLIENT', 'PROFESIA', 'SEX','VENIT_ANUAL',


'VARSTA']],
df1[['ID_CLIENT', 'MARCA', 'PRET_MANOPERA', 'VALOARE_DAUNA']],
on='ID_CLIENT’, how = ‘inner’)
print(result)
print('Structura fisier clienti_leasing.csv', df.shape)
print('Structura fisier clienti_daune.csv', df1.shape)
print(df['ID_CLIENT'].isin(df1['ID_CLIENT']).value_counts())
CONCAT, MERGE (IV)
Data analytics pe clienti si daune
import pandas as pd
df = pd.read_csv('clienti_leasing.csv')
df1 = pd.read_csv('clienti_daune.csv’)

result = pd.merge(df[['ID_CLIENT','NUME_CLIENT', 'PROFESIA', 'SEX','VENIT_ANUAL',


'VARSTA']],
df1[['ID_CLIENT', 'VIN','MARCA', 'PRET_MANOPERA', 'VALOARE_DAUNA']],
on='ID_CLIENT’)

print('Grupare dupa Id_client si Marca, calcul min, max, suma pentru Valoare_dauna si
numar daune (VIN)')
print(result.groupby(['ID_CLIENT', 'MARCA']).agg({'VALOARE_DAUNA': [min, max, sum],
'VIN': "count"}))
print('Afisam primele 5 marci cu cele mai multe daune')
print(result.groupby(['MARCA'])['VALOARE_DAUNA'].count().nlargest(5))
print(result.groupby(['MARCA'])['VALOARE_DAUNA'].size().nlargest(5))
print('Afisam primii 15 clienti cu cele mai multe daune')
print(result.groupby(['ID_CLIENT'])['VIN'].count().nlargest(15))
print('Afisam primii 15 clienti cu cea mai mare valoare totala a daunelor')
print(result.groupby(['ID_CLIENT'])['VALOARE_DAUNA'].sum().nlargest(15))
CONCAT, MERGE (V)
Left merge sau left join
import pandas as pd
pd.options.display.max_columns = 10

df = pd.read_csv('clienti_leasing.csv')
df1 = pd.read_csv('clienti_daune.csv’)

result = pd.merge(df[['ID_CLIENT','NUME_CLIENT', 'PROFESIA',


'SEX','VENIT_ANUAL', 'VARSTA']],
df1[['ID_CLIENT', 'MARCA', 'PRET_MANOPERA',
'VALOARE_DAUNA']],
on='ID_CLIENT',
how='left')
print(result)
print(result.shape)
print('Structura fisier clienti_leasing.csv', df.shape)
print('Structura fisier clienti_daune.csv', df1.shape)
print(df['ID_CLIENT'].isin(df1['ID_CLIENT']).value_counts())
CONCAT, MERGE (VI)
Right merge sau right join
import pandas as pd
pd.options.display.max_columns = 10
df = pd.read_csv('clienti_leasing.csv')
df1 = pd.read_csv('clienti_daune.csv’)

result = pd.merge(df[['ID_CLIENT','NUME_CLIENT', 'PROFESIA',


'SEX','VENIT_ANUAL', 'VARSTA']],
df1[['ID_CLIENT', 'MARCA', 'PRET_MANOPERA',
'VALOARE_DAUNA']],
on='ID_CLIENT',
how='right’)

print(result)
print(result.shape)
print('Structura fisier clienti_leasing.csv', df.shape)
print('Structura fisier clienti_daune.csv', df1.shape)
print(df['ID_CLIENT'].isin(df1['ID_CLIENT']).value_counts())
CONCAT, MERGE (VII)
Full outer merge sau full outer join
import pandas as pd
pd.options.display.max_columns = 10
df = pd.read_csv('clienti_leasing.csv')
df1 = pd.read_csv('clienti_daune.csv')

result = pd.merge(df[['ID_CLIENT','NUME_CLIENT', 'PROFESIA',


'SEX','VENIT_ANUAL', 'VARSTA']],
df1[['ID_CLIENT', 'MARCA', 'PRET_MANOPERA',
'VALOARE_DAUNA']],
on='ID_CLIENT',
how='outer’, indicator = True)

print(result)
print(result.shape)
print('Structura fisier clienti_leasing.csv', df.shape)
print('Structura fisier clienti_daune.csv', df1.shape)
print(df['ID_CLIENT'].isin(df1['ID_CLIENT']).value_counts())
CONCAT, MERGE (VIII)
Full outer merge sau full outer join cu indicația _merge
import pandas as pd
pd.options.display.max_columns = 10
df = pd.read_csv('clienti_leasing.csv')
df1 = pd.read_csv('clienti_daune.csv’)

result = pd.merge(df[['ID_CLIENT','NUME_CLIENT', 'PROFESIA',


'SEX','VENIT_ANUAL', 'VARSTA']],
df1[['ID_CLIENT', 'MARCA', 'PRET_MANOPERA',
'VALOARE_DAUNA']],
on='ID_CLIENT',
how='outer',
indicator=True)

print(result)
print(result.shape)
print('Structura fisier clienti_leasing.csv', df.shape)
print('Structura fisier clienti_daune.csv', df1.shape)
print(df['ID_CLIENT'].isin(df1['ID_CLIENT']).value_counts())
CONCAT, MERGE (IX)
Merge utilizând trei seturi de date
import pandas as pd
df = pd.read_csv('clienti_leasing.csv')
df1 = pd.read_csv('clienti_daune.csv')
df2 = pd.read_csv('cars.csv’)

result = pd.merge(df[['ID_CLIENT','NUME_CLIENT', 'PROFESIA',


'SEX','VENIT_ANUAL', 'VARSTA']],
df1[['ID_CLIENT', 'MARCA', 'PRET_MANOPERA',
'VALOARE_DAUNA']],
on='ID_CLIENT',
how='outer’)

result = pd.merge(result[['ID_CLIENT','NUME_CLIENT', 'MARCA']],


df2,
left_on='MARCA',
right_on='MARCA_CARS',
how='left')
MATPLOTLIB (I)
Grafic cu gruparea și sortarea datelor cu matplotlib.pyplot
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('clienti_leasing.csv')
plot_data=df[df['SEX']=='m']
plot_data=plot_data.groupby('PROFESIA')['VENIT_ANUAL'].sum()
plot_data.sort_values().plot(kind='bar', color = 'lightpink')
plt.show()
MATPLOTLIB (II)
Reprezentare grafică cu bare cu matplotlib.pyplot
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import cm
pd.set_option("display.max_columns",10)
df = pd.read_csv('clienti_leasing20.csv')
print(df['AGE'])
#all_colors = list(plt.cm.colors.cnames.keys())
colors = cm.hsv( df['AGE']/ float(max(df['AGE'])))
df['AGE'].plot(kind=‘bar',color=colors)
plt.xlabel('ID_CLIENT')
plt.ylabel('AGE')
plt.show()
SURSE BIBLIOGRAFICE

• https://matplotlib.org/index.html
• https://www.shanelynn.ie/summarising-aggregation-and-grouping-data-in-python-pandas/
• https://www.shanelynn.ie/merge-join-dataframes-python-pandas-index-1/
• Python for Data Analysis, DATA WRANGLING WITH PANDAS, NUMPY, AND IPYTHON,
Wes McKinney, 2nd edition, 2012, Ed. O’REILLY
• Data Science from Scratch, FIRST PRINCIPLES WITH PYTHON, Joel Grus, 2015, Ed. O’REILLY
• Python Data Science Handbook, ESSENTIAL TOOLS FOR WORKING WITH DATA, Jake
VanderPlas, 2016, Ed. O’REILLY
PYTHON
P YTHON 4 - ORAC L E
CONECTAREA LA BAZE DE DATE ORACLE –
PACHETUL CX_ORACLE
• Pachetul cx_Oracle conține metode pentru realizarea unei conexiuni cu o bază de date Oracle,
pentru gestiunea interogărilor și a tranzacțiilor (comenzile
SELECT/INSERT/UPDATE/DELETE/MERGE și COMMIT/ROLLBACK).
• Lista completă a metodelor pachetului cx_Oracle este disponibilă aici: https://cx-
oracle.readthedocs.io/en/latest/user_guide/introduction.html
• Pentru realizarea conexiunii cu o bază de date Oracle este necesar clientul pentru Oracle
Database (Oracle Instant Client), iar in cadrul conexiunii se precizează:
- userul, parola, serverul (host/ip) și denumirea bazei de date (service name/SID).

De exemplu, pentru realizarea conexiunii cu serverul oracle care rulează pe IP-ul 193.226.34.57
cu service_name oradb, nume utilizator ms_dba și parola oracle se inițializează conexiunea
următoare:
• connection = cx_Oracle.connect("ms_dba", "oracle", "193.226.34.57/oradb")
• Pentru gestiunea interogărilor sau a tranzacțiilor este
necesară utilizarea unui cursor:
cursor = connection.cursor()
CURSORUL • Variabila de tip cursor dispune de toate metodele
necesare gestiunii tranzacțiilor și procesării interogărilor.
METODE ALE CURSORULUI
Metoda Explicații
cursor.execute(comanda SQL, Execută comanda SQL specificată împreună cu lista de parametrii. Ca rezultat,
parametri) în cazul SELECT, cursorul este încărcat cu înregistrările returnate;

cursor.close() Închide cursorul și eliberează zona de memorie alocată;


cursor.fetchone() Încarcă înregistrările din cursor în variabile locale Python (de obicei în liste de
cursor.fetchmany(n) tupluri);
cursor.fetchall()
cursor.prepare(comanda SQL) Transmite comanda SQL către cursor fără a o executa;
cursor.rowcount Returnează numărul de înregistrări parcurse din cursor, inițial este 0, iar pe
măsură ce se utilizează comanda fetch(), numărul crește.

cursor.bindarraysize Precizează dimensiunea cursorului, utilizată în special la comanda INSERT;

cursor.setinputsizes() Precizează tipul de date, utilizată în special la comanda INSERT.


REALIZAREA INTEROGĂRILOR
• Instrucțiunile SELECT sunt executate în cadrul cursorului astfel:
cursor.execute("""SELECT * FROM t_clienti_leasing""")
• Cursorul este încărcat cu tuplurile returnate de interogare, parcurgerea sa se poate realiza în
cadrul unui for:
for rec in cursor:
print("Values:", rec)
• După prelucrarea cursorului se recomandă închiderea sa, iar la final închiderea conexiunii cu
baza de date:
cursor.close()
connection.close()

Pentru exemplificare se utilizează tabelele T_CLIENTI_DAUNE și T_CLIENTI_LEASING din


schema utilizatorului ms_dbs.
REALIZAREA INTEROGĂRILOR
Python

connection = cx_Oracle.connect("student_ps", "oracle",


"37.120.250.20/oracle")
cursor = connection.cursor()
cursor.execute("""SELECT nume_client, profesia, venit_anual
FROM T_CLIENTI_LEASING""")
lista_clienti=cursor.fetchall()
cursor.close() Oracle Database
connection.close() 1. Autentificare utilizator
2. Execuție comandă SQL
3. Returnare set activ de date
Cursor T_CLIENTI_LEASING
Setul de date returnat de Oracle
Database T_CLIENTI_DAUNE
CX_ORACLE IN GOOGLE COLAB
1. Descarcati clientul de Oracle - Oracle Instant client basic lite RPM
https://download.oracle.com/otn_software/linux/instantclient/193000/oracle-instantclient19.3-
basiclite-19.3.0.0.0-1.x86_64.rpm
2. Incarcati fisierul RPM in Google Drive
3. Mount Google Drive. Rulati urmatoarea comanda:
from google.colab import drive
drive.mount('/content/drive’)
4. Instalati pachetul cx_Oracle:
!pip install cx_Oracle
!apt install alien
!alien -i /content/drive/MyDrive/…./oracle-instantclient19.3-basiclite-19.3.0.0.0-1.x86_64.rpm
METODELE FETCH, INTEROGARI CU PARAMETRI

• Pentru prelucrarea unui cursor se pot utiliza listele de tupluri, înregistrările putând fi încărcate
cu ajutorul metodelor cursorului (exemplul1):
fetchone() – încarcă o singură înregistrare;
fetchmany(n) – încarcă n înregistrări;
fetchall() – încarcă toate înregistrările din cursor.
• Interogări cu parametri:
- Parametrii se pot specifica direct în cadrul metodei execute() (a se vedea exemplul 2);
- O altă variantă presupune utilizarea metodei prepare() pentru realizarea interogării cu
parametru (a se vedea exemplul 3).
EXEMPLUL 1 INTEROGARI
Să se returneze numele, profesia, venitul anual și suma solicitată în cazul clienților care au solicitat mai mult de
5000 lei credit.
import cx_Oracle
from pprint import pprint

# Realizarea conexiunii cu serverul Oracle


# Conexiunea - user student_ps, parola oracle, host:37.120.250.20,
service_name oracle
connection = cx_Oracle.connect("student_ps", "oracle",
"37.120.250.20/oracle")
cursor = connection.cursor()
cursor.execute("""SELECT nume_client, profesia, venit_anual FROM
t_clienti_leasing WHERE suma_solicitata>5000""")
lista_clienti=cursor.fetchall()
# Inchidere cursor si conexiune
cursor.close()
connection.close()
# Afisare lista clienti
pprint (lista_clienti)
EXEMPLUL 2 INTEROGARI CU PARAMETRU
Să se returneze valoarea totală a daunelor înregistrate pentru o anumită marcă auto introdusă de utilizator de la
tastatură.
import cx_Oracle
from pprint import pprint

# Realizarea conexiunii cu serverul Oracle


#Conexiunea - user student_ps, parola oracle, host:37.120.250.20, service_name
oracle
connection = cx_Oracle.connect("student_ps", "oracle", "37.120.250.20/oracle")
cursor = connection.cursor()
v_marca = input("Introduceti marca: ");
cursor.execute("""SELECT marca, sum(valoare_dauna) Total_daune FROM
t_clienti_daune where lower(marca) like :p_marca group by marca""",
p_marca='%'+v_marca.lower()+'%')
lista_daune=cursor.fetchall()
#inchidere cursor si conexiune
cursor.close()
connection.close()
#afisare lista marci cu daune
pprint (lista_daune)
EXEMPLUL 3 INTEROGARI CU PARAMETRU
Să se returneze valoarea totală a daunelor pe fiecare marcă auto, dacă această valoare este mai mare decât o anumită valoare
prag. De la tastatură se va introduce valoarea prag pentru 2 executii succesive.
import cx_Oracle
from pprint import pprint
connection = cx_Oracle.connect("student_ps", "oracle", "37.120.250.20/oracle")
cursor = connection.cursor()
#pregatirea interogarii cu parametru
cursor.prepare("""SELECT marca, sum(valoare_dauna) Total_daune FROM t_clienti_daune
group by marca having sum(valoare_dauna)>:p_val""")
#prima executie
v_val = input("Introduceti valoarea: ")
cursor.execute(None, {'p_val': v_val})
lista_daune=cursor.fetchall()
#afisare lista marci cu daune
pprint (lista_daune)
#a doua executie
v_val = input("Introduceti valoarea: ")
cursor.execute(None, {'p_val': v_val})
lista_daune=cursor.fetchall()
#afisare lista marci cu daune
pprint (lista_daune)
#inchidere cursor si conexiune
cursor.close()
connection.close()
CONTROLUL TRANZACTIILOR

• Operațiile de INSERT, UPDATE și DELETE sunt realizate tot prin intermediul


unui cursor cu ajutorul metodei execute().
• În cazul INSERT, se pot transmite mai multe înregistrări prin metoda executemany(). În acest
caz se recomandă să se precizeze numărul de înregistrări prin proprietatea bindarraysize
și tipul parametrilor prin metoda setinputsizes.
• Tranzacțiile se pot finaliza sau anula prin precizarea opțiunilor COMMIT sau ROLLBACK ale
conexiunii: connection.commit() sau connection.rollback()
• Se poate seta modul de gestiune a tranzacțiilor prin metoda connection.autocommit=True
EXEMPLUL 4 INSERT
Să se adauge o listă de tupluri în tabela CLIENTI_NOI care are următoarea structură: id_client number, nume_client varchar2(150),
profesia varchar2(150), sex varchar2(3), varsta number, stare_civila varchar2(1), suma_solicitata number. Să se finalizeze tranzacția și
apoi să se returneze înregistrările noi adăugate. Modificați secvența de cod și anulați tranzacția.
import cx_Oracle
from pprint import pprint
connection = cx_Oracle.connect("student_ps", "oracle", "37.120.250.20/oracle")
lista_clienti_noi = [(100, "Popa Marcel", "Inginer", "m", 34, "C", 230),
(101, "Popa Vasilica", "Coafeza", "f", 32, "C", 200),
(102, "Popa Ion", "Instalator", "m", 64, "C", 120)]
cursor = connection.cursor()
#adaugarea listei de clienti noi in tabela
cursor.bindarraysize = 3
cursor.setinputsizes(int, 150, 150, 3, int, 1, float)
cursor.executemany("insert into clienti_noi(id_client, nume_client, profesia, sex, varsta,
stare_civila,suma_solicitata) values (:1, :2, :3, :4, :5, :6, :7)", lista_clienti_noi)
cursor.close()
#finalizarea tranzactiei
connection.commit()
#interogarea bazei de date pentru vizualizarea inregistrarilor noi adaugate
cursor2 = connection.cursor()
cursor2.execute("""SELECT * from clienti_noi where nume_client like 'Popa%'""")
lista_clienti=cursor2.fetchall()
pprint(lista_clienti)
cursor2.close()
connection.close()
E X E M P L U L 5 U P D AT E
Să se majoreze cu 10% suma solicitată de clienții al căror nume este introdus de utilizator de la tastatură.
Actualizările se vor realiza pe tabela CLIENTI_NOI. Să se finalizeze/anuleze tranzacția și să se re-deschidă un
cursor pentru verificarea rezultatelor tranzacției.
import cx_Oracle
from pprint import pprint
connection = cx_Oracle.connect("student_ps", "oracle", "37.120.250.20/oracle"
cursor = connection.cursor()
#adaugarea listei de clienti noi in tabela
statement="update clienti_noi set suma_solicitata=suma_solicitata*1.10 where
lower(nume_client) like :p_nume"
v_nume=input("Introduceti numele clientului:")
cursor.execute(statement,p_nume='%'+v_nume.lower()+'%')
cursor.close()
#finalizarea tranzactiei
connection.commit()
#interogarea bazei de date pentru vizualizarea inregistrarilor noi adaugate
cursor2 = connection.cursor()
cursor2.execute("""SELECT * from clienti_noi where lower(nume_client) like :p_nume""",
p_nume='%'+v_nume.lower()+'%')
lista_clienti=cursor2.fetchall()
pprint(lista_clienti)
cursor2.close()
connection.close()
EXEMPLUL 6 DELETE
Să se șteargă din tabela CLIENTI_NOI clienții cu numele de familie Popa. Să se finalizeze tranzacția.

import cx_Oracle

# Realizarea conexiunii cu serverul Oracle


#Conexiunea - user student_ps, parola oracle, host 37.120.250.20, service_name oracle
connection = cx_Oracle.connect("student_ps", "oracle", "37.120.250.20/oracle")

cursor = connection.cursor()

#stergerea clientilor cu numele Popa


statement="delete from clienti_noi where nume_client like 'Popa%'"
cursor.execute(statement)
cursor.close()

#finalizarea tranzactiei
connection.commit()
connection.close()
EXEMPLUL 7 INCARCARE IN PANDAS
• Înregistrările returnate de o interogare SQL se pot încărca direct într-un DataFrame Pandas prin metoda
pandas.read_sql(comanda SQL, conexiunea, lista de parametri).
• În acest caz nu mai este necesară încărcarea înregistrărilor în cursor, acestea fiind gestionate automat
de către DataFrame.
Să se selecteze din tabela T_CLIENTI_DAUNE marca, modelul, anul de fabricație, componenta, prețul
manoperei și valoarea daunei pentru autoturismele mai noi de 2010.
import pandas as pd
import cx_Oracle
from pprint import pprint
# Connect to oracle.
connection = cx_Oracle.connect("student_ps", "oracle",
"37.120.250.20/oracle")
#incarcam in DataFrame inregistrarile returnate de SELECT
an=2010
query ="""Select marca, model, an_fabricatie, componenta, pret_manopera,
valoare_dauna
from t_clienti_daune
where an_fabricatie>:an"""
df = pd.read_sql(query, con=connection, params={'an': an})
pprint(df)
connection.close()
EXEMPLUL 8 PRELUCRARE IN PANDAS
Pornind de la exemplul anterior, în exemplul de mai sus să se adauge o nouă coloană în df pentru a calcula
ponderea manoperei din valoarea totală a daunei. Să se afișeze marca și componentele înlocuite în cazul în
care ponderea depășește 30% din valoarea daunei.
import pandas as pd
import cx_Oracle
from pprint import pprint
# Connect to oracle.
connection = cx_Oracle.connect("student_ps", "oracle",
"37.120.250.20/oracle")
#incarcam in DataFrame inregistrarile returnate de SELECT
an=2010
query ="""Select marca, model, an_fabricatie, componenta, pret_manopera,
valoare_dauna
from t_clienti_daune
where an_fabricatie>:an"""
df = pd.read_sql(query, con=connection, params={'an': an})
connection.close()

df["PROCENT"]=df["VALOARE_DAUNA"]/df["PRET_MANOPERA"]
pprint(df.loc[(df["PROCENT"]>30), ["MARCA","COMPONENTA"]])
• Using Python with Oracle Database 11g,
https://www.oracle.com/technetwork/articles/dsl/python-
091105.html
• Developing a Python Web Application with Oracle Database 11g,
SURSE https://www.oracle.com/webfolder/technetwork/tutorials/obe/db/
BIBLIOGRAFICE OOW11/python_django/python_django.htm
• https://learncodeshare.net/2015/06/26/insert-crud-using-
cx_oracle/

S-ar putea să vă placă și