2016-04-14 12 views
0

Ich habe eine Pandas-Serie, s1, und ich möchte eine neue Serie, s2, durch eine Funktion, die zwei Eingaben, um einen neuen Wert zu erstellen. Diese Funktion würde auf ein 2-Wert-Fenster auf s1 angewendet werden. Die resultierende Reihe, s2, sollte einen Wert weniger als s1 haben. Es gibt viele Möglichkeiten, dies zu erreichen, aber ich suche nach einer Möglichkeit, es sehr effizient zu machen. Dies ist auf Linux und ich laufe gerade Python 2.7 und 3.4 und Pandas 15.2, obwohl ich Pandas aktualisieren kann, wenn das notwendig ist. Hier ist eine Vereinfachung meines Problems. Meine Serie besteht aus Tonhöhen, die als Streicher dargestellt werden.Machen Sie eine Pandas-Serie, indem Sie eine Funktion auf alle benachbarten Werte ausführen

import pandas 
s1 = pandas.Series(['C4', 'E-4', 'G4', 'A-4') 

Ich möchte diese Funktion nutzen:

def interval_func(event1, event2): 
    ev1 = music21.note.Note(event1) 
    ev2 = music21.note.Note(event2) 
    intrvl = music21.interval.Interval(ev1, ev2) 
    return intrvl.name 

Auf s1 und eine verschobene Version von s1, die folgende Reihe zu bekommen:

s2 = pandas.Series(['m3', 'M3', 'm2']) 
+3

Falsches 'apply' kann einen Benutzer func oder lambda nehmen und kann 0-N params nehmen, Sie müssen Ihr Problem besser mit rohen Daten, Code und gewünschter Ausgabe definieren – EdChum

Antwort

1

Als Antwort auf Ihre bearbeiten Wir könnten versuchen, eine ähnliche .rolling-Methode zu verwenden, aber Pandas unterstützt derzeit keine nicht numerischen Typen in Rollen.

So können wir eine Liste Verständnis verwenden:

[music21.interval.Interval(music21.note.Note(s1[i]),\ 
          music21.note.Note(s1[i + 1])).name\ 
for i in range(len(s1)-1)] 

oder eine Anwendung:

import music21 
import pandas as pd 
import numpy as np 

s1 = pd.Series(['C4', 'E-4', 'G4', 'A-4']) 
df = pd.DataFrame({0:s1, 1:s1.shift(1)}) 

def myfunc(x): 
    if not any([pd.isnull(x[0]), pd.isnull(x[1])]): 
     return music21.interval.Interval(music21.note.Note(x[0]),music21.note.Note(x[1])).name 


df.apply(myfunc, axis = 1) 

nb, ich wäre überrascht, wenn die apply schneller als das Verständnis ist

+0

Diese Lösung würde definitiv funktionieren, aber die Laufzeit wird immer noch direkt mit der Länge der Serie verbunden sein. Ich hatte gehofft, .apply() oder etwas Ähnliches zu gebrauchen, um zu einer Lösung zu kommen, die in der Pandas-Bibliothek endemischer ist. – Alex

+0

Sie hatten recht, die Laufzeit ist für die beiden Implementierungen grundsätzlich gleich. – Alex