假设我们要构建一个股票投资组合。为了决定将哪些股票包含在投资组合中以及为这些股票分配什么权重,我们使用不同的指标,例如价格、每股 yield (eps)、股息 yield 等......所有这些指标都存储在单个 Pandas 数据框,其中行指定特定时间点,列与特定股票相关联(例如,IBM、MSFT 等):
import pandas as pd
price = pd.DataFrame([[-1.332298, 0.396217, 0.574269, -0.679972, -0.470584, 0.234379],
[-0.222567, 0.281202, -0.505856, -1.392477, 0.941539, 0.974867],
[-1.139867, -0.458111, -0.999498, 1.920840, 0.478174, -0.315904],
[-0.189720, -0.542432, -0.471642, 1.506206, -1.506439, 0.301714]],
columns=['IBM', 'MSFT', 'APPL', 'ORCL','FB','TWTR'],
index=pd.date_range('2000', freq='D', periods=4))
eps = pd.DataFrame([[-1.91, 1.63, 0.51, -.32, -0.84, 0.37],
[-0.56, 0.02, 0.56, 1.77, 0.99, 0.97],
[-1.67, -0.41, -0.98, 1.20, 0.74, -0.04],
[-0.80, -0.43, -0.12, 1.06, 1.59, 0.34]],
columns=['IBM', 'MSFT', 'APPL', 'ORCL','FB','TWTR'],
index=pd.date_range('2000', freq='D', periods=4))
price
IBM MSFT APPL ORCL FB TWTR
2000-01-01 -1.332298 0.396217 0.574269 -0.679972 -0.470584 0.234379
2000-01-02 -0.222567 0.281202 -0.505856 -1.392477 0.941539 0.974867
2000-01-03 -1.139867 -0.458111 -0.999498 1.920840 0.478174 -0.315904
2000-01-04 -0.189720 -0.542432 -0.471642 1.506206 -1.506439 0.301714
eps
IBM MSFT APPL ORCL FB TWTR
2000-01-01 -1.91 1.63 0.51 -0.32 -0.84 0.37
2000-01-02 -0.56 0.02 0.56 1.77 0.99 0.97
2000-01-03 -1.67 -0.41 -0.98 1.20 0.74 -0.04
2000-01-04 -0.80 -0.43 -0.12 1.06 1.59 0.34
不同的数据帧显然是紧密相连的。但是,它们都存储在单独的变量中。在大型应用程序中,很难跟踪哪些变量属于一起并形成一个连贯的单元。安排此类相关数据集的良好设计范式是什么?使用面向对象的设计模式,我将构造类似 StockList() 对象的东西,该对象存储单个 Stock() 对象,该对象又存储与特定股票对应的信息(时间序列)。
class Stock():
def __init__(self, price_series, eps_series, div_yield_series):
self.price = price_series
self.eps = eps_series
self.div_yield = div_yield_series
class StockList():
def __init__(self, stock_list):
self.stock_list = stock_list
def append(self, stock):
self.stock_list.append(stock)
但是,在使用数据框时,这是一个可行的选择吗?我认为将时间序列分开并在查询时将它们合并在一起,会导致性能的显着损失和一组多余的操作。或者, StockList() 可以直接存储数据帧,而无需构造单个 Stock() 对象(或多或少用作数据结构)。然而,这是一个适当的妥协吗?
我通常想知道是否应该创建一个单独的对象,或者是否应该将这些单独的数据帧作为单独的变量保留。这很可能会提高性能、减少内存使用、支持并行计算并培养函数式编程风格。
但是我们如何才能捆绑属于一起的数据呢?
最佳答案
此示例有 3 个度量,因此我将创建一个具有 3 级多索引的 Pandas 系列:
首先,根据原始帖子创建 eps 和 price 数据框:
import pandas as pd
price = pd.DataFrame([[-1.332298, 0.396217, 0.574269, -0.679972, -0.470584, 0.234379],
[-0.222567, 0.281202, -0.505856, -1.392477, 0.941539, 0.974867],
[-1.139867, -0.458111, -0.999498, 1.920840, 0.478174, -0.315904],
[-0.189720, -0.542432, -0.471642, 1.506206, -1.506439, 0.301714]],
columns=['IBM', 'MSFT', 'APPL', 'ORCL','FB','TWTR'],
index=pd.date_range('2000', freq='D', periods=4))
eps = pd.DataFrame([[-1.91, 1.63, 0.51, -.32, -0.84, 0.37],
[-0.56, 0.02, 0.56, 1.77, 0.99, 0.97],
[-1.67, -0.41, -0.98, 1.20, 0.74, -0.04],
[-0.80, -0.43, -0.12, 1.06, 1.59, 0.34]],
columns=['IBM', 'MSFT', 'APPL', 'ORCL','FB','TWTR'],
index=pd.date_range('2000', freq='D', periods=4))
其次,结合这些来创建新的股票表(具有多索引):# re-shape `eps` data frame
eps.index.name = 'date'
eps.columns.name = 'ticker'
eps = (eps.assign(metric='eps')
.set_index('metric', append=True)
.stack()
.swaplevel('metric', 'date')
.sort_index()
)
# re-shape `price` data frame
price.index.name = 'date'
price.columns.name = 'ticker'
price = (price.assign(metric='price')
.set_index('metric', append=True)
.stack()
.swaplevel('metric', 'date')
.sort_index())
# you could put, say, `volume` data frame here...
# concatenate
stock_data = pd.concat([eps, price]).rename('value')
# display
print(stock_data.head(8))
metric date ticker
eps 2000-01-01 APPL 0.51
FB -0.84
IBM -1.91
MSFT 1.63
ORCL -0.32
TWTR 0.37
2000-01-02 APPL 0.56
FB 0.99
Name: value, dtype: float64
pandas MultiIndex 功能强大,但对于数据帧来说并不直观。对于系列来说,它更直接。一切都用 .loc[::]
指定.然后我们可以使用 .unstack()
重新塑造以进行进一步的下游处理(例如,在行上创建带有日期的数据框,在列上创建股票代码,并使用 Matplotlib 创建绘图)# index level 0, scalar
t0 = stock_data.loc['eps']
# index level 1, range
t1 = stock_data.loc[:, '2000-01-02':'2000-01-03']
# index level 2, list
t2 = stock_data.loc[:, :, ['AAPL', 'MSFT', 'TWTR']]
关于python - 什么是组合相关但存储在不同数据帧中的数据集的好设计模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63174054/