Daten mit Envision filtern - Software zur Bestandsoptimierung

Daten filtern












Startseite » Ressourcen » Hier

Das Filtern von Daten stellt das A und O der Betriebsanalyse dar. Envision bietet eine breite Unterstützung, um dies zu erreichen. So wird das Filtern von den Bedingungen where und when unterstützt, die sowohl für die Filterung von großen Skriptblocks auf einmal, als auch zur Filterung individueller Anweisungen genutzt werden kann. Auf dieser Seite bieten wir Ihnen eine praktische Einführung zu diesen Konzepten.


Ein veranschaulichendes Skript

Wir beginnen erneut mit dem Beispiel-Dataset, den Sie über den Pfad /sample in Ihrem Lokad-Konto erreichen sollten. Sollten Sie dies noch nicht gemacht haben, empfehlen wir Ihnen, zuerst Berechnungen mit Envision zu lesen, bevor Sie mit der Information auf dieser Seite weiterarbeiten.
read "/sample/Lokad_Items.tsv"
read "/sample/Lokad_Orders.tsv" as O

show label "Filtering data" a1f1 tomato

oend := max(O.Date)

when date > oend - 365
LastYearQty = sum(O.Quantity)
where StockOnHand + StockOnOrder > LastYearQty
show table "Overstocked items, +1 year of stock" a2f3 tomato with 
Id
Name
StockOnHand + StockOnOrder as "Stock"
LastYearQty

where O.NetAmount > 1000
show table "Large transactions over $1000" a4f5 tomato with 
Id
Name 
O.Date 
O.Quantity
O.NetAmount
O.Client

lastDay := monday(oend)
firstDay := lastDay - 52 * 7
when date >= firstDay & date < lastDay
Week.sold := sum(O.NetAmount)
show linechart "Sold by week" a6f7 tomato unit:"$" with
Week.sold
Wir empfehlen Ihnen, mit dem Kopieren und Einfügen dieses Skripts in Ihrem Lokad-Konto zu beginnen. Anschließend sollten Sie diesen ausführen, um das entstehende Dashboard zu sehen. Wenn alles korrekt funktioniert, sollten Sie dann das unten angezeigte Dashboard sehen.

Image

Filterblöcke

Beginnt man beispielsweise mit all den historischen Daten, die innerhalb vom letzten Jahr entstanden sind, zu arbeiten, sind höchstwahrscheinlich mehrere Berechnungen im Spiel. In solchen Situationen sollte der Filter last year only auf alle Berechnungen angewandt werden. Aus diesem Grund wird in Envision hauptsächlich in Codeblocks gefiltert. Der unten angezeigte Abschnitt des Skripts zeigt zwei eingebettete Filterblöcke. Der erste Block beginnt in Zeile 1 mit der Bedingung when und wird von einem zweiten Block gefolgt, der in Zeile 3 mit der Bedingung where beginnt.
when date > oend - 365
  LastYearQty = sum(O.Quantity)
  where StockOnHand + StockOnOrder > LastYearQty
    show table "Overstocked items, +1 year of stock" a2f3 tomato with
      Id
      Name
      StockOnHand + StockOnOrder as "Stock"
      LastYearQty
Envision ist eine Sprache, die die Leerzeichen am Anfang jeder Zeile berücksichtigt. Eine Reihe von Zeilen, die mit Leerzeichen beginnen, wird als Codeblock bezeichnet und diese Codeblocks können ineinander verschachtelt sein, d.h. dass ein Block einen anderen Block enthalten kann.

Womöglich kann Ihnen dies etwas verwirrend vorkommen, wenn Sie solche Programmierungsmuster noch nicht kennen. Doch in der Praxis bietet der Skript-Editor von Envision breite eingebaute Unterstützung: Wenn Sie am Ende eine Skriptzeile, die eine Filterbedingungen enthält, auf Eingabe klicken, beginnt die nächste Zeile automatisch mit einer Einrückung aus zwei Leerzeichen.

Bemerkung für Entwickler. Envision nutzt ein ähnliches Leerzeichenmuster, wie Python. Dieser Ansatz passt gut zu Envision, das um eine prägnante Syntax zur Datenverarbeitung bemüht ist. Da Envision keine Schleifen und keine Verzweigungen besitzt, überschreitet die Einrückung selten 3 Ebenen, was sich durch Leerzeichen in der Praxis gut ausführen lässt.

