pandas-ta · 调用形态
pandas-ta 的 df.ta 与 ta.function 有什么区别:四种调用与列名
同一个指标有四到五种写法,它们的返回值、是否修改原 DataFrame、列名生成规则都不一样。本站把每种写法的实测结果列成表,并给出五个最常见写法错误的报错原文与正解。
pandas-ta 的同一个 RSI,四种写法差在哪?
下面这张表是本站运行期实测的结果(classic 0.8.32 / pandas 3.0.6 / Python 3.11.9)。关键差异只有三个维度:返回值类型、是否修改原 DataFrame、能不能继续链式调用。
| 写法 | 示例 | 返回值(实测) | 是否修改原 df | 适用场景 |
|---|---|---|---|---|
| ① 标准函数 | ta.rsi(df["close"], length=14) | Series RSI_14 | 否 | 只想拿一个序列去做后续计算 |
| ② DataFrame 扩展 | df.ta.rsi(length=14) | Series RSI_14 | 否(append 默认 False) | 数据已经在 DataFrame 里,想省掉传参 |
| ③ 扩展 + append | df.ta.rsi(length=14, append=True) | 返回 None | 是(直接加列) | 一次算完就并进表里 |
| ④ Strategy | df.ta.strategy(ta.CommonStrategy) | 返回 None | 是 | 一次算一批指标 |
| ⑤ 链式调用 | df.ta.chain().sma(20).ta.rsi(14) | 返回 DataFrame,可继续 .ta | 是(链式模式自动 append) | v0.6+ 的写法,一行算多个 |
| 注意点 | ② 与 ① 的差别只在传参方式 | ③④⑤ 都返回 None,别再对返回值取列 | ②不写 append 时原表不变 | 按「要不要就地加列」来选,而不是按长短 |
df.ta.rsi(length=14, append=True) 的返回值是 None。写 rsi = df.ta.rsi(length=14, append=True) 之后再对 rsi 取列,会得到 AttributeError: 'NoneType' object has no attribute ...。为什么有的指标返回一列,有的返回五列?
因为指标的数学输出本来就不一样。下表列出常见指标在实测中的返回结构与列名——取列名的代码必须按这张表写,否则会在升级后突然 KeyError。
| 指标 | 返回值 | 实测列名 | 口径提醒 |
|---|---|---|---|
sma | Series | SMA_20(默认 SMA_10) | 默认窗口是 10,不是 20 |
rsi | Series | RSI_14 | 默认 14;本站实测其数值与朴素 Wilder 复算差异较大,见「TA-Lib 对照」页 |
macd | DataFrame(3 列) | MACD_12_26_9 / MACDh_12_26_9 / MACDs_12_26_9 | MACD / 柱 / 信号三列,名字里带参数 |
bbands | DataFrame(5 列) | BBL_ / BBM_ / BBU_ / BBB_ / BBP_ | 默认 length=5;官方 quickstart 示例只列了 3 列 |
adx | DataFrame(3 列) | ADX_14 / DMP_14 / DMN_14 | 三个方向信息一起给 |
stoch | DataFrame(2 列) | STOCHk_14_3_3 / STOCHd_14_3_3 | %K 与 %D |
ichimoku | DataFrame(5 列) | ITS_9 / IKS_26 / ISA_9 / ISB_26 / ICS_26 | 含 Chikou,属含未来数据的一列,见「未来函数」页 |
supertrend | DataFrame(4 列) | SUPERT_7_3.0 / SUPERTd_ / SUPERTl_ / SUPERTs_ | 默认 7/3.0 |
df["BBU_20_2.0"],把 length 改成 10 之后就会取不到列。稳妥写法是用 df.ta.bbands(...) 的返回值直接取,或用 col_names 显式命名。pandas-ta 的 prefix、suffix、col_names 分别怎么用?
同一指标算多次时必须靠这三个参数区分列名。下表是实测结果——注意 prefix 的分隔符会叠加,这一点和直觉不同。
| 参数 | 写法 | 实测列名 | 使用建议 |
|---|---|---|---|
prefix | df.ta.sma(length=20, append=True, prefix="p_") | p__SMA_20 | 库会再加一个下划线,因此不要自己在前缀末尾补下划线 |
suffix | df.ta.sma(length=20, append=True, suffix="_s") | SMA_20__s | 同上,双下划线是库自动拼的 |
col_names | df.ta.sma(length=20, append=True, col_names=("MY_SMA",)) | MY_SMA | 完全接管列名,适合把列名写进下游契约 |
| 多列指标用 col_names | df.ta.bbands(length=20, col_names=("LOWER","MID","UPPER","BW","PCT")) | 五个指定列名 | 注意顺序:BBands 的 5 列是 下轨/中轨/上轨/带宽/百分比 |
| 同一指标两个窗口 | df.ta.sma(length=20, prefix="FAST"); df.ta.sma(length=50, prefix="SLOW") | FAST_SMA_20 / SLOW_SMA_50 | 做双均线时最常用的写法 |
| 注意点 | 列名里包含参数值(20、2.0 等) | — | 参数一变列名就变,写死列名是脆的 |
pandas-ta 的 Strategy 一次算一批指标怎么写?
Strategy 是官方推荐的批量方式,适合一次要算十几个指标的场景。下面给出可直接运行的写法与实测行为。
import pandas_ta_classic as ta
# 1) 用内置策略(注意:传的是 Strategy 对象,不是它的名字)
df.ta.strategy(ta.CommonStrategy)
# 2) 自定义策略
my_strategy = ta.Strategy(
name="MyStrategy",
ta=[
{"kind": "sma", "length": 20},
{"kind": "sma", "length": 50},
{"kind": "rsi", "length": 14},
{"kind": "macd"},
{"kind": "bbands", "length": 20},
],
)
df.ta.strategy(my_strategy)
print(df.columns) # 指标列已被追加进原 DataFrame
| 你要确认的事 | 实测行为 | 怎么处理 |
|---|---|---|
| 返回值是什么 | 返回 None(无论是传字符串还是传对象) | 指标列直接加在传入的 DataFrame 上,用 df.columns 查 |
| 传字符串可以吗 | 可以运行,但官方推荐传对象(ta.CommonStrategy) | 为了让静态检查工具看得懂,建议统一传对象 |
| 全量指标怎么写 | ta.AllStrategy.ALL 在 0.8.32 不存在(实测 AttributeError) | 先确认版本支持的全量策略常量,再调用;或自己列 ta=[...] |
| 多进程怎么开 | 官方 quickstart 提到约 10 万行以上可传 cores=N | 本站未复现加速效果,按自己的数据规模实测后决定 |
| 注意点 | Strategy 会一次加很多列 | 列多时建议先用 prefix 分组,方便下游筛选 |
pandas-ta 的 df.ta.chain() 是什么?值得用吗?
链式调用是 v0.6 之后新增的写法,把多个指标串在一行里。它的定位是可读性,不是性能。下表是实测行为。
| 行为 | 写法 | 实测结果 | 注意点 |
|---|---|---|---|
| 开启链式模式 | df.ta.chain() | 之后每个指标自动 append | 链式模式下返回的是 DataFrame,可以继续 .ta |
| 正常链到底 | df.ta.chain().sma(20).ta.rsi(14).ta.macd().ta.bbands(20) | 多个指标列全部加上 | 一行算完,可读性更好 |
| 带前缀链 | df.ta.chain().sma(20, prefix="FAST").ta.sma(50, prefix="SLOW") | 两组列名不冲突 | 双均线场景常用 |
| 自定义列名 | df.ta.chain().bbands(20, col_names=("LOWER","MID","UPPER","BW","PCT")) | 五列全部改名 | 列名数量要与输出列数一致 |
| 中途退出 | df.ta.chain().sma(20).ta.unchain().ta.rsi(14) | unchain() 之后的指标恢复「返回 Series」 | 适合只想链一段的场景 |
| 作用范围 | 只对调用 chain() 的那个 DataFrame 生效 | df.copy() 与 df.iloc[-100:] 不会被链式接管 | 切片后要重新 chain() |
五种最常见的调用写错方式是什么?
下面每一条都能在中文论坛里搜到,但多数回答只给结论不给原因。这里给出报错原文 + 原因 + 正解。
| 报错原文 / 现象 | 原因 | 正解 | |
|---|---|---|---|
AttributeError: 'Series' object has no attribute 'ta' | .ta 访问器只挂在 DataFrame 上,不在 Series 上 | 先用 df.ta.rsi();只有 Series 时用 ta.rsi(series, length=14) | |
None 被当成结果继续用 | 带 append=True 的调用返回 None | 要么不接返回值,用 df["RSI_14"] 取列;要么不写 append 接返回值 | |
| 算了半天,一列都没加上 | 列缺失或行数不足时库静默返回原表,不抛异常 | 先断言 {"open","high","low","close"} ⊆ df.columns,再断言 len(df) > length | |
KeyError: 'BBU_20_2.0' | 列名里带参数;改了 length 或没传 length(默认 5)都会换名字 | 打印 df.columns 核对,或用 col_names 固定列名 | |
TypeError: sma() expected a pandas Series but got ndarray | 传了 df["close"].values(numpy 数组)而不是 Series | 传 df["close"] 本身;0.8.32 上该错误表现为返回 None 加 FutureWarning,更隐蔽 | |
| 注意点 | 以上五类都不涉及「计算错误」 | — | 指标算法本身没问题,问题都在调用姿势 |
pandas-ta 调用写法常见问题:返回值、append、列名与 Series 报错
下面的回答都指向可核验的官方文件或本站实测;与官方表述冲突时,以官方仓库与文档为准。
df.ta.sma() 和 ta.sma() 结果一样吗?
数值一样,差别在传参与副作用:ta.sma(df["close"], length=20) 要显式传序列,返回 Series 且不改原表;df.ta.sma(length=20) 会自动找 close 列,append 缺省为 False,因此同样不改原表。
为什么 append=True 之后我的变量是 None?
因为带 append=True 的调用是「就地写回」模式,实测返回 None。需要返回值就不要写 append,改为 s = df.ta.rsi(length=14)。
MACD 和布林带为什么一次加好几列?
因为它们的数学输出本身就是多列:MACD 是 MACD / 柱 / 信号三列,BBands 是下轨 / 中轨 / 上轨 / 带宽 / 百分比五列。实测列名里带参数,例如 BBU_20_2.0。
prefix 加双下划线是 bug 吗?
不是。实测 prefix="p_" 得到 p__SMA_20,库会在你给的前缀后自己再拼一个下划线。想完全控制列名就用 col_names。
df.ta.strategy() 没有返回值,怎么拿结果?
结果已经写进你传入的那个 DataFrame,用 df.columns 查看新增列即可。注意实测里传字符串与传对象都返回 None。
可以直接对一列 Series 调用 .ta 吗?
不可以。实测 df["close"].ta.rsi(length=14) 报 AttributeError: 'Series' object has no attribute 'ta'。只有 Series 时用模块级函数 ta.rsi(series, length=14)。