在pandas中使用assign with time series data和groupby

时间:2016-11-15 22:40:26

标签: python pandas

我正在尝试为现有的pandas数据框mydf分配一个新列。要添加的系列是评估作为字符串传递的表达式的结果。表达式可以包含python函数调用,例如:

formula = 'myfunction(mydf.v1)'

myfunction如下

def myfunction(series):
    return recursive_filter(series, 0.1)

以下代码将评估表达式并执行myfunction并将列v2分配给mydf

mydf.assign(v2 = eval(formula))

但是,我需要Market执行该功能。输出应如下表所示

Market      Date          v1    v2
UK          2013-01-01    10   10.00
UK          2013-01-02    10   11.00 
UK          2013-01-03    10   11.10
UK          2013-01-04    10   11.11
US          2013-01-01    10   10.00
US          2013-01-02    10   11.00
US          2013-01-03    10   11.10
US          2013-01-04    10   11.11

我尝试了以下代码(我不确定会产生正确的结果......)

mydf.groupby('CrossSection').apply(mydf.assign(v2 = eval(formula)))

然而,这会产生此错误

TypeError: 'DataFrame' objects are mutable, thus they cannot be hashed

1 个答案:

答案 0 :(得分:0)

您遇到的一个问题是公式将DataFrame硬编码为应用它,即mydf

无论如何,这里应该有用。我找不到一种不创建另一个数据帧的方法,但是如果你的数据集不是很大,那就不重要了。

我重写了公式以接受将数据帧应用到的字符串格式。

from statsmodels.tsa.filters.filtertools import recursive_filter

formula = 'myfunction({}.v1)'
def myfunction(series):
    return recursive_filter(series, 0.1)

df2 = mydf.groupby('Market').apply(lambda df: df.assign(v2 = eval(formula.format("df"))))
df2.index = df2.index.droplevel(level=0)
df2

结果:

  Market        Date  v1     v2
0     UK  2013-01-01  10  10.00
1     UK  2013-01-02  10  11.00
2     UK  2013-01-03  10  11.10
3     UK  2013-01-04  10  11.11
4     US  2013-01-01  10  10.00
5     US  2013-01-02  10  11.00
6     US  2013-01-03  10  11.10
7     US  2013-01-04  10  11.11