当我在 pd.Series.str.replace() 方法中使用 regex=[True|False] 标志时,我得到了矛盾的异常:
repl是一个字典 => 它说repl must be a string or callablereplis a callable => 它说Cannot use a callable replacement when regex=False
我正在尝试用相应的英文短名称替换 DataFrame 索引中西类牙日期的月份部分。
import pandas as pd
import numpy as np
# Define the months' short names in English and Spanish
ENG = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC']
ESP = ['ENE', 'FEB', 'MAR', 'ABR', 'MAY', 'JUN', 'JUL', 'AGO', 'SEP', 'OCT', 'NOV', 'DIC']
# Dictionary mapping Spanish months to English months
esp2eng = dict(zip(ESP, ENG))
# Function to make the dictionary "callable"
def eng_from_esp(key):
return esp2eng[key]
# Create the DF with date in the "%d-%b-%y" format as index, where %b is the Spanish naming
idx = ['06-{}-19'.format(m) for m in ESP]
col = ['ordinal']
data = pd.DataFrame(np.arange(12).reshape((12, 1)),
index=idx,
columns=col)
data.index.str.replace('ENE', esp2eng, regex=False)
TypeError: repl must be a string or callable
data.index.str.replace('ENE', eng_from_esp, regex=False)
ValueError: Cannot use a callable replacement when regex=False
请您参考如下方法:
如果您查看 pandas.Series.str.replace 的文档您会看到 repl 参数可以是 string 或 callable,但不支持 dict。
考虑到这一点,不支持您的第一次尝试。
深入研究源代码(下面转载的关键部分),您仍然看到 string 或 callable 的检查是首先完成的,在检查 regex 标志之前。
# Check whether repl is valid (GH 13438, GH 15055)
if not (is_string_like(repl) or callable(repl)):
raise TypeError("repl must be a string or callable")
if regex:
# omitted
else:
# omitted
if callable(repl):
raise ValueError("Cannot use a callable replacement when "
"regex=False")
因此,您的第一次尝试(使用 repl 的字典)触发了第一个 if 检查,打印出消息 “repl must be a string or callable”.
您的第二次尝试通过了此检查,但随后被 regex 检查的 else block 内的可调用检查绊倒了。
所以简而言之,没有不一致。当然,第一个错误消息可能可能会被改进为类似“repl 必须是字符串或可调用的(除非您使用的是 regex=False)”,但事实并非如此必要的。
FWIW,这是一个应该达到预期结果的 Pandas “单线”:
print(
data.reset_index()
.replace(esp2eng, regex=True)
.set_index("index", drop=True)
.rename_axis(None, axis=0)
)
# ordinal
#06-JAN-19 0
#06-FEB-19 1
#06-MAR-19 2
#06-APR-19 3
#06-MAY-19 4
#06-JUN-19 5
#06-JUL-19 6
#06-AUG-19 7
#06-SEP-19 8
#06-OCT-19 9
#06-NOV-19 10
#06-DEC-19 11
