将异质时间序列添加到数据框中

6

目标

我有一些不同产品的金融交易数据,以CSV格式存储,希望使用pandas进行分析。交易发生的时间间隔不规则,并且时间戳精确到1秒,这导致某些交易“同时”发生,即具有相同的时间戳。

目前的目标是为每个产品生成累计交易数量的图表。

当前进展

使用read_csv()函数将交易数据读入DataFrame,索引为解析后的日期时间。

<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 447 entries, 2012-12-07 17:16:46 to 2012-12-10 16:28:29
Data columns:
Account Name    447  non-null values
Exchange        447  non-null values
Instrument      447  non-null values
Fill ID         447  non-null values
Side            447  non-null values
Quantity        447  non-null values
Price           447  non-null values
dtypes: float64(1), int64(1), object(5)

我做了一点工作来添加一个“QuantitySigned”列。

我进行了“groupby”操作,以便可以按仪器访问数据。

grouped = trades.groupby('Instrument', sort=True)
for name, group in grouped:
        group.QuantitySigned.cumsum().plot(label=name)
plt.legend()

问题

上述方法是可行的,但我想把每个工具的TimeSeries放到一个DataFrame中,也就是说每个工具都有一列,这样我就可以使用DataFrame.plot()了。 问题是没有两个TimeSeries的索引完全相同,也就是说我需要合并所有TimeSeries的索引。

我知道这是可行的,因为下面有个简单的例子:

index=pd.date_range('2012-12-21', periods=5)
s1 = Series(randn(3), index=index[:3])
s2 = Series(randn(3), index=index[2:])
df = DataFrame(index=index)
df['s1'] = s1
df['s2'] = s2

然而,当尝试将TimeSeries聚合到DataFrame中时,会抛出异常,我认为这与索引元素重复有关:

grouped = trades.groupby('Instrument', sort=True)
df = DataFrame(index=trades.index)
for name, group in grouped:
        df[name] = group.QuantitySigned.cumsum()
df.plot()

Exception: Reindexing only valid with uniquely valued Index objects

我这样做“正确”吗?有没有更好的方法建议?

可运行示例

这是一个可运行的示例,会抛出异常:

import pandas as pd
from pandas import Series
from pandas import DataFrame

index = pd.tseries.index.DatetimeIndex(['2012-12-22', '2012-12-23', '2012-12-23'])

s1 = Series(randn(2), index[:2]) # No duplicate index elements
df1 = DataFrame(s1, index=index) # This works

s2 = Series(randn(2), index[-2:]) # Duplicate index elements
df2 = DataFrame(s2, index=index) # This throws

解决方案

感谢@crewbum提供的解决方案。

grouped = trades.groupby('Instrument', sort=True)
dflist = list()
for name, group in grouped:
    dflist.append(DataFrame({name : group.QuantitySigned.cumsum()}))
results = pd.concat(dflist)
results = results.sort().ffill().fillna(0)
results.plot()

注意:在将剩余的NaN设置为零之前,我先进行了前向填充。正如@crewbum指出的那样,ffill()和bfill()是新版本的0.10.0。
我使用的是: - pandas 0.10.0 - numpy 1.6.1 - Python 2.7.3.

我找到了一个类似的问题。我尝试了Wes建议的方法,但是我仍然遇到了相同的异常。 - commander.trout
你能提供一个包含样本数据且能够运行的示例,以阐明这个问题吗? - BrenBarn
@BrenBarn 我已经在原帖中添加了一个可运行的示例。反思一下,我认为我可以理解为什么DataFrame不支持这种行为。对于传入的“重复”TimeSeries元素属于哪一行是不明确的。尽管如此,我仍然希望听到任何关于如何使其工作或其他方法的建议。 - commander.trout
1个回答

3

pd.concat() 默认在索引上执行“outer”连接,可以通过向前和/或向后填充来填补空洞。

In [17]: pd.concat([DataFrame({'s1': s1}), DataFrame({'s2': s2})]).ffill().bfill()
Out[17]: 
                 s1   s2
2012-12-21  9.0e-01 -0.3
2012-12-22  5.0e-03 -0.3
2012-12-23 -2.9e-01 -0.3
2012-12-23 -2.9e-01 -0.3
2012-12-24 -2.9e-01 -1.8
2012-12-25 -2.9e-01 -1.4

我应该补充的是,ffill()bfill()在pandas 0.10.0中是新功能。 在此之前,您可以使用fillna(method='ffill')fillna(method='bfill')


谢谢!我会将我的最终解决方案添加到原帖中。 - commander.trout

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接