pandas.to_datetime() автоматически преобразуется в ‹M8[ns] и не может использовать numpy.isnat()

У меня есть кадр данных, который был прочитан как строка, содержащая дату в формате «ГГГГ-ММ-ДД». Я преобразовал столбец в дату и время, используя pd.to_datetime (с принуждением), и я собираюсь искать столбец для NaT, используя numpy.isnat().

defaultDate = datetime.datetime(2020, 12, 31)
df['dates'] = pd.to_datetime(df['dates'], errors = 'coerce')
df['newDates'] = [x if ~np.isnat(x) else defaultDate for x in df['dates']]

При попытке запустить код получаю ошибку:

**TypeError**: ufunc 'isnat' is only defined for datetime and timedelta.

Позже я узнал, что dtype столбца был преобразован в ‹M8[ns]. Есть ли способ правильно преобразовать дату и время или как-то обойти это? У меня пустая версия 1.16.4.


person just4lizzy    schedule 21.10.2019    source источник
comment
Попробуйте [x if ~np.isnat(x) else defaultDate for x in df['dates'].values]. а почему не pd.isnull()?   -  person Buckeye14Guy    schedule 21.10.2019


Ответы (2)


<M8[ns] является синонимом datetime64[ns]. Кроме того, вам не нужно np.isnat, если вы имеете дело с пандами datetime:

defaultDate = pd.to_datetime('2020-12-31')
df['newDates'] = [x if ~np.isnat(x) else defaultDate for x in df['dates']]
df['newDates'] = df['dates'].fillna(defaultDate)
person Quang Hoang    schedule 21.10.2019

Похоже, isnat предназначен для проверки массива, например:

In [47]: np.array([0,1,'NaT'], 'datetime64[D]')                                 
Out[47]: array(['1970-01-01', '1970-01-02',        'NaT'], dtype='datetime64[D]')
In [48]: np.isnat(_)                                                            
Out[48]: array([False, False,  True])

Мне пришлось поэкспериментировать, чтобы узнать, как сгенерировать элемент NaT. Могут быть и другие способы.

Можете ли вы предоставить кадр данных или серию, в которой есть образцы значений, как действительные даты, так и недаты. Это облегчит изучение способов фильтрации. Я считаю, что у панд есть какой-то элемент не времени, но я не знаю, совместим ли он с элементом numpy. Имейте также в виду, что pandas легко переключается на dtype объекта, когда элементы Series включают строки и None.

Тестирование серии:

In [50]: ds = pd.Series(_47)                                                    
In [51]: ds                                                                     
Out[51]: 
0   1970-01-01
1   1970-01-02
2          NaT
dtype: datetime64[ns]
In [52]: ds.isna()                                                              
Out[52]: 
0    False
1    False
2     True
dtype: bool
In [54]: ds.isnull()                                                            
Out[54]: 
0    False
1    False
2     True
dtype: bool

Изменить элемент серии:

In [58]: ds[2]=12                                                               
In [59]: ds                                                                     
Out[59]: 
0    1970-01-01 00:00:00
1    1970-01-02 00:00:00
2                     12
dtype: object

который изменяет dtype

In [60]: ds.values                                                              
Out[60]: 
array([Timestamp('1970-01-01 00:00:00'), Timestamp('1970-01-02 00:00:00'),
       12], dtype=object)
In [61]: np.isnat(_)                                                            
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-61-47ce91c66a51> in <module>
----> 1 np.isnat(_)

TypeError: ufunc 'isnat' is only defined for datetime and timedelta.

Возможная последовательность преобразования:

Серия со смесью дат и чего-то еще, object dtype:

In [118]: ds                                                                    
Out[118]: 
0    1970-01-01 00:00:00
1    1970-01-02 00:00:00
2                     12
dtype: object
In [119]: ds1=pd.to_datetime(ds,errors='coerce')                                
In [120]: ds1                                                                   
Out[120]: 
0   1970-01-01
1   1970-01-02
2          NaT
dtype: datetime64[ns]

преобразование с принуждением производит NaT:

In [121]: idx = np.isnat(ds1)                                                   
In [122]: idx                                                                   
Out[122]: 
0    False
1    False
2     True
dtype: bool
In [123]: ds1[idx]                                                              
Out[123]: 
2   NaT
dtype: datetime64[ns]

определить правильное значение по умолчанию; его dtype важен, так как pandas легко меняет dtype (numpy нет):

In [124]: default= np.array('2020-12-31','datetime64[ns]')[()]                  
In [125]: default                                                               
Out[125]: numpy.datetime64('2020-12-31T00:00:00.000000000')
In [126]: ds1[idx]=default                                                      
In [127]: ds1                                                                   
Out[127]: 
0   1970-01-01
1   1970-01-02
2   2020-12-31
dtype: datetime64[ns]
person hpaulj    schedule 21.10.2019