【问题标题】:Pandas DataFrame column assignment ValueError: Wrong number of items passedPandas DataFrame 列分配ValueError:传递的项目数错误
【发布时间】:2016-04-09 18:36:50
【问题描述】:

在升级 Anaconda(因此升级 pandas 和 numpy)之前运行的脚本存在问题

我有一个 DataFrame,我想使用其中的一列并乘以另一个 DataFrame 的一列中的值,将最终值输出到新 DataFrame 中的一列。正如我所说,这段代码一直有效,直到我升级到 pandas 0.17。

class MarketOnClosePortfolio(Portfolio):
    def __init__(self, symbol, bars, signals, initial_capital=10000.0):
        self.symbol = symbol
        self.bars = bars
        self.signals = signals
        self.initial_capital = float(initial_capital)
        self.positions = self.generate_positions()

    def generate_positions(self):
        positions = pd.DataFrame(index=signals.index).fillna(0.0)
        positions[self.symbol] = signals['signal']*10

        return positions        

    def backtest_portfolio(self):
        portfolio = self.positions*self.bars['Close']
        pos_diff = self.positions.diff()

        portfolio = pd.DataFrame(index=signals.index)
        portfolio['holdings'] = (self.positions*self.bars['Close'])
        portfolio['cash'] = self.initial_capital - (pos_diff*self.bars['Close']).sum(axis=1).cumsum()

        portfolio['total'] = portfolio['cash'] + portfolio['holdings']
        portfolio['returns'] = portfolio['total'].pct_change()

        return portfolio

if __name__ == "__main__":
    portfolio = MarketOnClosePortfolio(symbol, bars, signals, initial_capital=10000.0)
    returns = portfolio.backtest_portfolio()

我在尝试执行 returns = portfolio.backtest_portfolio() 引用 portfolio['holdings'] = self.positions*self.bars['Close'] 并返回时出现错误

ValueError: 传递的项目数错误 3509,位置暗示 1。

self.positions 有这个样子(它的索引在 3600 左右):

    Symbol
1    int
2    int
3    int

self.bars.Close 有这个外观(索引大小与 self.positions 相同):

    Close
1   float
2   float
3   float

我在这里忽略了一些明显的东西吗?我知道我传递的是一个系列而不是一个单一的值,但我很困惑为什么我会得到“放置意味着 1”。

非常感谢任何帮助。

【问题讨论】:

  • @Stefan。 self.positions 是symbol index value 形式的数据框,大约有 3600 行。
  • 你试过self.positions.shape和self.bars['close'].shape吗?顺便说一句,看起来您正在创建 portfolio 两次。我猜self.bars['Close'] 只选择了一个项目,可能是row index,而不是你可能想要的column。可能想试试self.bars.loc[:, 'Close']]
  • 好的。有趣的。它 self.bars.Close.shape 返回 (3559, ) 但是当我 print(bars.head()) 它具有所有预期值。 self.positions.shape 返回与应具有的 1 列相同的索引值。 (3559, 1)
  • 您是否要将self.bars.closeself.positions 中的所有columns 相乘?没有看到data..
  • 是的,我是。 self.positions 只有一列(符号)定义给定股票代码中的头寸。我在问题中添加了一小部分数据格式

标签: python numpy pandas quantitative-finance


【解决方案1】:

尝试按照以下方式调整乘法:

position = pd.DataFrame({'symbol': [ 1,2,3,4,5]})
bar = pd.DataFrame({'close': np.random.random(5)})

position.symbol.mul(bar.close, axis=0)

0    0.184591
1    1.830434
2    0.343875
3    1.531412
4    2.257981
dtype: float64

【讨论】:

  • 运行portfolio['holdings'] = position.symbol.mul(bar.close) 输出一个数据帧,其索引作为末尾带有符号的列传递。即形状 (3559, 3560)
  • 尝试添加 axis=0 关键字以确保索引对齐 - 假设它们兼容?
  • 谢谢!看起来我们现在正在取得进展。更改 axis=0 解决了乘法问题,同时还添加了一个带有相关符号标题的列。但是,我的现金栏根本无法运行。只需发布原始现金价值,而不是价值减去购买股票的原始成本。我会看看我能做些什么。
  • cash 上:看起来它是__init__ 中的float 值,但您在使用.sum(axis=1).cumsum() 时尝试减去Series。也许那条线应该是sum(axis=1).sum(),所以你那里也有一个号码?
  • 您总是乐于助人且在线。谢谢!所以我实际上只是完全删除了.sum(),而是使用了portfolio['cash']=self.initial_capital-pos_diff.mul(self.bars.Close, axis=0).cumsum()。这似乎解决了问题。
猜你喜欢
  • 2021-08-10
  • 2020-08-01
  • 2021-09-25
  • 2020-07-02
  • 1970-01-01
  • 2021-07-13
  • 2020-04-22
  • 2019-05-17
  • 2021-04-08
相关资源
最近更新 更多