2016-04-14 54 views
0

我有一个熊猫系列s1,我想通过应用一个函数来创建一个新的系列s2,该函数需要两个输入来创建一个新值。该函数将应用于s1上的2值窗口。结果系列s2的值应小于s1。 有很多方法可以做到这一点,但我正在寻找一种非常有效的方法。 这是在Linux上,我目前正在运行Python 2.7和3.4和熊猫15.2,但如果有必要,我可以更新熊猫。 这是我的问题的简化。我的系列包括以弦乐表现的音乐节目。通过在所有相邻值上运行函数来制作熊猫系列

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

我想使用此功能:

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

S1和S1的位移版本,得到以下几大系列:

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

不正确的'apply'可能需要用户func或lambda,并且可能需要0-N params,因此需要使用原始数据,代码和期望的输出来更好地定义问题 – EdChum

回答

1

在回答您的编辑,我们可以尝试使用类似的.rolling方法,但熊猫目前不支持roll中的非数字类型。

所以,我们可以用一个列表理解:

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

,或者一个应用:

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,我会感到惊讶,如果apply是比任何修真快

+0

此解决方案将绝对有效,但运行时间仍将直接与系列的长度相关联。我希望能够使用.apply()或类似的东西来达成一种更加适合熊猫图书馆的解决方案。 – Alex

+0

你说得对,两种实现的运行时基本相同。 – Alex