对 isinstance 的调用在一系列 map (以及数据帧上的 applymap)外部返回 True,但在 map 内部返回 False...
import pandas as pd
import pytz
s = pd.Series([pd.Timestamp(2018,5,11,6,0,0,0, pytz.timezone('UTC'))])
s
0 2018-05-11 06:00:00+00:00
dtype: datetime64[ns, UTC]
为该系列中的单个值调用 isinstance 会产生 True。
isinstance(s.iloc[0], pd.Timestamp)
True
在它给出 True 的系列 map 中。
s.map(lambda x: isinstance(x, pd.Timestamp)).iloc[0]
True
但是如果我们尝试根据该值进行某些操作,比如转换为字符串...
s.map(lambda x: x.isoformat() if isinstance(x, pd.Timestamp) else x).iloc[0]
Timestamp('2018-05-11 06:00:00+0000', tz='UTC')
...它似乎返回了 False 并且没有调用方法 isoformat(实际的方法调用是无关紧要的,因为它没有被调用)。
最佳答案
查看 source的 .map
, Pandas 似乎正在检查 Series 的类型是否为 extension type .正如 OP 指出的那样,这对于不同的时区会有不同的表现。让
s1 = pd.Series([
pd.Timestamp(2018,5,11,6,0,0,0),
])
s2 = pd.Series([
pd.Timestamp(2018,5,11,6,0,0,0, pytz.timezone('UTC')),
])
当 .map
被调用,它检查 pd.api.types.is_extension_type(s)
.如果s == s1
,这将返回 False
, 而如果 s == s2
这返回 True
.
因此,s2.map
变成 s2._values.map
.自 s2._values
类型为 DatetimeIndex
,相关执行.map
叫做。它首先尝试调用 f(s2._values)
并恢复到 s2._values.map(f)
如果发生错误。
在这种情况下,f = lambda x: x.isoformat(x) if isinstance(x, pd.Timestamp) else x
.没有错误发生,因为 f
检查是否 isinstance(s2._values, pd.Timestamp)
,失败了。因此,f(s2._values)
返回 s2._values
.事实上,这可以用 s2._values is f(s2._values) == True
来验证。 .
一种解决方法是确保 pd.api.types.is_extension_type
不被调用,例如s.astype(object).map
.
关于python - 为什么 isinstance 仅在系列 map 内返回错误值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50333866/