Effizientes Programmieren mit Suchtfaktor: SAS Hash-Tables

[email protected] Effizientes Programmieren mit Suchtfaktor: SAS Hash-Tables Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d. Table Look...
Author: Leopold Kohler
0 downloads 3 Views 2MB Size
[email protected] Effizientes Programmieren mit Suchtfaktor: SAS Hash-Tables

Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

Table Lookup Technik: Hash Tables Werte aus einer Referenztabelle abfragen mittels Hash Tables

DATA Step Hash Objekte: Eigenschaften       

Datenspeicherung und Suche im Arbeitsspeicher Hash Objekt muss in den Arbeitsspeicher passen (kleinere Datei nehmen) Schnelle Alternative zu Data Step Merge oder SQL Joins Anders als bei Arrays können verschiedene Datentypen zusammen in einem Objekt sein Daten müssen nicht sortiert sein Nutzt den Schlüssel für eine schnelle Datensuche Dot-Net Syntax (objektorientiert)

Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

Szenario Die Datei orion.supplier beinhaltet demographische Informationen über Lieferanten (keine Produktinfos). Teilauszug aus der Datei: orion.supplier Supplier_ ID

Supplier_Name

Street_ ID

Supplier_Address

Sup_ Street_N umber

Country

50

Scandinavian Clothing A/S

6850100389

Kr. Augusts Gate 13

13

NO

109

Petterson AB

8500100286

Blasieholmstorg 1

1

SE

316

Prime Sports Ltd

9250103252

9 Carlisle Place

9

GB

755

Top Sports

3150108266

Jernbanegade 45

45

DK

9260115819

553 Cliffview Dr

553

US

. . .

. . .

. . .

772 . . .

AllSeasons Outdoor Clothing . . .

. . .

Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

Szenario Es müssen Daten aus der Datei orion.supplier mit orion.product_list verbunden werden, welche Produktinformationen beinhaltet. Teilauszug aus der Datei: orion.product_list Product_ID

Product_Name

Supplier_ ID

Product_ Level

Product_ Ref_ID

210000000000

Children

.

4

.

210100000000

Children Outdoors

.

3

210000000000

210100100000

Outdoor things, Kids

.

2

210100000000

210200000000

Children Sports

.

3

210000000000

210200100000

A-Team, Kids Kids Sweat Round Neck,Large Logo

.

2

210200000000

3298

1

210200100000

. . .

. . .

. . .

210200100009 . . .

. . .

Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

Ein Hash Objekt aus einer SAS Datei befüllen data supplier_info; length Supplier_Name $40 Supplier_Address $ 45 Country $ 2; if _N_=1 then do; declare hash S(dataset:'orion.supplier'); S.definekey('Supplier_ID'); S.definedata('Supplier_Name', 'Supplier_Address','Country'); S.definedone(); call missing(Supplier_Name, Supplier_Address,Country); end; set orion.product_list; rc=S.find(); if rc=0; drop rc; run; Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

Hash Objekt erstellen Erstellen eines Hash Objekts namens T.

declare hash T();

Erstellen des T Hash Objekts und Laden aus der Datei orion.MemberType.

declare hash T(dataset: 'orion.MemberType');

Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

Ausführung Auszug: HASH Object S KEY: Supplier _ID

DATA: Supplier_ Name

DATA: Supplier_ Address

DATA: Country

50

Scandinavian Clothing A/S

Kr. Augusts Gate 13

NO

109

Petterson AB

Blasieholmstorg 1

SE

316

Prime Sports Ltd

9 Carlisle Place

GB

. . .

. . . 3298

A Team Sports

. . . 2687 Julie Ann Ct

. . . US

data supplier_info; drop rc; length Supplier_Name $40 Supplier_Address $ 45 Country $ 2; if _N_=1 then do; declare hash S(dataset:'orion.supplier'); S.definekey('Supplier_ID'); S.definedata('Supplier_Name', 'Supplier_Address', 'Country'); S.definedone(); call missing(Supplier_Name, Supplier_Address, Country); end; set orion.product_list; rc=S.find(); if rc=0; run;

