Python DataFrame column lookup is nondeterministic when a Symbol column and its ticker string column coexist

未关闭
#10,093 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
42/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
活跃
技术栈
pandas, python
领域
data

调研方向

Start by tracing how Lean’s Python Symbol objects compare and hash when used as pandas DataFrame column labels; the report provides a reproduction using AlgorithmImports, history, and pd.DataFrame. Check existing tests for Symbol equality, hashing, and DataFrame column lookup. Done when df['open'] consistently selects the intended column when a Symbol ticker and matching string column coexist, with a regression test covering the reported case.

由索引模型根据 Issue 内容生成。

描述

Expected Behavior

In Python, a DataFrame that has both a Symbol column and a string column named like that Symbol's ticker returns the same result for df['open'] in every run.

Actual Behavior

With the ticker cached, Symbol == 'open' is True while hash(symbol) != hash('open'). A frame with columns [OPEN Symbol, 'open'] then returns different results from run to run for df['open']: usually a Series, but in some processes a DataFrame with both columns. Python randomizes string hashes per process, which is likely why the outcome changes between processes. Code that builds a mask from it, such as history.loc[lambda d: other['open'] > 0, 'close'], then fails intermittently with ValueError: Cannot index with multidimensional key.

Potential Solution

A suggestion only: Python requires that objects that compare equal have the same hash, which Symbol vs. ticker string doesn't meet. Either the equality or the hash would need to change for these cases.

Reproducing the Problem
from AlgorithmImports import *

class SymbolTickerColumnAmbiguity(QCAlgorithm):
    def initialize(self):
        spy = self.add_equity("SPY", Resolution.DAILY).symbol
        opened = self.add_equity("OPEN", Resolution.DAILY).symbol
        history = self.history(spy, 10, Resolution.DAILY)
        other = pd.DataFrame({opened: 1.0, 'open': -1.0}, index=history.index)
        self.log(f"{opened == 'open'} {hash(opened) == hash('open')} {type(other['open']).__name__}")

The first two values are always True False. The type varies between processes: in ten runs of the same steps as a unit test, other['open'] was a DataFrame once and a Series nine times. The same steps with LOW/low and HIGH/high gave a Series in all ten runs.

System Information

pandas 2.3.3, Python 3.11, current master.

Checklist
  • I have completely filled out this template
  • I have confirmed that this issue exists on the current master branch
  • I have confirmed that this is not a duplicate issue by searching issues
主要语言
C#
星标
22.5k
派生
5.4k
平均合并
22 小时 6 分钟
30 天内合并 PR
81

环境准备

在 Codespaces 中打开

在浏览器里用你自己的 GitHub 账号启动这个项目的开发容器。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

QuantConnect/Lean 的其他 Issue

查看 QuantConnect/Lean 的全部 Issue

相似的 Issue

更多 C# Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。