Soru Numpy: NaT değerinin olup olmadığını kontrol etme


nat = np.datetime64('NaT')
nat == nat
>> FutureWarning: In the future, 'NAT == x' and 'x == NAT' will always be False.

np.isnan(nat)
>> TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

Datetime64 NaT olup olmadığını nasıl kontrol edebilirim? Dokümanlardan bir şey kazmaya çalışmıyorum. Panda'ların yapabileceğini biliyorum, ancak bu kadar basit bir şeye bağımlılık eklemem.


25
2017-07-21 16:25


Menşei


İle karşılaştırabilirsiniz np.datetime64('NaT') aslında: nat == np.datetime64('NaT') Çıktı: True. - Vadim Shkaberda
1.11.1 kullanıyor musunuz? NaT'ler artık karşılaştırılamaz: github.com/numpy/numpy/blob/master/doc/release/1.11.0-notes.rst - user65
Özür dilerim, dikkatsizlikti. 1. Şimdi karşılaştırabilirsiniz nat == nat ve geri dönecek True. 2. Github'da olduğu gibi, numpy 1.12.0 hala mukayese edebileceksiniz NaT: nat != np.datetime64('NaT') dönecek TrueAksi takdirde NaT ile ilgili tüm karşılaştırmalar False değerini döndürür. Sonuç olarak, son sonuç: önce numpy sürümünü kontrol etmeniz ve sonra nasıl karşılaştırılacağını seçmeniz gerekir. NaTVar. - Vadim Shkaberda
Bir değerin NaT olup olmadığını nasıl kontrol edeceğinize dair bir örnek verebilir misiniz? Operatörün ne işe yaradığına bakılmaksızın hala uyarı alıyorum. - user65
Vadim'in yanıtını kabul edermisin? FutureWarning, NumPy geliştiricilerinin bir şeyleri değiştirmeyi planladıklarını ve böylece yanıtın artık çalışmadığını söylüyor. - user2357112


Cevaplar:


GİRİŞ: Bu cevap, Numpy'nin 1.11 sürümünün olduğu ve NAT 1.12 sürümünden beri NAT karşılaştırmasının davranışının değiştiği bir zamanda yazılmıştır. Açıkçası bu durum böyle değildi ve cevabın ikinci kısmı yanlış oldu. Yanıtın ilk kısmı, numpy'nin yeni sürümleri için geçerli olmayabilir. MSeifert'in cevaplarını aşağıda kontrol ettiğinden emin ol.


İlk kez bir karşılaştırma yaptığınızda, her zaman bir uyarınız vardır. Ancak bu arada karşılaştırma sonucu doğrudur:

import numpy as np    
nat = np.datetime64('NaT')

def nat_check(nat):
    return nat == np.datetime64('NaT')    

nat_check(nat)
Out[4]: FutureWarning: In the future, 'NAT == x' and 'x == NAT' will always be False.
True

nat_check(nat)
Out[5]: True

Eğer uyarıyı bastırmak istiyorsanız catch_warnings içerik yöneticisi:

import numpy as np
import warnings

nat = np.datetime64('NaT')

def nat_check(nat):
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        return nat == np.datetime64('NaT')    

nat_check(nat)
Out[5]: True


DÜZENLE: Bazı nedenlerden dolayı, Numpy sürüm 1.12'deki NAT karşılaştırması değişmedi, dolayısıyla bir sonraki kod tutarsız çıktı.

Son olarak, 1.12.0 sürümünden beri değişen davranışları ele almak için numpy sürümünü kontrol edebilirsiniz:

def nat_check(nat):
    if [int(x) for x in np.__version__.split('.')[:-1]] > [1, 11]:
        return nat != nat
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        return nat == np.datetime64('NaT')


8
2017-07-22 16:22



