Ich lerne q über die kdb-Datenbank. Ich bin besorgt über die Tatsache, dass es keine Schleifen in q gibt. Ich muss einen Algorithmus schreiben, den ich mit mehreren geschachtelten for-Schleifen in einem ausführlichen Programm wie C schreiben würde. Aber in q bin ich fest davon, dass ich keine Schleife machen kann.
Nur um ein konkretes Beispiel zu geben (eines von vielen), habe ich diesen einfachen Vektor (Spaltentabelle):
%Vor%Ich brauche einen Vektor, der 3by3 diese Einträge gruppiert, mit Überlagerung, wie (mit R-Syntax): Verschlüsse [0: 2], Verschlüsse [1: 3], Verschlüsse [2: 4], Verschlüsse [3: 5] ... Wie kann ich tun?
Im Allgemeinen, wie muss ich meine Mentalität ändern, um richtig in q zu programmieren?
Vielen Dank für Ihre Vorschläge Marco
Adressieren Sie Ihren letzten Punkt über "Wie muss ich meine Mentalität ändern, um richtig in q zu programmieren?":
Sie müssen über (/), scan (\) und .z.s statt Schleifen verwenden.
Zum Beispiel könnte Ihr Problem auf folgende Weise gelöst werden: (Beachten Sie, dass dies nicht die beste Lösung für Ihr spezielles Problem ist - Indexierung ist der bessere Ansatz dort - aber nichtsdestoweniger sollten diese Lösungen helfen, den Punkt zu verdeutlichen)
%Vor%ie iterieren Sie über die Liste, hacken Sie jedes Mal eine davon ab, nehmen Sie die erste 3 jeder Iteration
oder ähnlich
%Vor%d. rotieren Sie um das Achtfache, nehmen Sie die ersten 3 jeder Umdrehung
Verwendung eines .z.s Ansatzes
%Vor%d. Wenn mindestens 3 Elemente übrig sind, nehmen Sie zuerst die 3, dann hacken Sie das erste Element ab und wenden Sie dieselbe Funktion erneut auf die verkürzte Liste an.
Die Verwendung von over (/) würde in diesem Beispiel verschachtelt werden, aber im Allgemeinen ist es sinnvoll, "while" -Typkonstrukte zu ersetzen
%Vor%wird besser mit
erreicht %Vor%d. addiere 10, zehn mal mit einem Startwert (Nullwert) von Null.
%Vor%d. h. fügen Sie zufällige Zahlen zwischen 1 und 20 an, bis Sie 18 erreichen, und stoppen Sie dann.
wird besser mit
erreicht %Vor%z. B. eine Zufallszahl zwischen 1 und 20 anhängen, iterieren, solange die Prüffunktion true zurückgibt, beginnend mit () als Startwert
Es gibt viele andere Optionen für die Verwendung von scan und over, abhängig davon, ob die Funktion, über die Sie iterieren, monadisch / diadisch usw. ist.
Als allgemeine Verallgemeinerung: eine Schleife vom Typ "for i = 1: 10" kann in q mit "function each i" erreicht werden, Eine Schleife vom Typ "do" kann in q mit "function / [numOfTimes; seed]" erreicht werden, Eine Schleife vom Typ "while" kann in q mit "function / [booleanCheckFunction; seed]"
erreicht werdenQ hat traditionelle Schleifenkonstrukte: do um eine Anweisung mehrmals zu wiederholen und < a href="http://code.kx.com/q/ref/control/#while"> während zu wiederholen, während eine gegebene Bedingung gilt. Darüber hinaus, q "Adverbien" jedes , über , usw. können Sie eine Funktion über Elemente eines Vektors" loopen ".
Um jedoch die Vorteile von q voll auszunutzen, sollten Sie lernen, explizite Schleifen zu vermeiden.
Vereinfachen Sie Ihr konkretes Beispiel (um einen einfachen Vektor anstatt einer einspaltigen Tabelle zu verwenden), hier können Sie einen Vektor von Preisen neu gruppieren:
%Vor%So funktioniert es. (Denken Sie daran: q wird von rechts nach links ausgewertet.) Die Funktion prev verschiebt die Preise nach rechts der Vektor (vorangestellte Nullwerte am Anfang und Verwerfen des letzten Wertes:
%Vor% Wir kombinieren den ursprünglichen Preisvektor mit zwei in einer $ 3 \ mal n $ -Matrix verschobenen. Die Spalten dieser Matrix sind die Gruppen, die wir wollen. Die Funktion flip transponiert die Matrix so, dass Sie die Gruppen als Zeilen erhalten und schließlich die ersten beiden löschen Zeilen, die Nullwerte enthalten, indem Sie den Operator _
verwenden.
Wie bereits erwähnt, ist die Verwendung von Built-Ins immer schneller als die Iteration mit 'oder /. Deshalb benötigt der Code aus der Top-Antwort für eine Million Elemente eine Ewigkeit, bis er vollständig ist und GBs Heap verwendet. Die Indizierung Methode von JPC und Harshal ist Meilen schneller, aber der Flip oben ist noch dreimal schneller.
Sobald Sie die Daten in dem Format haben, das Sie benötigen, verwenden Sie einfach jedes , um Ihre Schließung anzuwenden die Elemente der Liste.
Immer im Auge zu behalten, was Sie sagen, ist eine gute Übung - KDB wird nichts für Sie optimieren.
Was Nested Loops betrifft, habe ich herausgefunden, dass es nützlich ist, eine Kreuzliste zu erstellen. ZB
'für i = 1: 10
%Vor%'
in q kannst du
%Vor%wobei g als
definiert ist %Vor%Hoffe das klärt auf. Was die Schließungen betrifft, so kennen sie dort die R-Syntax nicht. Kann helfen, wenn Sie sagen können, welche Ausgabe Sie wollen.
KDB Q ist eine Vektorverarbeitungssprache, ihre Stärke liegt in der Verarbeitung von Listen im Gegensatz zur Verarbeitung einzelner -Atome , wie sie regelmäßig in Imperativsprachen verwendet werden.
Wenn Ihnen das aber nicht bekannt ist, unterstützt Q Schleifen und kann in Fällen verwendet werden, in denen dies nicht anders aussieht! Hier ist ein Beispiel, das ich geschrieben hatte, als ich mit der Migration von Java zu KDB Q begann.
%Vor% Es hat auch do-while
kinda Syntax
Schauen Sie hier
nachTags und Links kdb