【问题标题】:How do I tell if a column in a pandas dataframe is of type datetime? How do I tell if a column is numerical?如何判断 pandas 数据框中的列是否为 datetime 类型?如何判断一列是否为数字?
【发布时间】:2017-08-30 01:34:08
【问题描述】:

我正在尝试根据它们是否为日期类型来过滤熊猫数据框中的列。我可以弄清楚哪些是,但随后必须解析该输出或手动选择列。我想自动选择日期列。这是我到目前为止的示例 - 在这种情况下,我只想选择“date_col”列。

import pandas as pd
df = pd.DataFrame([['Feb-2017', 1, 2],
                   ['Mar-2017', 1, 2],
                   ['Apr-2017', 1, 2],
                   ['May-2017', 1, 2]], 
                  columns=['date_str', 'col1', 'col2'])
df['date_col'] = pd.to_datetime(df['date_str'])
df.dtypes

输出:

date_str            object
col1                 int64
col2                 int64
date_col    datetime64[ns]
dtype: object

【问题讨论】:

    标签: python pandas numpy dataframe


    【解决方案1】:

    我刚遇到这个问题,发现@charlie-haley 的回答对于我的用例来说不够笼统。特别是np.datetime64 似乎与datetime64[ns, UTC] 不匹配。

    df['date_col'] = pd.to_datetime(df['date_str'], utc=True)
    print(df.date_str.dtype)  # datetime64[ns, UTC]
    

    您还可以扩展 dtypes 列表以包含其他类型,但这似乎不是未来兼容性的好解决方案,因此我最终使用了 pandas api 中的 is_datetime64_any_dtype 函数。

    在:

    from pandas.api.types import is_datetime64_any_dtype as is_datetime
    
    df[[column for column in df.columns if is_datetime(df[column])]]
    

    输出:

                       date_col
    0 2017-02-01 00:00:00+00:00
    1 2017-03-01 00:00:00+00:00
    2 2017-04-01 00:00:00+00:00
    3 2017-05-01 00:00:00+00:00
    

    【讨论】:

    • 尽管严格来说是正确的,但我想指出的是,这个解决方案没有检测到datetime.date 字段
    【解决方案2】:

    Pandas 有一个很酷的函数select_dtypes,它可以将排除或包含(或两者)作为参数。它根据 dtypes 过滤数据框。因此,在这种情况下,您需要包含 dtype np.datetime64 的列。要按整数过滤,您可以使用[np.int64, np.int32, np.int16, np.int],对于浮点数:[np.float32, np.float64, np.float16, np.float],仅按数字列过滤:[np.number]

    df.select_dtypes(include=[np.datetime64])
    

    输出:

        date_col
    0   2017-02-01
    1   2017-03-01
    2   2017-04-01
    3   2017-05-01
    

    在:

    df.select_dtypes(include=[np.number])
    

    输出:

        col1    col2
    0   1       2
    1   1       2
    2   1       2
    3   1       2
    

    【讨论】:

      【解决方案3】:

      有点丑的 Numpy 替代方案:

      In [102]: df.loc[:, [np.issubdtype(t, np.datetime64) for t in df.dtypes]]
      Out[102]:
          date_col
      0 2017-02-01
      1 2017-03-01
      2 2017-04-01
      3 2017-05-01
      
      In [103]: df.loc[:, [np.issubdtype(t, np.number) for t in df.dtypes]]
      Out[103]:
         col1  col2
      0     1     2
      1     1     2
      2     1     2
      3     1     2
      

      【讨论】:

        【解决方案4】:

        此代码自动识别日期列并将数据类型从对象更改为“datetime64[ns]”。获得日期数据类型后,您可以轻松执行其他操作。

        for col in data.columns:
            if data[col].dtype == 'object':
                try:
                    data[col] = pd.to_datetime(data[col])
                except ValueError:
                    pass
        

        【讨论】:

          【解决方案5】:

          最近我需要检查列的任何元素是日期还是数字

          我的方法是,尝试转换为类型(日期时间或数字),然后检查是否有任何元素为空

          pd.to_datetime( data_temp.eval('col_name'), format='%d/%m/%Y', errors='coerce')
          

          输出:

          0   2010-09-16
          1   2010-09-16
          2   2018-06-04
          3          NaT
          4          NaT
          5   2018-11-30
          

          然后使用isnull()检查元素是否可以转换

          pd.to_datetime( data_temp.eval('col_name'), format='%d/%m/%Y', errors='coerce').isnull().any()
          

          这将返回 True,因为最后一个元素是 null/NaT

          检查数字

          data_temp.eval('col_name').astype(str).str.isnumeric().all()
          

          如果列上的所有元素都是数字,这将返回 True

          两者都会返回一个 numpy.bool_,但如果需要,它可以很容易地转换为 bool

          type(pd.to_datetime( data_temp.eval(name), format='%d/%m/%Y', errors='coerce').isnull().any())
          

          输出:

          numpy.bool_
          

          --

          type(bool(pd.to_datetime( data_temp.eval(name), format='%d/%m/%Y', errors='coerce').isnull().any()))
          

          输出:

          bool
          

          【讨论】:

            【解决方案6】:

            这应该适用于其中包含时区信息的日期时间。在这里,我将一个日期时间对象(最初存储为对象)转换为日期时间,然后将其本地化。

            我的初始日期时间值如下所示

            2021-06-15 23:35:00+05:30

            for i,j in zip(data.dtypes.index,data.dtypes.values):
                if type(j) ==  pd.core.dtypes.dtypes.DatetimeTZDtype:
                    data[i] = pd.to_datetime(data[i],utc=True)
                    data[i] = data[i].dt.tz_convert(tz='Asia/Kolkata')
                    data[i] = data[i].dt.tz_localize(tz=None)
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-01-25
              • 1970-01-01
              • 2017-03-05
              • 2013-09-29
              • 2011-05-31
              • 2013-08-19
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多