在 python 中导入 pandas 会改变 matplotlib 处理日期时间对象的方式?
Posted
技术标签:
【中文标题】在 python 中导入 pandas 会改变 matplotlib 处理日期时间对象的方式?【英文标题】:Importing pandas in python changes how matplotlib handles datetime objects? 【发布时间】:2012-12-08 21:56:14 【问题描述】:在我的 debian 挤压系统上,我遇到了一个 python 问题,可以归纳为以下几点:
import numpy
import datetime
from matplotlib import pyplot
x = [datetime.datetime.utcfromtimestamp(i) for i in numpy.arange(100000,200000,3600)]
y = range(len(x))
# See matplotlib handle a series of datetimes just fine..
pyplot.plot(x, y)
# [<matplotlib.lines.Line2D object at 0xad10f4c>]
import pandas
# Now we try exactly what we did before..
pyplot.plot(x, y)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/pymodules/python2.6/matplotlib/pyplot.py", line 2141, in plot
ret = ax.plot(*args, **kwargs)
File "/usr/lib/pymodules/python2.6/matplotlib/axes.py", line 3432, in plot
for line in self._get_lines(*args, **kwargs):
File "/usr/lib/pymodules/python2.6/matplotlib/axes.py", line 311, in _grab_next_args
for seg in self._plot_args(remaining, kwargs):
File "/usr/lib/pymodules/python2.6/matplotlib/axes.py", line 288, in _plot_args
x, y = self._xy_from_xy(x, y)
File "/usr/lib/pymodules/python2.6/matplotlib/axes.py", line 204, in _xy_from_xy
bx = self.axes.xaxis.update_units(x)
File "/usr/lib/pymodules/python2.6/matplotlib/axis.py", line 982, in update_units
self._update_axisinfo()
File "/usr/lib/pymodules/python2.6/matplotlib/axis.py", line 994, in _update_axisinfo
info = self.converter.axisinfo(self.units, self)
File "/usr/local/lib/python2.6/dist-packages/pandas/tseries/converter.py", line 184, in axisinfo
majfmt = PandasAutoDateFormatter(majloc, tz=tz)
File "/usr/local/lib/python2.6/dist-packages/pandas/tseries/converter.py", line 195, in __init__
dates.AutoDateFormatter.__init__(self, locator, tz, defaultfmt)
TypeError: __init__() takes at most 3 arguments (4 given)
我对所显示的特定错误的原因不感兴趣,很明显,pandas 期望使用不同版本的 matplotlib - 从标准 debian 存储库获取一个包并通过 pip 获取另一个包的风险相当大,并且通过允许 pip 升级 matplotlib,我已经“解决”了这部分问题。
真正的问题是——现在出现了一个三重问题:为什么只是 导入 pandas 就破坏了 matplotlib 处理日期时间对象的能力,而之前的两行显然甚至没有涉及 pandas在同一个操作中?导入时 pandas 是否会默默地更改***命名空间中的其他模块以强制它们使用 pandas 方法?对于 python 模块,这是可以接受的行为吗?因为我需要能够依赖它,例如导入一个随机数模块,不会默默地改变,例如,pickle 模块以将随机盐应用于它编写的所有内容..
更新更多信息
python 是 2.6.6(当前 debian stable 来自包 2.6.6-3+squeeze7)
matplotlib 版本是 debian 的 0.99.3-1(当前 debian stable 来自包 python-matplotlib)
pandas 版本是 0.9.0(使用 'pip install pandas' 安装,不久前 -- 不是今天)
平台是一个运行 debian Squeeze 的 i386
复制步骤
-
(很明显)引导一个干净的 debian 压缩 i386 安装并 chroot 进入它。
apt-get 更新
apt-get install python python-matplotlib
apt-get install python-pip build-essential python-dev
pip install --upgrade numpy
点安装熊猫
现在开始一个交互式 python 会话
import numpy
import datetime
# Next two lines added to original example to avoid hassle with DISPLAY in chroot
import matplotlib
matplotlib.use('agg')
from matplotlib import pyplot
x = [datetime.datetime.utcfromtimestamp(i) for i in numpy.arange(100000,200000,3600)]
y = range(len(x))
pyplot.plot(x, y)
import pandas
pyplot.plot(x, y)
【问题讨论】:
真的不应该!你能复制这个吗?你使用的是什么 pandas/matplotlib 版本? 我无法在 Windows 7 上使用 pandas 0.9.1 和 matplotlib 1.1.0 复制它 @joris 他使用的是旧版本的 matplotlib(注意:熊猫不支持 安装了 pandas(并且 python 保持打开状态)! ... python 是 2.6.6(当前 debian stable 来自包 2.6.6-3+squeeze7)matplotlib 版本是 debian 的 0.99.3-1(当前 debian stable 来自包 python-matplotlib)pandas 版本是 0.9 .0 平台是运行 debian Squeeze 的 i386 我在其他机器上复制成功。复制的步骤已添加到主要文章中。请注意,在复制中,pip 检索到的 pandas 版本为 0.10.0,但结果与 0.9.0 中观察到的完全相同。 【参考方案1】:当您导入pandas
时,它会使用matplotlib
注册一堆单位转换器。这是来自两个库的更新版本,但我认为整体行为是相同的。
In [4]: import matplotlib.units as muints
In [5]: muints.registry
Out[5]:
datetime.date: <matplotlib.dates.DateConverter instance at 0x2ab8908>,
datetime.datetime: <matplotlib.dates.DateConverter instance at 0x2ab8ab8>
In [6]: import pandas
In [7]: muints.registry
Out[7]:
pandas.tseries.period.Period: <pandas.tseries.converter.PeriodConverter instance at 0x2627e60>,
pandas.tslib.Timestamp: <pandas.tseries.converter.DatetimeConverter instance at 0x264ea28>,
datetime.date: <pandas.tseries.converter.DatetimeConverter instance at 0x2532fc8>,
datetime.datetime: <pandas.tseries.converter.DatetimeConverter instance at 0x2627ab8>,
datetime.time: <pandas.tseries.converter.TimeConverter instance at 0x2532f38>
axis
(带有几层重定向)使用此注册表来确定如何格式化不是数字的信息,并且它与它试图标记的事物的类别相匹配(因此,字典中的条目键入datetime.*
)。
我怀疑您可以通过替换 dict
中的违规条目来解决此问题
【讨论】:
目前,pandas 使用自己的转换器,以便在缩放时更好地标记刻度。它应该在第一个情节上注册那些而不是导入。我在这里提出了一个问题:github.com/pydata/pandas/issues/2579 希望我们能够在下一个版本中解决它 嗨,Chang,我不同意这应该是自动的;在使用最新版本的 Pandas 和旧版本的 matplotlib 时,这会导致一些错误。这些副作用应该由用户显式调用,即使这意味着默认情况下用户会得到较旧/较丑的刻度标签。 @blais 你应该在 github 问题上留下评论 @ChangShe 见上面的评论。 pandas-0.18.1和pandas-0.20.3有这个问题,但是pandas-0.22.0不做自动注册。以上是关于在 python 中导入 pandas 会改变 matplotlib 处理日期时间对象的方式?的主要内容,如果未能解决你的问题,请参考以下文章
python 使用Mac在Pandas(Python)中导入Excel文件