Ein Filterblock beginnt mit einer Bedingung,wie wir weiter unten erklären, die für jede Zeile jeder Tabelle wahr oder falsch sein kann. In einem Filterblock werden nur die Zeilen, für die die Bedingung wahr ist behalten, während die restlichen Zeilen rausgefiltert werden. Wie aus dem Namen hervorgeht, ist die Bedingung when mit einem zeitlichen Filter verbunden, das auf alle indexierten Tabellen mit einer Date Spalte angewandt wird. Die Bedingung where hingegen wird zum Filtern der Artikel genutzt und auf alle indexierte Tabellen mit einer Id Spalte angewandt.

Beginnt ein Block mit einem Envision-Skript verhält es sich so, als wenn alle Zeilen der Tabellen, die den Filter erfüllen, behalten werden würden. Abgesehen davon bleibt alles andere gleich. Es ist weiterhin möglich alle Skriptabschnitte, die außerhalb des Blocks geschrieben werden konnten, in den Block zu verlegen. Insbesondere ist es möglich, einen anderen Filterblock in einem Block zu definieren. Dieses Muster nennt sich Verschachtelung. So ist der Block where im oberen Beispiel, der in Zeile 3 beginnt im Block when, der in Zeile 1 beginnt verschachtelt.

Erstellung einer Bedingung

Eine Bedingung ist ein Ausdruck, der als wahr oder falsch bewertet werden kann. Der Grundgedanke der Filter stützt sich auf die Erstellung von Bedingungen, die anhand der Eingabedaten oder möglicherweise der Ergebnisse der Zwischenrechnungen bewertet werden. Envision bietet daher die Möglichkeit, bedeutende Bedingungen zu erstellen, wie im folgenden Skript gezeigt wird:
lastDay := monday(oend)
firstDay := lastDay - 52 * 7
when date >= firstDay & date < lastDay
Week.sold := sum(O.NetAmount)
show linechart "Sold by week" a6f7 tomato unit:"$" with
Week.sold
In diesem Snippet weist der Operator and darauf hin, dass beide Ausdrücke, sowohl der rechte als auch der linke, wahr sein müssen. Die logischen Operatoren, die Envision unterstützt sind: and, or und not. Zusätzlich können Zahlen mit den numerischen Operatoren == (Gleichheit), != (Ungleichheit), <= (kleiner oder gleich), >= (größer als), < (kleiner als), > (größer als) verglichen werden. Im folgenden Snippet wird gezeigt, wie diese Operatoren kombiniert und bewertet werden.
a := 1 > 10 // false
b := not a // true
c := a | b // true
d := a & b // false
e := 10 >= 3 | 5 > 7 // true
show table "Conditions" with a, b, c, d, e
Wird ein Filterblock in einen anderen Filterblock verschachtelt, funktioniert dieser als ob ein and Operator mit zwei Bedingungen auf der rechten und der linken Seite des Operators and genutzt werden würde

Vielleicht haben Sie im oberen Beispiel die Syntax monday(oend) bemerkt. Dies ist eine Funktion, zum Aufruf an die Funktion namens monday. Diese Funktion ergibt für jedes Datum den letzten Montag, der nicht vor dem Datum (inklusive des Datums), das als Argument angegeben wird, geschehen ist.

Diese monday() Funktion wird zur Definition des Zeitraums einer ganzen Woche genutzt (statt für Teile von der Woche). Tatsächlich sollten bei wöchentlichen Aggregationen immer nur vollständige Wochen in Betracht gezogen werden. Ansonsten können das erste und letzte Datum etwas verwirrend niedrige Werte ergeben, die lediglich widerspiegeln, dass nur ein Teil der Woche genutzt wurde.

Filtern von Tabellen nach Datum

Envision bietet eine breite Unterstützung beim Filtern der Tabelle nach zeitlichen Kriterien. Im oberen Skript werden alle Zeilen, die älter als 1 Jahr sind gefiltert. Sehen wir uns den relevanten Teil des Skripts genauer an.
oend := max(O.Date)
when date > oend - 365
  LastYearQty = sum(O.Quantity)
Envision behandelt intern das Datum als die Gesamtzahl der Tage seit dem 1. Januar 2001. Dies bietet mehrere Vorteile, wie etwa die Möglichkeit, Berechnungen mit Daten durchzuführen. So kann man beispielsweise, wenn man von einem bestimmten Datum 7 subtrahiert, die vorherige Woche erhalten, während die Subtraktion von 365 Tagen (in etwa) das Datum des Vorjahrs ergibt.

