Я пишу библиотеку процедур Pandas, которая должна иметь возможность обрабатывать даты во фреймах данных, которые потенциально могут быть разных типов. В частности, я получаю различные комбинации типов datetime.date
и pandas._libs.tslib.Timestamp
совсем немного. Сообщается (и подтверждено моими испытаниями), что это связано с кадрами, для которых был установлен многоиндексный набор, а затем сброшен. (См. Мой предыдущий вопрос Что меняет тип даты в этом коде панд? , который решает проблему изменения типа при переходе назад и вперед от мультииндекса.)
Воткороткий (но надуманный) пример:
import pandas as pd
df = pd.DataFrame(
data={
'date' : ['2019-01-01', '2019-01-02', '2019-01-03'],
'value' : [1, 2, 3],
'other' : [11, 12, 13]
}
)
df.date = pd.to_datetime(df.date).dt.date
print df.head()
date other value
0 2019-01-01 11 1
1 2019-01-02 12 2
2 2019-01-03 13 3
df_reindex = df.set_index(['date','other']).reset_index()
date other value
0 2019-01-01 11 1
1 2019-01-02 12 2
2 2019-01-03 13 3
print pd.merge(df, df_reindex, on='date')
Empty DataFrame
Columns: [date, other_x, value_x, other_y, value_y]
Index: []
print pd.merge(df, df, on='date')
date other_x value_x other_y value_y
0 2019-01-01 11 1 11 1
1 2019-01-02 12 2 12 2
2 2019-01-03 13 3 13 3
print pd.merge(df_reindex, df_reindex, on='date')
date other_x value_x other_y value_y
0 2019-01-01 11 1 11 1
1 2019-01-02 12 2 12 2
2 2019-01-03 13 3 13 3
print type(df.date[0])
<type 'datetime.date'>
print type(df_reindex.date[0])
<class 'pandas._libs.tslib.Timestamp'>
Здесь и df
, и df_reindex
имеют по существу одинаковое содержимое данных, но из-за того, что тип был изменен внутри Панд в точке set_index
, слияние между ними пустое, в то время как «самослияние» между любым из двух с самим собой дает ожидаемый (хотя, в данном случае надуманный, избыточный и тривиальный) результат.
Реальные случаи, конечно, достигают этой точки без капризной установки и сброса индекса следующим образом: реальные данные проходят через несколько битов кода, выполняя различные операции с различными требованиями к индексации на разных этапах, и объединениемежду кадрами, в которых есть несколько неперекрывающихся столбцов.
Есть комментарий к моему другому вопросу об использовании даты и времени NumPy, но это кажется бесполезным, поскольку преобразование, очевидно, приводит к одному из двух проблемных типов данных, то естьбазовый класс Pandas:
df_numpy = df.copy()
df_numpy.date = df.date.apply(np.datetime64)
print type(df.date[0])
<type 'datetime.date'>
print type(df_numpy.date[0])
<class 'pandas._libs.tslib.Timestamp'>
(Не говоря уже о том, что я работаю в рамках существующего фреймворка, поэтому на данном этапе может быть невозможно заставить все кадры иметь типы NumPy вместо типов Pandas.)
Что мне нужно сделать, так это уметь объединять таблицы внутри кода библиотеки, независимо от того, были ли они так манипулированы вызывающей стороной вне моего контроля. Кадры данных, которые я получаю в качестве входных данных, не могут быть изменены. Я мог бы скопировать их и реализовать прямое преобразование копий (как здесь панды объединяются при выпуске столбца даты ), но рамки иногда бывают большими, и я не хочу копировать их, если нет другого выбора.
Есть ли способ заставить объединение признать их эквивалентными? Если нет, есть ли лучший выбор формата даты, позволяющий избежать проблемы конвертации, которая здесь описана?