Partial PDV Supplier_ Name

Supplier_ Address

Country

Product _ID

Product_ Name

. Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

Supplier _ID

.

...

D

rc

.

_N_ 1

Ausführung Auszug: HASH Table S KEY: Supplier _ID

DATA: Supplier_ Name

DATA: Supplier_ Address

DATA: Country

50

Scandinavian Clothing A/S

Kr. Augusts Gate 13

NO

109

Petterson AB

Blasieholmstorg 1

SE

316

Prime Sports Ltd

9 Carlisle Place

GB

. . .

. . . 3298

A Team Sports

. . . 2687 Julie Ann Ct

. . . US

Partial PDV Supplier_ Name

Supplier_ Address

Country

data supplier_info; drop rc; length Supplier_Name $40 Supplier_Address $ 45 Country $ 2; if _N_=1 then do; declare hash S(dataset:'orion.supplier'); S.definekey('Supplier_ID'); S.definedata('Supplier_Name', 'Supplier_Address', 'Country'); S.definedone(); call missing(Supplier_Name, Supplier_Address, Country); end; set orion.product_list; rc=S.find(); if rc=0; run; Product _ID 210000000000

Product_ Name

Children

Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

Supplier _ID

... .

rc

D

-2147450842

-2147450842

_N_ 1

Ausführung Auszug: HASH Object S KEY: Supplier _ID

DATA: Supplier_ Name

DATA: Supplier_ Address

DATA: Country

50

Scandinavian Clothing A/S

Kr. Augusts Gate 13

NO

109

Petterson AB

Blasieholmstorg 1

SE

316

Prime Sports Ltd

9 Carlisle Place

GB

. . .

. . . 3298

. . .

A Team Sports

2687 Julie Ann Ct

. . . US

data supplier_info; drop rc; length Supplier_Name $40 Supplier_Address $ 45 Country $ 2; if _N_=1 then do; declare hash S(dataset:'orion.supplier'); S.definekey('Supplier_ID'); S.definedata('Supplier_Name', 'Supplier_Address', 'Country'); S.definedone(); call missing(Supplier_Name, Supplier_Address, Country); end; False set orion.product_list; rc=S.find(); if rc=0; run; -2147450842

Partial PDV Supplier_ Name

Supplier_ Address

Country

Product _ID 210000000000

Product_ Name

Children

Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

Supplier _ID

.

...

D

rc -2147450842

_N_ 1

Ausführung Auszug: HASH Object S KEY: Supplier _ID

DATA: Supplier_ Name

DATA: Supplier_ Address

DATA: Country

50

Scandinavian Clothing A/S

Kr. Augusts Gate 13

NO

109

Petterson AB

Blasieholmstorg 1

SE

316

Prime Sports Ltd

9 Carlisle Place

GB

. . .

. . . 3298

. . .

A Team Sports

2687 Julie Ann Ct

. . . US

data supplier_info; drop rc; length Supplier_Name $40 Supplier_Address $ 45 Country $ 2; if _N_=1 then do; declare hash S(dataset:'orion.supplier'); S.definekey('Supplier_ID'); S.definedata('Supplier_Name', 'Supplier_Address', 'Country'); S.definedone(); call missing(Supplier_Name, Supplier_Address, Country); end; set orion.product_list; rc=S.find(); if rc=0; run;

Continue until _N_=6

Partial PDV Supplier_ Name

Supplier_ Address

Country

Product _ID

210200100009

Product_ Name Kids Sweat Round Neck,Large Logo

Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

Supplier _ID

3298

...

D

rc .

_N_ 6

Ausführung Auszug: HASH Object S KEY: Supplier _ID

DATA: Supplier_ Name

DATA: Supplier_ Address

DATA: Country

50

Scandinavian Clothing A/S

Kr. Augusts Gate 13

NO

109

Petterson AB

Blasieholmstorg 1

SE

316

Prime Sports Ltd

9 Carlisle Place

GB

. . .

. . . 3298

A Team Sports

