【问题标题】:Python: Bar chart - plot sum of values by a) year and b) quarter across all yearsPython:条形图 - 绘制所有年份的 a) 年份和 b) 季度的值总和
【发布时间】:2018-05-16 20:50:24
【问题描述】:

我有时间序列数据,即按日期 (YYYY-MM-DD)、收益、pnl、交易次数:

date             returns       pnl      no_trades
1998-01-01         0.01        0.05         5
1998-01-02        -0.04        0.12         2
...
2010-12-31         0.05        0.25         3

现在我想显示水平条形图 a) 平均收益 b) pnls 的总和

作者:

1) 年,即 1998、1999、...、2010

2) 所有年份的季度,即 Q1(YYYY-01-01 至 YYYY-03-31)、Q2、..、Q4

此外,每 1) 和 2) 的交易次数之和应表示每个水平条旁边的数字。

所以在我看来,需要两个独立的步骤:

1) 以正确的格式获取数据

2) 将数据输入绘图,然后叠加多个绘图。

样本数据:

start = datetime(1998, 1, 1)
end = datetime(2001, 12, 31)
dates = pd.date_range(start, end, freq = 'D')

df = pd.DataFrame(np.random.randn(len(dates), 3), index = dates, 
                  columns = ['returns', 'pnl', 'no_trades'])

所以这可能是两个分别代表年份和季度的水平条形图:

1) 一个用于返回:条形图,条形中间的数字,条形末尾的 no_trades 总和

2) 一个用于 pnl:条形图,条形中间的数字,条形末尾的 no_trades 总和

加上一条横穿条形的虚线垂直线,显示平均回报率和 pnl。

我可以在 excel 中执行此操作(实际上是在相应视图中添加列,然后对其进行透视图),但更喜欢一种“自动化”方式,可以通过 python 重现(或了解它是如何完成的)。

编辑:正如下面评论中所讨论的,这就是我已经走了多远;但是,我不确定这是否是关于 1) 最快的方法。我目前正在研究2)。

df_ret_year = df[['date', 'returns']].groupby(df['date'].dt.year).mean()
df_ret_quarter = df[['date', 'returns']].groupby(df['date'].dt.quarter).mean()

df_pnl_year = df[['date', 'pnl']].groupby(df['date'].dt.year).sum()
df_pnl_quarter = df[['date', 'pnl']].groupby(df['date'].dt.quarter).sum()

df_trades_year = df[['date', 'pnl']].groupby(df['date'].dt.year).sum()
df_trades_quarter = df[['date', 'pnl']].groupby(df['date'].dt.quarter).sum()

【问题讨论】:

  • 听起来您希望有人为您编写代码... SO 在这里帮助那些在代码中遇到特定问题的程序员,在他们进行了很好的尝试之后。如果您尝试过某事,但在某个点上卡住了,请告诉我们您尝试过什么以及难以实现什么,我相信有人会帮助您
  • 如果遇到这种情况,请道歉。事实上,我已经被第 1 步卡住了,以获取季度分组的相应子组。一般来说,正如我所写,我会创建另一列 yearquarter 并按总和分组。我会在我的答案中更新我到目前为止所获得的信息
  • 太棒了!仅供参考,很多人确实尝试使用 SO 作为免费的编码服务,这就是为什么在你的问题中表明这不是你的意图总是好的。

标签: python pandas conditional bar-chart timeserieschart


【解决方案1】:
start = datetime(1998, 1, 1)
end = datetime(2001, 12, 31)
dates = pd.date_range(start, end, freq = 'D')

使用 MultiIndex -(年,季度)创建 DataFrame

index = pd.MultiIndex.from_tuples([(thing.year, thing.quarter) for thing in dates])
df = pd.DataFrame(np.random.randn(len(dates), 3), index = index, 
                  columns = ['returns', 'pnl', 'no_trades'])

然后你可以按年、季或年季分组:

gb_yr = df.groupby(level=0)
gb_qtr = df.groupby(level=1)
gb_yr_qtr = df.groupby(level=(0,1))

>>> 
>>> # yearly means
>>> gb_yr.mean()
       returns       pnl  no_trades
1998  0.080989 -0.019115   0.142576
1999 -0.040881 -0.005331   0.029815
2000 -0.036227 -0.100028  -0.009175
2001  0.097230 -0.019342  -0.089498
>>> 
>>> # quarterly means across all years
>>> gb_qtr.mean()
    returns       pnl  no_trades
1  0.036992  0.023923   0.048497
2  0.053445 -0.039583   0.076721
3  0.003891 -0.016180   0.004619
4  0.007145 -0.111050  -0.054988
>>> 
>>> # means by year and quarter
>>> gb_yr_qtr.mean()
         returns       pnl  no_trades
1998 1 -0.062570  0.139856   0.105288
     2  0.044946 -0.008685   0.200393
     3  0.152209  0.007341   0.119093
     4  0.185858 -0.211401   0.145347
1999 1  0.085799  0.072655   0.054060
     2  0.111595  0.002972   0.068792
     3 -0.194506 -0.093435   0.107210
     4 -0.161999 -0.001732  -0.109851
2000 1  0.001543 -0.083488   0.174226
     2 -0.064343 -0.158431  -0.071415
     3 -0.036334 -0.037008  -0.068717
     4 -0.045669 -0.121640  -0.069474
2001 1  0.123592 -0.032138  -0.140982
     2  0.121582  0.005810   0.109115
     3  0.094194  0.058382  -0.139110
     4  0.050388 -0.109429  -0.185975
>>>
>>> # operate on single columns
>>> gb_yr['pnl'].sum()
1998    -6.976917
1999    -1.945935
2000   -36.610206
2001    -7.060010
Name: pnl, dtype: float64

>>> # plotting
>>> from matplotlib import pyplot as plt
>>> gb_yr.mean().plot()
<matplotlib.axes._subplots.AxesSubplot object at 0x000000000C04BF28>
>>> plt.show()
>>> plt.close()

【讨论】:

  • 感谢@wwii 的多索引!事实上,我可以每年显示 4 个条形图(每个季度也有 1 个条形图)。
  • @eternity1 与 MultiIndex 你甚至可能不需要 groupby 的 - 看看文档的 MultiIndex 部分,有一些非常灵活的索引方法可能会避免 groupby 的 - pandas.pydata.org/pandas-docs/stable/advanced.html跨度>
猜你喜欢
  • 2022-10-13
  • 1970-01-01
  • 2018-05-16
  • 1970-01-01
  • 2018-01-05
  • 2020-11-11
  • 2018-05-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多