我有一些CSV格式的多种产品的金融交易数据,我想用熊猫来分析。交易以非定期的间隔发生,并且时间戳为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()
上述工作,但我希望在一个DataFrame中有TimeSeries(每个工具一个),即每个工具的一列,这样我就可以使用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的新东西。
我正在使用:
答案 0 :(得分:3)
pd.concat()默认情况下对索引执行“外部”连接,并且可以通过向前和/或向后填充填充孔。
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')
。