Außerdem weist das date Schlüsselwort ein besonderes Verhalten auf. Implizit bezieht sich das date Schlüsselwort auf alle Tabellen, die eine date Spalte enthalten. Da hier nur eine Tabelle eine Rolle spielt, nämlich die Tabelle O, ist es so, als wenn man stattdessen O.Date > oend - 365 geschrieben hätte. Doch die Date Syntax ist nicht nur prägnanter, sondern wird auch auf alle relevanten Tabellen auf einmal angewandt. Wenn wir uns statt für die verkauften Mengen, für die gekauften Mengen interessieren hätten, hätte man dies so schreiben können:
// Upload von PurchaseOrders
read "/sample/Lokad_PurchaseOrders.tsv" as PO

// abgeschnitten

when date > oend - 365
  LastYearQty = sum(PO.Quantity)

Artikel filtern

Abgesehen von der Filterung von Zeilen nach Datum, bietet Envision auch die Möglichkeit, Artikel zu filtern. Dies wird oft benötigt, wenn man bestimmte Produkte, Standorte, Kategorien, etc. herausfiltern möchte. Im obersten Skript auf dieser Seite können Sie erkennen, wie das Ergebnis auf Artikel beschränkt werden kann, die man als toten Bestand bezeichnen kann. Die relevante Zeile wird unten genauer beschrieben.
  where StockOnHand + StockOnOrder > LastYearQty
    show table "Overstocked items, +1 year of stock" a2f3 tomato with
      Id
      Name
      StockOnHand + StockOnOrder as "Stock"
      LastYearQty
Dem where Schlüsselwort folgt eine Bedingung. Diese Bedingung trifft auf die drei Vektoren zu, die implizit zur Items Tabelle gehören. Dies ist außerdem die einzige Tabelle, auf die man sich, ohne den Tabellennamen als Präfix im Namen der Variablen zu nennen, beziehen kann. So muss man beispielsweise O.NetAmount und nicht NetAmount nutzen, wenn man sich auf die Zeilen der Bestellungstabelle O bezieht. Vorliegende Bedingung kann hier wie folgt gelesen werden: nur Artikel berücksichtigen, bei denen die Summe des aktuellen Bestands und des Bestellbestands größer als die Zahl der im vergangenen Jahr verkauften Einheiten ist.

Wenn einmal eine Bedingungen für die Items Tabelle erstellt wurde, werden alle Tabellen, die eine Id Spalte enthalten - d.h. einen Identifikator, der sich den Envision Konventionen nach auf die Artikel beziehen - ähnlich gefiltert. Dieses Verhalten ist zu dem bei der Filterung nach Zeiträumen, die bereits erklärt wurde, identisch. In der Tat hat es ja auch wenig Sinn, beim Filtern von Artikeln Verkaufs- oder Einkaufsbestellungszeilen zu behalten, die nun zu keinem Artikel gehören, weil die entsprechenden Artikel bereits herausgefiltert wurden.

Das Filtern von Artikel wirkt sich auf den Definitionsbereich neuberechneter Vektoren aus. Lassen Sie uns an einem kleinen Abschnitt vom Skript veranschaulichen.
where StockOnHand > 5
  GreaterThanFive = "yes"
  show table "Hello" with
  Name
  GreaterThanFive // CORRECT!

// ab dieser Zeile sind wir außerhalb des Filterblocks
show table "Hello" with
  Name
  GreaterThanFive // WRONG!
Zeile 10 ist falsch, da der Vektor GreaterThanFive nur für Zeilen definiert wurde, für die die Bedingung StockOnHand > 5 wahr ist. Daher kann dieser Vektor, da er innerhalb der Blocks richtig definiert ist, im Block genutzt werden, wie aus Zeile 5 hervorgeht. Hingegen kann dieser Vektor nicht außerhalb des Filterblocks genutzt werden, da dann einige Werte nicht definiert wären. Dies kann man lösen, indem man sich vergewissert, dass der Vektor für alle Artikelwerte korrekt definiert ist, wie unten gezeigt wird.
GreaterThanFive = "no"

where StockOnHand > 5
  GreaterThanFive = "yes"
  show table "Hello" with
  Name
  GreaterThanFive // RICHTIG!

// ab dieser Zeile sind wir außerhalb des Filterblocks
show table "Hello" with
  Name
  GreaterThanFive // CORRECT!
Dieses Snippet beginnt in Zeile 1 mit einer passenden Definition des Vektors GreaterThanFive für alle Artikel. Diese Definition wird in Zeile 4 für einen Teil der Artikel überarbeitet. Doch diese Überarbeitung ändert nichts an der Tatsache, dass der Vektor GreaterThanFive für alle Artikel explizit definiert wurde. Folglich stimmt nun die Anzeige auf Zeile 12.

