python - الباندا 0.21.0 مشكلة توافق الطابع الزمني مع matplotlib




pandas (2)

بعد فتح issue على github الباندا ، علمت أن هذه بالفعل مشكلة معروفة بين الباندا و matplotlib فيما يتعلق بالتسجيل التلقائي لمحول الوحدة. في الواقع تم إدراجها في page الجديدة التي فشلت في رؤيتها من قبل ، إلى جانب الطريقة الصحيحة لتسجيل المحولات:

from pandas.tseries import converter
converter.register() 

يتم ذلك أيضًا في المرة الأولى التي يتم فيها استدعاء طريقة مؤامرة عضو على سلسلة أو DataFrame والتي تشرح ما لاحظته أعلاه.

يبدو أنه قد تم القيام به مع نية يفترض أن matplotlib لتنفيذ بعض الدعم الأساسي لوقت الباندا ، ولكن في الواقع تحذير الإهمال من نوع ما يمكن أن يكون مفيدا لمثل هذا الاستراحة. ومع ذلك ، إلى أن تنفذ matplotlib بالفعل مثل هذا الدعم (أو نوع من آلية التسجيل البطيئة) ، فأنا دائمًا ما أضع هذين الخطين عند استيراد الباندا. لذلك لست متأكدًا من سبب رغبة الباندا في تعطيل التسجيل التلقائي عند الاستيراد قبل أن تصبح الأمور جاهزة على جانب matplotlib.

لقد قمت للتو بتحديث الباندا من 0.17.1 إلى 0.21.0 للاستفادة من بعض الوظائف الجديدة ، وواجهت مشكلة التوافق مع matplotlib (الذي قمت بتحديثه أيضًا إلى الإصدار 2.1.0 الأخير). على وجه الخصوص ، يبدو أن كائن الطابع الزمني قد تغير بشكل ملحوظ.

تصادف أن هناك جهازًا آخر لا يزال يعمل على الإصدارات القديمة من الباندا (0.17.1) / matplotlib (1.5.1) والتي اعتدت أن أقارنها:

يعرض كلا الإصدارين فهرس DataFrame الخاص بي ليكون dtype='datetime64[ns]

DatetimeIndex(['2017-03-13', '2017-03-14', ... '2017-11-17'], type='datetime64[ns]', name='dates', length=170, freq=None)

ولكن عند استدعاء type(df.index[0]) ، يعطي pandas.tslib.Timestamp و 0.21.0 يعطي pandas._libs.tslib.Timestamp .

عند التخطيط باستخدام df.index كمحور x:

plt.plot(df.index, df['data'])

يقوم matplotlibs افتراضيًا بتنسيق تسميات المحور السيني كتواريخ للباندا 0.17.1 ولكنه يفشل في التعرف عليه لباندا 0.21.0 ويعطي رقمًا 1.5e18 (وقت العصر في nanosec).

لدي أيضًا مؤشر مخصص يقوم بالإبلاغ عن الموقع الذي تم النقر فوقه على الرسم البياني باستخدام matplotlib.dates.DateFormatter على القيمة x التي تفشل في 0.21.0 مع:

OverflowError: signed integer is greater than maximum

أستطيع أن أرى في تصحيح القيمة x المبلغ عنها حوالي 736500 (أي عدد الأيام منذ السنة 0) مقابل 0.17.1 ولكن حوالي 1.5e18 (أي وقت عصر nanosec) مقابل 0.21.0.

أنا مندهش من كسر التوافق هذا بين matplotlib و pandas لأنه من الواضح أن معظمهم يستخدمون معًا. هل أفتقد شيئًا ما بالطريقة التي أسميها وظيفة الرسم أعلاه للإصدارات الأحدث؟

تحديث كما ذكرت أعلاه ، أفضل الاتصال مباشرة plot باستخدام كائن محاور معين ولكن فقط من أجل التحقق منه ، حاولت استدعاء طريقة الرسم الخاصة بـ DataFrame نفسها df.plot() . بمجرد القيام بذلك ، تتعرف جميع المخططات اللاحقة بشكل صحيح على الطابع الزمني في نفس جلسة الثعبان . يبدو الأمر كما لو أنه تم تعيين متغير بيئة ، لأنه يمكنني إعادة تحميل DataFrame آخر أو إنشاء محاور أخرى مع مخططات subplots ولا يظهر فيها 1.5e18 . هذا حقا تنبعث منه رائحة علة كما يقول أحدث وثيقة pandas :

The plot method on Series and DataFrame is just a simple wrapper around plt.plot()

لكن من الواضح أنها تفعل شيئًا لجلسة الثعبان بحيث تتعامل المؤامرات اللاحقة مع مؤشر الطابع الزمني بشكل صحيح.

في الواقع ، ببساطة تشغيل المثال على الرابط الباندا أعلاه:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))

اعتمادًا على ما إذا كان يتم استدعاء ts.plot() أم لا ، فإن المخطط التالي إما ts.plot() المحور السيني بشكل صحيح كتواريخ أم لا:

plt.plot(ts.index,ts)
plt.show()

بمجرد استدعاء مؤامرة عضو ، سيتم بعد ذلك استدعاء plt.plot على السلسلة الجديدة أو DataFrame التنسيق التلقائي بشكل صحيح دون الحاجة إلى استدعاء طريقة مؤامرة العضو مرة أخرى.


هناك مشكلة مع datetimes pandas و matplotlib قادمة من الإصدار الأخير من pandas 0.21 ، الذي لا يسجل محولاته أكثر عند الاستيراد. بمجرد استخدام هذه المحولات مرة واحدة (ضمن الباندا) ، سيتم تسجيلهم واستخدامهم تلقائيًا بواسطة matplotlib أيضًا.

سيكون الحل لتسجيلهم يدويًا ،

import pandas.plotting._converter as pandacnv
pandacnv.register()

في أي حال ، المشكلة معروفة جيدًا في كل من الباندا والجانب matplotlib ، لذلك سيكون هناك نوع من الإصلاح للإصدارات القادمة. تفكر Pandas في قراءة السجل في إصدار جديد. لذلك قد تكون هذه المشكلة هناك مؤقتا فقط. أحد الخيارات هو العودة أيضًا إلى الباندا 0.20.x حيث يجب ألا يحدث ذلك.

التحديث: لم تعد هذه مشكلة في الإصدارات الحالية من matplotlib (2.2.2) / pandas (0.23.1) ، ومن المحتمل أن العديد منها قد تم إصداره منذ ديسمبر 2017 تقريبًا ، عندما تم إصلاح ذلك.





plot