. . . 2687 Julie Ann Ct

. . . US

data supplier_info; drop rc; length Supplier_Name $40 Supplier_Address $ 45 Country $ 2; if _N_=1 then do; declare hash S(dataset:'orion.supplier'); S.definekey('Supplier_ID'); S.definedata('Supplier_Name', 'Supplier_Address', 'Country'); S.definedone(); call missing(Supplier_Name, Supplier_Address, Country); end; set orion.product_list; rc=S.find(); if rc=0; run;

Partial PDV Supplier_ Name

Supplier_ Address

Country

Product _ID

210200100009

Product_ Name Kids Sweat Round Neck,Large Logo

Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

Supplier _ID

3298

...

D

rc 0

_N_ 6

Ausführung Auszug: HASH Object S KEY: Supplier _ID

DATA: Supplier_ Name

DATA: Supplier_ Address

DATA: Country

50

Scandinavian Clothing A/S

Kr. Augusts Gate 13

NO

109

Petterson AB

Blasieholmstorg 1

SE

316

Prime Sports Ltd

9 Carlisle Place

GB

. . .

. . . 3298

A Team Sports

. . . 2687 Julie Ann Ct

. . . US

data supplier_info; drop rc; length Supplier_Name $40 Supplier_Address $ 45 Country $ 2; if _N_=1 then do; declare hash S(dataset:'orion.supplier'); S.definekey('Supplier_ID'); S.definedata('Supplier_Name', 'Supplier_Address', 'Country'); S.definedone(); call missing(Supplier_Name, Supplier_Address, Country); end; set orion.product_list; rc=S.find(); if rc=0; run; Implicit OUTPUT;

True

Partial PDV Supplier_ Name A Team Sports

Supplier_ Address 2687 Julie Ann Ct

Country

US

Product _ID 210200100009

Product_ Name Kids Sweat Round Neck,Large Logo

Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

Implicit RETURN; Supplier _ID

3298

...

D

rc

0

_N_

6

Die Find-Methode Die FIND Methode lokalisiert den Schlüsselwert im Hash Objekt und gibt die Datenwerte zurück. Allgemeine Form:

rc=object.FIND(); Der ReturnCode kann mit bedingter Logik verbunden werden, um verschiedene ReturnWerte abzufragen. Beispiel: Werte der ReturnCode Variablen Null (0) Nicht null

Übereinstimmung Keine Übereinstimmung

Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

Length Anweisung data supplier_info; drop rc;

length Supplier_Name $40 Supplier_Address $ 45 Country $ 2;

if _N_=1 then do; declare hash S(dataset:'orion.supplier'); S.definekey('Supplier_ID'); S.definedata('Supplier_Name', 'Supplier_Address', 'Country'); S.definedone(); ..... end;

Partial PDV Supplier_ Name

Supplier_ Address

Count ry

Product _ID

.

Product_ Name

Supplie r _ID

. Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

S.definedata: Die Datenkomponenten beziehen sich auf SAS Variablen und sollen als SAS Variablen auch angelegt werden , um automatisch befüllt werden zu können. Wie? Eine Möglichkeit: LENGTH nutzen Damit legt SAS in der Kompilierungsphase im Data Step diese als SAS Variablen im Zwischenspeicher PDV an.

CALL MISSING data supplier_info; drop rc; length Supplier_Name $40 Supplier_Address $ 45 Country $ 2; if _N_=1 then do; ... S.definedata('Supplier_Name', 'Supplier_Address', 'Country'); ...

Da die Datenelemente als SAS Variablen erstellt werden sollen mittels Length Anweisung - haben sie jedoch keinen Startwert (Initialisierungswert).

Sie kommen über das Hash Objekt, direkt in den PDV, nicht aus der Datei, und sie werden auch nicht zugewiesen call missing(Supplier_Name, Supplier_Address, mit Gleichzeichen = Country); Dies erzeugt folgende Meldung im Log: Call Missing: - Verhindert Note im Log NOTE: Variable Supplier_Name is uninitialized. - Weist Missingwerte als NOTE: Variable Supplier_Address is uninitialized. NOTE: Variable Country is uninitialized. Startwert zu Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