Filtern von beliebigen Tabellen

Generell ist das Filtern nach Datum oder von Artikeln sehr nützlich, doch manchmal muss man eine bestimmte Tabelle filtern. Dies kann auch mit dem Schlüsselwort where getan werden. Sehen wir uns die Zeilen an, die diese Fähigkeit Envisions zeigen.
  where O.NetAmount > 1000
    show table "Large transactions over $1000" a4f5 tomato with
      Id
      Name
      O.Date
      O.Quantity
      O.NetAmount
      O.Client
Hiermit wird die O Tabelle gefiltert, um alle Zeilen der Tabelle, die kleiner als 1000$ sind herauszufiltern. Die Zeilen, die nicht herausgefiltert werden, werden dann durch show table in Zeilen 1, 2 und 3 angezeigt. Das Beispiel zeigt, wie eine einzige Tabelle gefiltert werden kann. Dieser Filter wirkt sich nur auf die O Tabelle aus. Die restlichen Tabellen bleiben von dieser Bedingung unberührt.

Wird ein Vektor, der mit der O Tabelle assoziiert ist, in einem Filterblock berechnet, ist der Zugang zu diesem Vektor vom Block selbst eingeschränkt. Wir haben dieses Verhalten bereits für die Artikel gesehen. Nun sehen wir uns genauer an, wie dies auf beliebige Tabellen angewandt werden kann.
where O.NetAmount > 1000
  O.LargeTxn = "yes"
  show table "Large transactions" with
  Name
  Orders.LargeTxn // CORRECT!
// letzte Blockzeile
// Einrückung verringert, wir sind außerhalb des Blocks
show table "Large transactions" with
 Name
 Orders.LargeTxn // WRONG!
Da der Vektor O.LargeTxn nicht für alle Zeilen der O Tabelle definiert ist, ist nur Zeile 5 richtig, während Zeile 10 falsch ist. Wie im vorherigen Beispiel kann dieses Skript repariert werden, indem ein LargeTxn Wert richtig für die gesamte O Tabelle definiert wird. Dies kann mit folgendem Skript gelöst werden.
Orders.LargeTxn = "no"
where O.NetAmount > 1000
  O.LargeTxn = "yes"
  show table "Large transactions" with
  Name
  O.LargeTxn // CORRECT!
// letzte Blockzeile
// Einrückung verringert, wir sind außerhalb des Blocks
show table "Large transactions" with
Name
O.LargeTxn // CORRECT!
Im Allgemeinen versucht Envision, so gut wie möglich, „Undichtheiten“ aus dem Block zu vermeiden: Ein in einem Block berechneter Vektor kann außerhalb des Blocks nur dann benutzt werden, wenn diese Nutzung nicht gegen die Regel verstößt, dass alle Vektorwerte explizit definiert werden, wenn der Vektor auf der rechten Seite der Zuordnung auftaucht.

Syntaktische Zucker zum Filtern

Die von Envision genutzten syntaktischen Muster zum Filtern filter-and-indent (filtern und einrücken) sind kurz und lesbar. Doch wenn mehrere Filter im Spiel sind, kann es schwer werden, die Einrückung zu entziffern. Daher bietet Envision verschiedene syntaktische Zucker, d.h. alternative Syntax, die etwas weniger Einrückungen benötigen. In diesem Abschnitt gehen wir auf diese Syntax näher ein.

Einrückungen bei mehreren Filtern überspringen

Envision benötig nur 1 zusätzliche Einrückungsebene pro Filter, wenn Filter unabhängig voneinander benutzt werden sollen. Wenn nur der innerste Gültigkeitsbereich interessant ist, wird nur eine einzige Einrückungsebene benötigt, wie hier gezeigt wird:
// jeder 'where'-Filter hat seine
// eigene Einrückungsebene
where O.Quantity > 10
where StockOnHand < 100
show table "Filtered orders" with
O.Quantity

// doch wenn mehrere Filter benutzt werden,
// ist nur eine Einrückung erforderlich
where O.Quantity > 10
where StockOnHand < 100 // keine Einrückung hier!
show table "Filtered orders" with O.Quantity
Der zweite Block verfügt über dieselbe Semantik des ersten, aber bedarf nur einer Einrückung. Verallgemeinert lautet die Syntax:
where A
when B
where C
show table "Filtered by A, B and C" with X
// wie
where A
when B
where C
show table "Filtered by A, B and C" with X

