Fre*_*d S 5 python time-series pandas
想象一下每 30 分钟测量一次包含多个变量的数据框。此数据框中的每个时间序列在可能不同的位置都有间隙。这些差距将被某种运行平均值取代,比如说 +/- 2 天。例如,如果在第 4 天 07:30 我缺少数据,我想NaN用第 2、3、5 和 6 天 07:30 的测量值的平均值替换一个条目。请注意,对于例如,第 5 天 07:30 也是NaN- 在这种情况下,这应该从替换第 4 天丢失的测量值的平均值中排除(应该可以用np.nanmean?)
我不知道该怎么做。现在,我可能会遍历数据框中的每一行和每一列,并沿着np.mean(df.ix[[i-48, i, i+48], "A"]).
样本数据集:
import numpy as np
import pandas as pd
# generate a 1-week time series
dates = pd.date_range(start="2014-01-01 00:00", end="2014-01-07 00:00", freq="30min")
df = pd.DataFrame(np.random.randn(len(dates),3), index=dates, columns=("A", "B", "C"))
# generate some artificial gaps
df.ix["2014-01-04 10:00":"2014-01-04 11:00", "A"] = np.nan
df.ix["2014-01-04 12:30":"2014-01-04 14:00", "B"] = np.nan
df.ix["2014-01-04 09:30":"2014-01-04 15:00", "C"] = np.nan
print df["2014-01-04 08:00":"2014-01-04 16:00"]
A B C
2014-01-04 08:00:00 0.675720 2.186484 -0.033969
2014-01-04 08:30:00 -0.897217 1.332437 -2.618197
2014-01-04 09:00:00 0.299395 0.837023 1.346117
2014-01-04 09:30:00 0.223051 0.913047 NaN
2014-01-04 10:00:00 NaN 1.395480 NaN
2014-01-04 10:30:00 NaN -0.800921 NaN
2014-01-04 11:00:00 NaN -0.932760 NaN
2014-01-04 11:30:00 0.057219 -0.071280 NaN
2014-01-04 12:00:00 0.215810 -1.099531 NaN
2014-01-04 12:30:00 -0.532563 NaN NaN
2014-01-04 13:00:00 -0.697872 NaN NaN
2014-01-04 13:30:00 -0.028541 NaN NaN
2014-01-04 14:00:00 -0.073426 NaN NaN
2014-01-04 14:30:00 -1.187419 0.221636 NaN
2014-01-04 15:00:00 1.802449 0.144715 NaN
2014-01-04 15:30:00 0.446615 1.013915 -1.813272
2014-01-04 16:00:00 -0.410670 1.265309 -0.198607
[17 rows x 3 columns]
Run Code Online (Sandbox Code Playgroud)
(一个更复杂的工具也会从平均程序中排除测量值,这些测量值本身是由平均创建的,但这不一定必须包含在答案中,因为我相信这可能会使现在的事情变得太复杂。)
/edit:我不太满意的示例解决方案:
# specify the columns of df where gaps should be filled
cols = ["A", "B", "C"]
for col in cols:
for idx, rows in df.iterrows():
if np.isnan(df.ix[idx, col]):
# replace with mean of adjacent days
df.ix[idx, col] = np.nanmean(df.ix[[idx-48, idx+48], col])
Run Code Online (Sandbox Code Playgroud)
我不喜欢这个解决方案的两件事:
这应该是一种更快、更简洁的方法。最主要的是使用 shift() 函数而不是循环。简单的版本是这样的:
df[ df.isnull() ] = np.nanmean( [ df.shift(-48), df.shift(48) ] )
Run Code Online (Sandbox Code Playgroud)
事实证明很难概括这一点,但这似乎有效:
df[ df.isnull() ] = np.nanmean( [ df.shift(x).values for x in
range(-48*window,48*(window+1),48) ], axis=0 )
Run Code Online (Sandbox Code Playgroud)
我不确定,但怀疑 nanmean 可能存在错误,这也是您自己丢失值的原因。在我看来,如果您向 nanmean 提供数据帧,则 nanmean 无法处理 nan。但如果我转换为数组(带有 .values)并使用 axis=0 那么它似乎可以工作。
检查 window=1 的结果:
print df.ix["2014-01-04 12:30":"2014-01-04 14:00", "B"]
print df.ix["2014-01-03 12:30":"2014-01-03 14:00", "B"]
print df.ix["2014-01-05 12:30":"2014-01-05 14:00", "B"]
2014-01-04 12:30:00 0.940193 # was nan, now filled
2014-01-04 13:00:00 0.078160
2014-01-04 13:30:00 -0.662918
2014-01-04 14:00:00 -0.967121
2014-01-03 12:30:00 0.947915 # day before
2014-01-03 13:00:00 0.167218
2014-01-03 13:30:00 -0.391444
2014-01-03 14:00:00 -1.157040
2014-01-05 12:30:00 0.932471 # day after
2014-01-05 13:00:00 -0.010899
2014-01-05 13:30:00 -0.934391
2014-01-05 14:00:00 -0.777203
Run Code Online (Sandbox Code Playgroud)
关于问题#2,这取决于您的数据,但如果您在上述内容之前添加
df = df.resample('30min')
这将为您提供一行 nan 来填充所有缺失的行,然后您可以像所有其他 nan 一样填充它们。如果可行的话,这可能是最简单、最快的方法。
或者,您可以使用 groupby 做一些事情。我的 groupby-fu 很弱,但为了让你体验一下它的味道,比如:
df.groupby( df.index.hour ).fillna(method='pad')
可以正确处理缺失行的问题,但不能处理其他问题。
| 归档时间: |
|
| 查看次数: |
2043 次 |
| 最近记录: |