Sadece isnull () datetime64 tipine genişletmeyi mi unutmadılar, yoksa 1.13'te NaT'yi kontrol etmeyi imkansız hale getirmeyi mi planlıyorlar? NaT karşılaştırmasının neden amorti edildiğini anlıyorum, fakat neden alternatif olmadığını anlayamıyorum (uyarıları bastırmaktan başka?) - user65
@ user65 Sanırım bir analog yapabilecekler isnan(), gibi bir şey isnat(). Ve neden 1.13'den bahsediyorsun? 1.12 sürümüne ekleyebilirler. Ve bu şu anda bir uyarı görmenizin sebebi: NaT karşılaştırmaları değil kullanımdan kaldırıldı olacak sürüm 1.12'de kullanımdan kaldırılmış (aslında davranışları değişecektir). 1.11 sürümünde, daha önceki gibi kullanılabilir. - Vadim Shkaberda
NaN == NaN değil. NaT == NaT mu? Görünüşe göre, en azından benim etrafımda dolaşıyor. Bu yüzden bir tarih değerini şu şekilde test edersek: thisDate == thisDate ise:ve sonuç yanlıştır, o zaman bu tarih NaT'dir. Evet? - GDB
CodeCabbie'nin cevabı tecrübemden doğrudur ve NaT belirsizliğinin bunun doğru olmamasına neden olabilecek bir sorun olduğundan emin değilim. Herhangi bir belirsizlik durumun böyle olmasına neden olmazsa? - GDB
@GDB Ne zaman thisDate = np.datetime64('NaT') karşılaştırma sonucu if thisDate == thisDate   olduğu True. En azından şimdilik. - Vadim Shkaberda


 kontrol edebilir NaT ile pandas.isnull:

>>> import numpy as np
>>> import pandas as pd
>>> pd.isnull(np.datetime64('NaT'))
True

Eğer panda kullanmak istemiyorsanız, kendi fonksiyonunuzu da tanımlayabilirsiniz (pandalar kaynağından parçalar alınır):

nat_as_integer = np.datetime64('NAT').view('i8')

def isnat(your_datetime):
    dtype_string = str(your_datetime.dtype)
    if 'datetime64' in dtype_string or 'timedelta64' in dtype_string:
        return your_datetime.view('i8') == nat_as_integer
    return False  # it can't be a NaT if it's not a dateime

Bu, NaT değerlerini doğru bir şekilde tanımlar:

>>> isnat(np.datetime64('NAT'))
True

>>> isnat(np.timedelta64('NAT'))
True

Ve bir tarih veya timedelta değilse fark eder:

>>> isnat(np.timedelta64('NAT').view('i8'))
False

Gelecekte bir isnatnumpy kodundaki işlev, en azından şu anda bir (şu anda açık) çekme isteği var: PR'ye (NumPy github) bağlantı


34
2018-02-08 02:05





NumPy sürüm 1.13'ten beri bir isnat fonksiyon:

>>> import numpy as np
>>> np.isnat(np.datetime64('nat'))
True

Ayrıca diziler için de çalışır:

>>> np.isnat(np.array(['nat', 1, 2, 3, 4, 'nat', 5], dtype='datetime64[D]'))
array([ True, False, False, False, False,  True, False], dtype=bool)

10
2018-05-07 20:15





Çok basit ve şaşırtıcı derecede hızlı: (uyuşmuş veya pandalar olmadan)

    str( myDate ) == 'NaT'            # True if myDate is NaT

Tamam, bu biraz kötü, ama 'NaT' çevreleyen belirsizlik göz önüne alındığında iş güzelce.

Aynı zamanda NaT olabilecek iki tarihi karşılaştırırken de yararlıdır:

   str( date1 ) == str( date1 )       # True
   str( date1 ) == str( NaT )         # False
   str( NaT )   == str( date1 )       # False

wait for it...

   str( NaT )   == str( Nat )         # True    (hooray!)

2
2017-10-05 15:21



Bu tek bir NaT için çalışır, ancak vektörelleştirilmiş işlemlerde değil, örneğin False için np.array(['nat', 1, 2, 3, 4, 'nat', 5], dtype='datetime64[D]') - MSeifert
Kabul. OP'den bahsetmişken, bağımlılık gerektirmeyen tekniklerle geliyor. (Kullanıcı65 gibi görünüyor olsa da zaten numpy zaten kullanıyor, böylece gitmek için en iyi yol olacaktır.) - CodeCabbie


Bu yaklaşım, dizi yönelimli değerlendirmeyi korurken uyarılardan kaçınır.

import numpy as np
def isnat(x):
    """ 
    datetime64 analog to isnan.
    doesn't yet exist in numpy - other ways give warnings
    and are likely to change.  
    """
    return x.astype('i8') == np.datetime64('NaT').astype('i8')

1
2018-02-08 01:11





Başka bir yol, dışavuru yakalamak olabilir:

def is_nat(npdatetime):
    try:
        npdatetime.strftime('%x')
        return False
    except:
        return True

-2
2017-10-19 11:43