Python:条形图 - 绘制所有年份中 a) 年和 b) 季度的值总和

标签 python pandas conditional-statements bar-chart timeserieschart

我有时间序列数据,即按日期 (YYYY-MM-DD)、 yield 、盈亏、交易数量:

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) 损益总和

作者:

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 总和

加上一条垂直的虚线,穿过条形图,显示平均返回和盈亏。

我可以在 Excel 中完成它(实际上是添加具有相应 View 的列,然后将其绘制为透视图表),但更喜欢一种“自动化”方式,可以通过 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()

最佳答案

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

使用多重索引创建 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()

关于Python:条形图 - 绘制所有年份中 a) 年和 b) 季度的值总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50379670/

相关文章:

python - 如果索引和列相同,如何在单独的列中获取数据集的相关值

python - 如何将列表字典转换为 Pandas 中的数据框

oop - 所有面向对象的设计都可以归结为减少条件吗?

python - 如何检查字典中的值是否都具有相同的值 X?

python - 在python中加载模块

python - 列上的 Multiindiex str 替换

youtube - API-有什么方法可以验证播放列表ID?

javascript - 条件语句返回输入框中的值

python - 是否可以在每个训练步骤中获得目标函数值?

python - 如果 Pandas Python 中的单元格值为 -1,如何放置另一列的值