Warum ist die Aufteilung auf große Datenrahmen mit vielen Gruppen ineffizient?

8
%Vor%

wird für eine große Anzahl von eindeutigen Werten von x langsam. Wenn wir den Datenrahmen stattdessen manuell in kleinere Teilmengen aufteilen und dann auf jeder Teilmenge aufteilen, reduzieren wir die Zeit um mindestens eine Größenordnung.

%Vor%

Running microbenchmark gibt uns

%Vor%

Ist split nicht für große Gruppen gedacht? Gibt es Alternativen neben der manuellen ersten Teilmenge?

Mein Laptop ist ein Macbook Pro Ende 2013, 2,4 GHz 8GB

    
Rickard 17.09.2016, 09:53
quelle

2 Antworten

2

Dies ist nicht unbedingt split.data.frame issue, es gibt ein allgemeineres Problem für die Skalierbarkeit von data.frame für viele Gruppen.
Wenn Sie split.data.table verwenden, können Sie eine sehr schöne Beschleunigung erzielen. Ich habe diese Methode zusätzlich zu regulären data.table-Methoden entwickelt und scheint hier ziemlich gut zu skalieren.

%Vor%

sorted=TRUE gibt die Liste derselben Reihenfolge zurück wie die data.frame-Methode. Die data.table-Methode speichert standardmäßig die in den Eingabedaten vorhandene Reihenfolge. Wenn du bei data.frame bleiben willst, kannst du am Ende lapply(l2, setDF) verwenden.

PS. split.data.table wurde in 1.9.7 hinzugefügt, die Installation der Devel-Version ist ziemlich einfach

%Vor%

Mehr dazu im Installations-Wiki .

    
jangorecki 17.09.2016, 15:25
quelle
8

Mehr eine Erklärung als eine Antwort. Das Subsetting eines großen data.frames ist kostspieliger als das Subsetting eines kleinen Datenframes

%Vor%

split() zahlt diese Kosten für jede Gruppe.

Der Grund kann durch Ausführen von Rprof()

gesehen werden %Vor%

Die gesamte Zeit wird in einem Anruf an attr() verbracht. Wenn Sie mit debug("[.data.frame") durch den Code gehen, wird der Aufruf wie folgt angezeigt:

%Vor%

Dieses kleine Beispiel zeigt einen Trick, den R verwendet, um zu vermeiden, dass Zeilennamen dargestellt werden, die nicht vorhanden sind: Verwenden Sie c(NA, -5L) anstatt 1:5 .

%Vor%

Beachten Sie, dass attr() einen Vektor zurückgibt - die row.names werden im Flug erzeugt, und für einen großen dat.frame wird eine große Anzahl von row.names erstellt.

%Vor%

Man könnte also erwarten, dass selbst unsinnige row.names die Berechnung beschleunigen würden

%Vor%

Auch das Teilen eines Vektors oder einer Matrix wäre schnell.

    
Martin Morgan 17.09.2016 15:05
quelle

Tags und Links