我的目标是计算存储在熊猫red
中的两个时间序列(green
和DataFrame
)的平均值。但是,尽管两个时间序列具有相同的列,但它们在精确的时间点上有所不同。我要实现的是一个函数average
,该函数根据两个给定序列计算平均时间序列,这样,如果在特定时间点缺少某个值,则应对其进行插值。 例如:
import pandas as pd
green_df = pd.DataFrame({'A': [4, 2, 5], 'B': [1, 2, 3]}, index=[1, 3, 6])
red_df = pd.DataFrame({'A': [4, 2.5, 8, 2, 4], 'B': [4, 2, 2, 4, 1]}, index=[1, 2, 4, 5, 6])
average_grey_df = pd.DataFrame({'A': [4, 2.7, 3.75, 5.5, 3, 4.5], 'B': [...]}, index= [1, 2, 3, 4, 5, 6])
assert average_grey_df == average(green_df, red_df)
以图形方式显示时很明显(A列显示的值,但所有列均应这样做;精确值仅是说明性的):
到目前为止,我还找不到完整的解决方案。我正在考虑将其分为三个步骤:
(1)将两个时间序列的时间点从另一个时间序列扩展,以使丢失的数据为nan
A | ... A | ...
------- -------
1 | 4 | 1 | 4 |
2 |nan| 2 |2.5|
red: 3 | 2 | green: 3 |nan|
4 |nan| 4 | 8 |
5 |nan| 5 | 2 |
6 | 5 | 6 | 4 |
(2)通过对两个数据帧进行插值来填充丢失的数据(直接使用dataframe interpolate method) (3)最终计算出这两个时间序列的平均值,如下所示:
averages = (green_df.stack() + red_df.stack()) / 2
average_grey_df = averages.unstack()
此外,方法dropna
可用于删除创建的nan
。而且,也许还有我没有发现的更好的方法。
我根本无法弄清楚如何计算第(1)部分。我通过各种示例检查了join
,merge
和concat
之类的方法,但似乎没有一个能胜任。有什么建议?我也对其他方法持开放态度。
谢谢
答案 0 :(得分:1)
您可以合并两个df。从那里,您可以插值NA值
green_df = pd.DataFrame({'A': [4, 2, 5], 'B': [1, 2, 3]}, index=[1, 3, 6])
red_df = pd.DataFrame({'A': [4, 2.5, 8, 2, 4], 'B': [4, 2, 2, 4, 1]}, index=[1, 2, 4, 5, 6])
combined_df = pd.merge(green_df, red_df, suffixes=('_green', '_red'), left_index=True, right_index=True, how='outer')
combined_df = combined_df.interpolate()
combined_df['A_avg'] = combined_df[["A_green", "A_red"]].mean(axis=1)
combined_df['B_avg'] = combined_df[["B_green", "B_red"]].mean(axis=1)
然后可以使用.plot()
绘制这些图形:
combined_df[['A_green', 'A_red', 'A_avg']].plot(color=['green', 'red', 'gray'])
答案 1 :(得分:1)
要执行任务1),您可以执行以下操作:
#union of the indexes
union_idx = green_df.index.union(red_df.index)
#reindex with the union
green_df= green_df.reindex(union_idx)
red_df= red_df.reindex(union_idx)
# the interpolation
green_df = green_df.interpolate(method='linear', limit_direction='forward', axis=0)
red_df = red_df.interpolate(method='linear', limit_direction='forward', axis=0)
grey_df= pd.concat([green_df,red_df])
grey_df= grey_df.groupby(level=0).mean()