Python 大熊猫的一列
我试图将一列(好吧,很多)收益数据转换为一列收盘价。在Clojure中,我会使用,它类似于Python 大熊猫的一列,python,pandas,Python,Pandas,我试图将一列(好吧,很多)收益数据转换为一列收盘价。在Clojure中,我会使用,它类似于reduce,但会返回所有中间值的序列 e、 g 注:实际收盘价并不重要,因此使用1作为初始值。我只需要一个“模拟”收盘价 我的数据的实际结构是TimeSeries的命名列的数据帧。我想我正在寻找一个类似于applymap的函数,但我不希望对该函数做一些不规范的操作,并从其中引用DF(我想这是解决这个问题的一个方法?) 此外,如果我想保留返回的数据,但有收盘价,我会怎么做?我是否应该返回一个元组,并使时间序
reduce
,但会返回所有中间值的序列
e、 g
注:实际收盘价并不重要,因此使用1作为初始值。我只需要一个“模拟”收盘价
我的数据的实际结构是TimeSeries的命名列的数据帧。我想我正在寻找一个类似于applymap
的函数,但我不希望对该函数做一些不规范的操作,并从其中引用DF(我想这是解决这个问题的一个方法?)
此外,如果我想保留
返回的数据,但有收盘价,我会怎么做?我是否应该返回一个元组,并使时间序列的类型为(返回,收盘价)
?它看起来还不是一个广为宣传的功能,但您可以使用扩展\u应用
来实现返回计算:
In [1]: s
Out[1]:
0 0.12
1 -0.13
2 0.23
3 0.17
4 0.29
5 -0.11
In [2]: pd.expanding_apply(s ,lambda s: reduce(lambda x, y: x * (1+y), s, 1))
Out[2]:
0 1.120000
1 0.974400
2 1.198512
3 1.402259
4 1.808914
5 1.609934
我不是百分之百确定,但我相信扩展\u apply
适用于从第一个索引到当前索引的应用系列。我使用内置的reduce
函数,其工作原理与Clojure函数完全相同
用于扩展应用的文档字符串
:
Generic expanding function application
Parameters
----------
arg : Series, DataFrame
func : function
Must produce a single value from an ndarray input
min_periods : int
Minimum number of observations in window required to have a value
freq : None or string alias / date offset object, default=None
Frequency to conform to before computing statistic
center : boolean, default False
Whether the label should correspond with center of window
Returns
-------
y : type of input argument
值得注意的是,使用pandas编写更详细的内容通常比使用
reduce
编写更快(也更容易理解)
在您的具体示例中,我只想然后:
或者init*c.add(1.cumprod()
注意:但是,在某些情况下,例如内存问题,您可能必须以更低级/更聪明的方式重写这些内容,但通常值得先尝试最简单的方法(并对其进行测试,例如使用%timeit或)。为了可读性,我更喜欢以下解决方案:
returns = pd.Series([0.12, -.13, 0.23, 0.17, 0.29, -0.11])
initial_value = 100
cum_growth = initial_value * (1 + returns).cumprod()
>>> cum_growth
0 112.000000
1 97.440000
2 119.851200
3 140.225904
4 180.891416
5 160.993360
dtype: float64
如果要在序列中包含初始值,请执行以下操作:
>>> pd.concat([pd.Series(initial_value), cum_growth]).reset_index(drop=True)
0 100.000000
1 112.000000
2 97.440000
3 119.851200
4 140.225904
5 180.891416
6 160.993360
dtype: float64
啊,函数本身不是问题(应该写在上面);这很容易。对我来说,问题在于数据帧列的(惯用的、适当的)应用程序。不过,谢谢!你对问题的描述抽象起来有点难理解。你能提供你实际格式的样本数据,并举例说明你想要它做什么吗?这是一个非常有趣的函数,我期待着使用它。谢谢,谢谢!这是可行的,除了我需要弄清楚如何在这里处理NaN数据(现在,只需使用一个简单的检查,例如,
lambda x,y:x*(1+y)if pd.notnull(y)else x
),但这不是一个很好的方法,原因很明显……对于这个特定的示例(即使有1000个条目)也值得注意它比上面的扩展应用程序要快得多。啊,现在将pandas更新到0.10.1;这应该可以解决这个问题。你可以做(c+1)。cumprod()
。安迪的解决方案也有同样的错误+1。这比我建议的要快得多。@Zelazny7当我键入这个时,我认为你的方法可能会更快(我可以想象一些可能的例子),但首先尝试最简单(最具pythonic?)的方法肯定是个好主意:)
returns = pd.Series([0.12, -.13, 0.23, 0.17, 0.29, -0.11])
initial_value = 100
cum_growth = initial_value * (1 + returns).cumprod()
>>> cum_growth
0 112.000000
1 97.440000
2 119.851200
3 140.225904
4 180.891416
5 160.993360
dtype: float64
>>> pd.concat([pd.Series(initial_value), cum_growth]).reset_index(drop=True)
0 100.000000
1 112.000000
2 97.440000
3 119.851200
4 140.225904
5 180.891416
6 160.993360
dtype: float64