Ergebnisse Partial PROC PRINT Output Product Information Obs

Product_ID

Supplier_ID

1 2 3 4 5 6 7 8 9 10

210200100009 210200100017 210200200022 210200200023 210200300006 210200300007 210200300052 210200400020 210200400070 210200500002

3298 3298 6153 6153 1303 1303 1303 1303 1303 772

Supplier_Name

Supplier_Address

A Team Sports A Team Sports Nautlius SportsWear Inc Nautlius SportsWear Inc Eclipse Inc Eclipse Inc Eclipse Inc Eclipse Inc Eclipse Inc AllSeasons Outdoor Clothing

2687 Julie Ann Ct 2687 Julie Ann Ct 56 Bagwell Ave 56 Bagwell Ave 1218 Carriole Ct 1218 Carriole Ct 1218 Carriole Ct 1218 Carriole Ct 1218 Carriole Ct 553 Cliffview Dr

Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

Country US US US US US US US US US US

Ein weiteres Anwendungsbeispiel für Hash Objekte • •

Die Marketing Abteilung will jeweils die beiden Kunden mit dem höchsten und die beiden mit dem niedrigsten Umsatz herausfinden Ausgabe in 2 Dateien in EINEM Data Step Partial orion.orderfact Customer ID 63 5 45 41 183

ProductID 220101300017 230100500026 240600100080 240600100010 240200200039

Quantity 1 1 1 2 3

Total Retail Price $16.50 $247.50 $28.30 $32.00 $63.60

$$$

CostPrice PerUnit

Discoun t

$7.45 $109.55 $8.55 $6.50 $8.80

. . . . .

$ Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

Hash Iterator Objekt (Hiter Objekt) Das Hash Iterator Objekt ist sehr gut geeignet zum effizienten Durchsuchen eines Hash Objekts. Dabei wird der Schlüssel genutzt, die Datei selbst muss nicht sortiert sein, das Hash Iterator Objekt sollte (aber muss nicht) sortiert sein. Auszug: Hash Object KEY: Total Retail Price 16.50 247.50 28.30 32.00 . . . 95.10 48.20 75.20 33.80

Auszug: Hiter View

KEY: Customer ID 63 5 45 41 . . . 10 10 89 5

KEY: Total Retail Price 1937.20 1796.00 1687.50 1561.80 . . . 3.20 3.00 2.70 2.60

KEY: Customer ID 70100 79 16 183 . . . 69 5 11171 79

Das Hash Iterator Objekt bezieht sich auf ein zuvor erstelltes Hash Objekt Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

Anwendungsbeispiel: Syntax data top bottom; drop i; if _N_=1 then do; if 0 then set orion.orderfact(keep=CustomerID ProductID TotalRetailPrice); declare hash customer(dataset:'orion.orderfact', ordered:'descending'); customer.definekey('TotalRetailPrice', 'CustomerID'); customer.definedata('TotalRetailPrice', 'CustomerID', 'ProductID'); customer.definedone(); declare hiter C('customer'); end; C.first(); do i=1 to 2; output top; C.next(); end; Das Hiter Objekt bezieht sich C.last(); do i=1 to 2; auf ein zuvor erstelltes Hash output bottom; C.prev(); Objekt end; stop; run; Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

Durchsuchen des Hash Objektes mit dem Hiter Objekt •

Vier Hiter Objekt Methoden geben die Werte basierend auf der Position im Hash Objekt zurück. FIRST

NEXT

LAST

PREV

Hash Object Key: A

Hiter Object View Data: B

Key: A

3 X

Data: B 3 X

1 Y

2 Z

2 Z

1 Y Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

Ausführung Auszug: Hash Object customer KEY: Total Retail Price 16.50 247.50 28.30 32.00 . . . 95.10 48.20 75.20 33.80

KEY: Customer ID 63 5 45 41 . . . 10 10 89 5

