我正在浏览pandas文档,试图理解如何使用transform,并可以从文档中找到这个例子:http://pandas.pydata.org/pandas-docs/stable/groupby.html(在"转换"下)
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
index = pd.date_range('10/1/1999', periods=1100)
ts = pd.Series(np.random.normal(0.5, 2, 1100), index)
ts = ts.rolling(window=100,min_periods=100).mean().dropna()
key = lambda x: x.year
zscore = lambda x: (x - x.mean()) / x.std()
transformed = ts.groupby(key).transform(zscore)
有几件事我很困惑;首先是lambda的用法。
key = lambda x: x.year
在这种情况下x应该代表什么数据类型?我不确定哪些数据类型允许调用属性".year"
对于这种情况:
zscore = lambda x: (x - x.mean()) / x.std()
x将代表ts的每一行,x。mean是什么的均值?
最后,transform在最后一行到底做了什么?它只是用zscore替换ts的值吗?我运行变量"转换",但索引(日期)看起来与它的索引相同。那么在这种情况下groupby(key)到底做了什么呢?
谢谢!
使用key = lambda x: x.year
意味着您的索引是dtype='datetime64[ns]'
这将调用每个索引的年份并按年份分组。
现在你有了一个groupby对象,你可以变换每个组:
zscore = lambda x: (x - x.mean()) / x.std()
将取每组(即每年)计算平均值(x.mean()
),标准差(x.std()
),并对每个数据点应用公式(x - x.mean()) / x.std()
。
ts.groupby(key).mean()
Out[274]:
2000 0.4851
2001 0.2568
2002 0.4544
返回每年的平均值,并执行以下操作:
ts.groupby(key).std()
Out[275]:
2000 0.1969
2001 0.1539
2002 0.1881
返回每年的标准差
变换将把它应用于每一行,所以让我们使用位置1作为测试
ts.head()
Out[277]:
2000-01-08 0.7562
2000-01-09 0.7639
2000-01-10 0.7020
2000-01-11 0.6970
2000-01-12 0.6906
由于第一个指数是2000年的,我们需要使用该组的平均值和STD,如:0.7562- 0.4851/0.1969 = 1.3767
ts.groupby(key).transform(zscore).head(2)
Out[282]:
2000-01-08 1.3767
2000-01-09 1.4159