提问者:小点点

使用groupby和滚动平均的数据帧行数累计


作为我正在学习的课程的一部分,我需要计算火箭发射的每月累计总和并计算逐月滚动平均值,最后在绘图中显示这两个结果。

数据框包含日期发射场任务状态和其他一些不太重要的参数。日期格式为YYYY-MM-DD,每个不同的年月组合的项目数量各不相同。

输入数据如下所示:

Organisation    Location    Date    Detail  Rocket_Status   Price   Mission_Status
4323    RVSN USSR   Site 1/5, Baikonur Cosmodrome, Kazakhstan   1957-10-04 19:28:00+00:00   Sputnik 8K71PS | Sputnik-1  StatusRetired   63.23   Success
4322    RVSN USSR   Site 1/5, Baikonur Cosmodrome, Kazakhstan   1957-11-03 02:30:00+00:00   Sputnik 8K71PS | Sputnik-2  StatusRetired   63.23   Success
4321    US Navy LC-18A, Cape Canaveral AFS, Florida, USA    1957-12-06 16:44:00+00:00   Vanguard | Vanguard TV3 StatusRetired   63.23   Failure

我的做法是:

  • 使用groupby和鸡蛋函数创建一个单独的df:
launchdays = pd.DataFrame(spacerace.groupby(spacerace.loc[:,"Date"].dt.date).agg("size"))

此数据框包含以下数据:

            0
Date    
1957-10-04  1
1957-11-03  1
1957-12-06  1
1958-02-01  1
1958-02-05  1
  • 将索引更改为DateTimeIndex
launchdays.index = pd.to_datetime(launchdays.index)
  • 计算每月的发布次数和逐月滚动平均值:
monthly_data = launchdays.resample("M").sum()
rolling = launchdays.rolling(30).mean().dropna()

重采样后的月度数据:

            0
Date    
1957-10-31  1
1957-11-30  1
1957-12-31  1
1958-01-31  0
1958-02-28  2

滚动平均值:

            0
Date    
1958-12-18  1.03
1959-01-02  1.03
1959-02-17  1.03
1959-02-28  1.03
1959-04-13  1.03

这似乎有效,至少在我看来,输出是现实的——然而,我想确定我的方法是否正确和/或是否可以更优雅地完成。

谢谢!

另一个编辑:

我已经修复了收集月度数据和计算滚动平均值的部分:

monthly_data = launchdays.resample("30D").sum()
rolling = monthly_data.rolling(“30D").mean()

然而,它们现在都产生了完全相同的输出,这是意料之中的…也许我误解了这个练习中的一些东西?这个任务被定义为:“绘制直到现在的每月发射次数图表。哪个月的发射次数是有史以来最高的?在每月时间序列图表上叠加滚动平均值。”


共1个答案

匿名用户

我不知道我是否理解你的实际问题,我不喜欢争论优雅vs不优雅的解决方案。如果它们有效,它们是好的。如果另一个解决方案更好,取决于你比较同一问题的不同解决方案的方式,例如需要更少的时间,或更少的内存,或更少的代码行等。

回到你的问题,滚动平均和重采样和是有区别的。滚动平均是一种平滑数据的方法,以给出正确的趋势,参见https://en.wikipedia.org/wiki/Moving_average.相反,重新取样和和方法是对绑定数据的数据聚合,基本上是直方图https://en.wikipedia.org/wiki/Histogram.

所以如果问题是关于哪个月的启动次数最多,你需要计算直方图并找到最大值。

你练习中的滚动平均值部分没有很好地定义,因为它没有给出窗口大小或至少给出更多信息为什么你应该平滑数据。它肯定应该超过30天,因为有超过30天的月份。我猜它们的意思是像一年(12个月)的窗口,但这纯粹是猜测。

编辑:我认为它们的意思是这样的:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

np.random.seed(7)
pd.plotting.register_matplotlib_converters()

# create dummy data
dates = (
    pd.Timestamp('1970-01-01') +
    pd.to_timedelta(np.random.randint(0, 19000, 20000), unit='D')
)
success = np.random.random(len(dates)) > 0.05
df = pd.DataFrame({
    'date': dates,
    'success': success
})
df.sort_values('date', inplace=True)
df.reset_index(drop=True, inplace=True)

# create histogram
monthly = df['date'].groupby(
    df['date'].dt.to_period('M').dt.to_timestamp()
).count()
print(monthly.loc[monthly==monthly.max()])

# add zeros for months that do not appear in the original histogram
monthly_dense = monthly.resample('MS').sum()

# plot
fig, ax = plt.subplots()
ax.plot(monthly_dense.index, monthly_dense)
ax.plot(monthly_dense.index, monthly_dense.rolling(12).mean())
fig.autofmt_xdate()