Pandas 将函数应用于系列的值和索引

Pandas 将函数应用于系列的值和索引,pandas,Pandas,我发现自己将一个函数应用于TimeSeries的值和索引。我这样做的方法是,构建一个包含时间序列的值和索引的数据帧,然后对数据帧应用一个函数 # imports import pandas as pd import numpy as np # Set up some input time series dates = pd.date_range('2012-04-01', periods=500,freq='MS') ts = pd.Series(np.arange(500), index=d

我发现自己将一个函数应用于TimeSeries的值和索引。我这样做的方法是,构建一个包含时间序列的值和索引的数据帧,然后对数据帧应用一个函数

# imports
import pandas as pd
import numpy as np

# Set up some input time series
dates = pd.date_range('2012-04-01', periods=500,freq='MS')
ts = pd.Series(np.arange(500), index=dates)

# Build data frame of values and index
tmp = pd.concat([ts, ts.index.to_series()], join='outer', axis=1)

# Example function to apply
f = lambda x: x[0] / 4 if x[1].month % 3 == 1 else 0

# Apply function
out = tmp.apply(f, axis=1)


我暗自怀疑,这不是最优雅/有效的方法,但我找不到任何东西来建议更好的路线。有什么想法吗?

您可以使用下面的数据帧来实现它,至少要优雅一点

ts = pd.DataFrame({ "data": np.arange(500) }, index=dates)
f = lambda x: x["data"] / 4 if x.name.month % 3 == 1 else 0
ts.apply(f, axis=1)

您可以使用
name
-属性访问数据帧元素的索引。

这是一个更有效的解决方案

s = Series(np.arange(500), index=dates)
(s/4).where(s.index.month % 3 == 1, 0)

我喜欢这个想法,并且与我当时的想法一致。问题是我不能让它工作,如果我应用你的精确代码(加上我的日期定义),我会得到一个类型错误:
TypeError:(/:'buffer'和'int'的不支持的操作数类型,u'发生在索引2012-04-01 00:00:00')
如果我在
的函数中调试。apply
ed我似乎只有一个值数组,在
x
中表示给定的数据行。我怀疑像
.name
这样的方法只能在
之外工作。apply
因为在内部,您不再真正使用DataFrame对象了抱歉,它现在已经被修复了(
df.data
返回内部存储,如果您将列命名为
“data”
您必须使用
df[“data”]
).而您/正在/处理
apply
内部的
DataFrame
对象。实际上,在
apply
内部,我们似乎正在处理一个
系列
对象,其名称是我们正在迭代的
DataFrame
的索引。这就是为什么您的名称建议可以用于访问索引的值。似乎
apply
会折叠起始对象的“维度”,因此这就是为什么直接处理
TimeSeries
只会给我留下一个值对象,而无法访问索引的值。这不是一个完美的解决方案,但比我现在的处境要好。再次感谢所有的帮助。这不起作用(尽管看起来应该如此!)。当我应用您的解决方案时,我得到
s
where
s.index.month%3==1
s/4
where
s.index.month%3!=1
;我想要
s/4
0
respectively@Jeff这是错误的,where的第三个参数是
inplace
,因此
0
在这里表示
False
,实际上是默认值。好的,我认为很容易启用,让我想想。你也可以做一个链接loc(相同的想法)真棒。开机速度快了近40倍!作为一个想法,它仅限于if语句求值,但这是一个足够常见的用例,使这个习惯用法值得使用。