Zusammenführung von Filtern mit dem and-Schlüsselwort

Wir konnten bereits sehen, dass in Envision der Boolesche Operator AND durch das Symbol & dargestellt wird. Doch Envision bietet auch ein and-Schlüsselwort, das eine etwas andere Semantik besitzt:
// beide verschachtelten 'where'-Filter
where O.NetAmount > 1000 
where StockOnHand > 10
show table "Filtered transactions" with
Name
O.Quantity

// können mit 'and' als ein einziger Filter geschrieben werden
where O.NetAmount > 1000 and StockOnHand > 10
show table "Filtered transactions" with
Name
O.Quantity
Die Nutzung des and-Schlüsselworts ist strikt der Verschachtelung von where-Filtern gleichwertig. Über das and-Schlüsselwort ist es möglich, mehrere Filter nacheinander mit nur einer Einrückungsebene einzuführen. Einfach gesagt, ergibt das:
where A
where B
where C
// abgeschnitten

// kann auch so geschrieben werden
where A and B and C
// abgeschnitten
In der Praxis bietet das and-Schlüsselwort die Möglichkeit, mehrere Filter, die nicht unabhängig voneinander funktionieren sollen, zusammenzuführen.

Keine Einrückung mit dem keep-Schlüsselwort

Ein häufiges Code-Muster ist die Einführung von Filtern am Anfang des Skripts, um die Datenanalyse auf einen bestimmten Gültigkeitsbereich einzuschränken. Während die Filter-Syntax in Envision für solche Fälle ziemlich gut funktioniert, ist das Envision-Skript letzten Endes auf eine oder zwei Einrückungsebenen geschrieben. Hier bietet das keep-Schlüsselwort die Möglichkeit, diese Einrückungen zu beseitigen:
// der 'where'-Filter führt einen eingerückten Block ein
where O.Quantity > 10
// Anfang des Blocks
show table "Inside the filter" with
sum(O.Quantity)
// Ende des Blocks
show table "Outside the filter" with
sum(O.Quantity)

// doch wenn 'keep' benutzt wird,
// wird der Filter ohne Einrückung angewendet
keep where O.Quantity > 10
show table "Inside the filter" with
sum(O.Quantity)
Das keep-Schlüsselwort sollte vor where oder when stehen und zeigt an, dass der Filter ohne Einrückung bis zum Ende des Gültigkeitsbereichs wirkt.
where A
keep where B
show table "Filtered by A and B" with X
// Ende von Filtern A und B
show table "Not filtered" with X
Folglich greift der Filter bis zum Ende des Envision-Skripts, wenn keep in einem Skript ohne Einrückung steht.

Inline-Filter mit Suffixen

Bisher waren alle Filter, die wir vorgestellt haben, als Filterblock geschrieben. Doch Envision bietet auch eine alternative und kompaktere Syntax, die sogenannten Bedingungssuffixe. Gehen wir zurück zur Berechnung der im letzten Jahr verkauften Mengen.
when date > oend - 365
  LastYearQty = sum(O.Quantity)
Dieses Skript kann auch so geschrieben werden:
LastYearQty = sum(O.Quantity) when date > oend - 365
Für diejenigen, die Kenntnisse von relationalen Datenbanken haben, kann diese Syntax etwas ähnlicher zu den where Bedingungen in SQL sein. In Envision ist diese Syntax hauptsächlich syntaktischer Zucker, um die Einführung eines einzeiligen Blocks, in dem nur eine Anweisung geschrieben werden würde, zu verhindern. Sowohl die where als auch die where Bedingung kann als „Suffix“ ganz rechts an der Zuweisung gesetzt werden.

Die Aggregatoren können inline über die Bedingungen when oder where gefiltert werden. Außerdem bietet Envision die Möglichkeit, diesen Bedingungen einen else-Modifizierer hinzuzufügen. So wäre es beispielsweise falsch Folgendes zu schreiben:
oend := max(O.Date)
lastDay := monday(oend)
Week.sold := sum(O.NetAmount) when date < lastDay
show linechart "Sold by week" with
Week.sold // FALSCH
Da Week.sold nicht im gesamten Ergebnis definiert ist, weil es in der darüberstehenden Zeilen gefiltert wurde. Doch wenn man die Option else hinzufügt, wird Week.sold überall richtig definiert und kann somit angezeigt werden:
oend := max(O.Date)
lastDay := monday(oend)
Week.sold := sum(O.NetAmount) when date < lastDay else 0
show linechart "Sold by week" with
Week.sold // RICHTIG