DATA: Total Retail Price 16.50 247.50 28.30 32.00 . . . 95.10 48.20 75.20 33.80

DATA: Customer ID

DATA: Product ID

63 5 45 41

220101300017 230100500026 240600100080 240600100010 . . . 240500200016 240500200122 240700200018 220101400130

. . . 10 10 89 5

data top bottom; drop i; if _N_=1 then do; if 0 then set orion.orderfact (keep=CustomerID ProductID TotalRetailPrice); declare hash customer (dataset:'orion.orderfact', ordered:'descending'); customer.definekey('TotalRetailPrice', 'CustomerID'); customer.definedata('TotalRetailPrice', 'CustomerID','ProductID'); customer.definedone(); declare hiter C('customer'); end;

Beachten Sie: Das Hash Objekt selbst ist nicht sortiert!

PDV Customer ID

Product ID

.

Total RetailPrice

. Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

D

.

i

D

.

_N_

1 ...

Ausführung Auszug: Hiter C View KEY: Total Retail Price 1937.20 1796.00 1687.50 1561.80 . . . 3.20 3.00 2.70 2.60

KEY: Customer ID 70100 79 16 183 . . . 69 5 11171 79

DATA: Total Retail Price 1937.20 1796.00 1687.50 1561.80 . . . 3.20 3.00 2.70 2.60

DATA: Customer ID

DATA: Product ID

70100 79 16 183 . . . 69 5 11171 79

240200100173 240200100076 230100700009 240300300090 . . . 230100500004 240100100433 240200100021 230100500045

data top bottom; drop i; if _N_=1 then do; if 0 then set orion.orderfact (keep=CustomerID ProductID TotalRetailPrice); declare hash customer (dataset:'orion.orderfact', ordered:'descending'); customer.definekey('TotalRetailPrice', 'CustomerID'); customer.definedata('TotalRetailPrice', 'CustomerID','ProductID'); customer.definedone(); declare hiter C('customer'); end;

Das Hiter Objekt jedoch ist absteigend sortiert, wie in der Syntax angegeben.

PDV Customer ID

Product ID

.

Total RetailPrice

. Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

D

.

i

D

.

_N_

1 ...

Dateien erstellen mittels Hash Iterator Objekt Methoden data top bottom; drop i; if _N_=1 then do; if 0 then set orion.orderfact(keep=CustomerID ProductID TotalRetailPrice);

declare hash customer(dataset:'orion.orderfact', ordered:'descending');

customer.definekey('TotalRetailPrice', 'CustomerID'); customer.definedata('TotalRetailPrice', 'CustomerID', 'ProductID'); customer.definedone();

declare hiter C('customer');

end;

C.first(); do i=1 to 2; output top; C.next(); end; C.last(); do i=1 to 2; output bottom; C.prev(); end; stop; run; Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

PROC PRINT Ausgabe proc print data=top; title 'Top 2 Big Spenders'; run; proc print data=bottom; title 'Bottom 2 Frugal Spenders'; run;

Top 2 Big Spenders

Obs 1 2

CustomerID

ProductID

TotalRetail Price

70100 79

240200100173 240200100076

$1,937.20 $1,796.00

Bottom 2 Frugal Spenders

Obs 1 2

CustomerID

ProductID

TotalRetail Price

79 11171

230100500045 24 240200100021

$2.60 $2.70

Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

Vielen Dank für Ihre Teilnahme SAS® Live Web Classes 2017: Termine und Anmeldung •

https://support.sas.com/edu/locations.html?locationId=LW&ctry=DE

Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

Weitere Informationen und Kurse zu diesem Thema… SAS® Programmierung 3: Effiziente Techniken des Datenmanagements 03. – 05. April 2017, Heidelberg 19. – 21. Juni 2017, Heidelberg

Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

Nächstes [email protected]: 27. April 2017 SAS und das Hadoop-Ökosystem Bastian Weiß, Kybeidos

Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.

Folien zum Download unter www.sas.de/lunchtime WIE HAT IHNEN UNSER WEBINAR GEFALLEN?

sas.com

Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.