python --pandas数据类型

学习目标

  • 知道Pandas中都有哪些数据类型和数据结构,并知道数据类型和数据结构之间的关系

  • 知道时间日期类型作为索引的数据集可以基于时间范围来选取子集

  • 知道时间差类型索引的数据集可以基于时间差范围来选取子集

1 一般类型

Pandas数据类型Python类型说明
objectstr字符串
int64int整数
float64float浮点数
boolbool布尔值
category无原生类型分类类型
datetime无原生类型时间日期类型
timedelta无原生类型时间差类型
  • pandas是基于numpy构建的包,所以pandas中的数据类型都是基于Numpy中的ndarray类型实现的

  • Pandas中的数据结构对象和数据类型对象:

    • dataframe 表 【数据结构】

      • series 列【数据结构】

        • object --> python str 字符串 【数据类型】

        • int64 --> python int 整数 【数据类型】

        • float64 --> python float 小数 【数据类型】

        • bool --> python bool True False 【数据类型】

        • datetime64 --> python datetime 时间日期 【数据类型】

        • timedelta[ns]--> 两个时间点之间相距的时间差,单位是纳秒 【数据类型】

        • category --> 特定分类数据类型,比如性别分为男、女、其他 【数据类型】

  • 字符串object 、整数int、小数float 以及 布尔值bool类型都是比较常见的一般类型;本章节将详细介绍不常见的 分类类型、 时间类型 以及 时间差类型

    import pandas as pd
    ​
    # 加载印度城市空气质量数据集
    df = pd.read_csv('../data/city_day.csv')
    ​
    # 查看数据集各列及各自的数据类型
    df.info()
    ​
    # 数据结果如下
    <class 'pandas.core.frame.DataFrame'>
    DatetimeIndex: 29531 entries, 2015-01-01 to 2020-07-01
    Data columns (total 15 columns):
     #   Column      Non-Null Count  Dtype  
    ---  ------      --------------  -----  
     0   City        29531 non-null  object 
     1   PM2.5       24933 non-null  float64
     2   PM10        18391 non-null  float64
     3   NO          25949 non-null  float64
     4   NO2         25946 non-null  float64
     5   NOx         25346 non-null  float64
     6   NH3         19203 non-null  float64
     7   CO          27472 non-null  float64
     8   SO2         25677 non-null  float64
     9   O3          25509 non-null  float64
     10  Benzene     23908 non-null  float64
     11  Toluene     21490 non-null  float64
     12  Xylene      11422 non-null  float64
     13  AQI         24850 non-null  float64
     14  AQI_Bucket  24850 non-null  object 
    dtypes: float64(13), object(2)
    memory usage: 3.6+ MB

2 类型转换

通过 astype()to_numeric() 实现类型转换

2.1 seriers.astype函数转换数据类型

astype函数是通用函数,可用于把DataFrame中的任何列(Series)转换为其他dtype;可以向astype方法提供任何内置类型或numpy类型来转换列(Series)的数据类型

  • astype函数使用

    print(df['PM2.5'].astype(dtype=str))
    print(df['PM2.5'].astype(dtype=object))
    ​
    # 以上效果相同, 输出结果如下
    0          NaN
    1          NaN
    2          NaN
    3          NaN
    4          NaN
             ...  
    29526    15.02
    29527    24.38
    29528    22.91
    29529    16.64
    29530       15
    Name: PM2.5, Length: 29531, dtype: object
  • astype注意点

    astype函数要求DataFrame列的数据类型必须相同,当有些数据中有缺失,但不是NaN时(如'missing','null'等),会使整列数据变成字符串类型而不是数值型,这个时候就会报错

    df2 = df.head().copy()
    # 创造包含'missing'为缺失值的数据,批量替换第1、3、5行中NO列的值为字符串'missing'
    df2.loc[::2, 'NO'] = 'missing'
    print(df2)
    print(df2['NO'].dtypes)
    ​
    # 输出结果如下
            City        Date  PM2.5  PM10  ... Toluene  Xylene  AQI  AQI_Bucket
    0  Ahmedabad  2015-01-01    NaN   NaN  ...    0.02    0.00  NaN         NaN
    1  Ahmedabad  2015-01-02    NaN   NaN  ...    5.50    3.77  NaN         NaN
    2  Ahmedabad  2015-01-03    NaN   NaN  ...   16.40    2.25  NaN         NaN
    3  Ahmedabad  2015-01-04    NaN   NaN  ...   10.14    1.00  NaN         NaN
    4  Ahmedabad  2015-01-05    NaN   NaN  ...   18.89    2.78  NaN         NaN
    ​
    [5 rows x 16 columns]
    object
  • 此时运行下面的代码会报错ValueError: could not convert string to float: 'missing',无法使用astype函数进行类型转换;这个时候我们可以使用to_numeric函数

    print(df2['NO'].astype(float))

2.2 pd.to_numeric函数字符串转数字类型

astype函数要求DataFrame列的数据类型必须相同,当有些数据中有缺失,但不是NaN时(如'missing','null'等),会使整列数据变成字符串类型而不是数值型,这个时候可以使用to_numeric处理

  • pd.to_numeric函数的参数errors, 它决定了当该函数遇到无法转换的数值时该如何处理

    • 默认情况下,该值为raise,如果to_numeric遇到无法转换的值时,会抛出异常

    • coerce: 如果to_numeric遇到无法转换的值时,会返回NaN值

    • ignore: 如果to_numeric遇到无法转换的值时会放弃转换,什么都不做

    # 转换成float类型, 抛出异常:ValueError: Unable to parse string "missing" at position 0
    # print(pd.to_numeric(df2['NO']))
    # 无法转换的值返回NaN
    print(pd.to_numeric(df2['NO'], errors='coerce'))
    # 无法转换的值返回原值
    print(pd.to_numeric(df2['NO'], errors='ignore'))
    ​
    # 输出结果
    0     NaN
    1    0.97
    2     NaN
    3    1.70
    4     NaN
    Name: NO, dtype: float64
    0    missing
    1       0.97
    2    missing
    3        1.7
    4    missing
    Name: NO, dtype: object

3 category分类类型

  • category类型是比较特殊的数据类型,是由固定的且有限数量的变量组成的,比如性别,分为男、女、保密;转换方法可以使用astype函数

  • category类型的数据中的分类是有顺序的

  • category类型在内存中使用的空间比字符串或其他数据类型更小。这对于数据集中有限且重复的值非常有用

3.1 创建分类类型

  • 方式一

    s = pd.Series(pd.Categorical(["a","a", "b", "c", "d"],categories=["c", "b", "a"]))
    print(s)
    ​
    # 输出结果如下
    0      a
    1      b
    2      c
    3    NaN
    dtype: category
    Categories (3, object): ['c', 'b', 'a']
  • 方式二

    s2 = pd.Series(['A','C','B','D','C','A'], dtype='category')
    print(s2)
    ​
    # 输出结果如下
    0    B
    1    D
    2    C
    3    A
    dtype: category
    Categories (4, object): ['A', 'B', 'C', 'D']

3.2 分类类型转换

s = pd.Series(['a', 'b', 'c', 'c', 'a'])   # 这是一个S对象,但是dtype类型是 Object
s2 = s.astype('category')    # 转换之后s2依然是一个S对象,但是dtype类型是 Category
print(s2)
# 输出结果如下
0    a
1    b
2    c
3    c
4    a
dtype: category
Categories (3, object): [a, b, c]

4 datetime时间类型

4.1 Python中的datetime类型

  • python没有原生的datetime数据类型,需要使用datetime包

    from datetime import datetime
    now = datetime.now()  # 2024-06-11 11:42:10.229232, 最后这个时间是微妙
    someday = datetime(2020, 1, 1)  # 造一个时间对象 :2020-01-01 00:00:00
    print(now)
    print(type(now))
    print(someday)
    print(type(someday))
    ​
    # 返回输出结果如下
    2024-02-07 09:50:20.461322
    <class 'datetime.datetime'>
    2020-01-01 00:00:00
    <class 'datetime.datetime'>

4.2 读取数据时指定列为datetime类型

  • 读取数据集时,使用参数parse_dates=[列下标/列名]直接将转为datetime类型

    # 加载印度城市空气质量数据集
    # df = pd.read_csv('../data/city_day.csv', parse_dates=[1])
    # 如果你不指定parse_dates,则Date这一列默认是Object,指定了之后,可以在读取数据时直接转为日期类型
    # 转为日期类型之后,就可以调用日期类相关的方法
    df = pd.read_csv('../data/city_day.csv', parse_dates=['Date'])
    print(df['Date'].head())
    ​
    # 数据结果如下
    0   2015-01-01
    1   2015-01-02
    2   2015-01-03
    3   2015-01-04
    4   2015-01-05
    Name: Date, dtype: datetime64[ns]

4.3 pd.to_datetime将字符串转换为时间日期类型

df = pd.read_csv('../data/city_day.csv')
# 查看Date列数据类型
print(df['Date'].head())
# 将Date列数据转换为时间类型
df['Date'] = pd.to_datetime(df['Date'])
print(df['Date'].head())
​
# 输出结果如下
0    2015-01-01
1    2015-01-02
2    2015-01-03
3    2015-01-04
4    2015-01-05
Name: Date, dtype: object
0   2015-01-01
1   2015-01-02
2   2015-01-03
3   2015-01-04
4   2015-01-05
Name: Date, dtype: datetime64[ns]

4.4 提取datetime类型数据中具体时间

  • 由datetime构成的Seriers提取时间日期中的各个部分

    # print(df['Date'].year) # 报错
    print(df['Date'].dt.year)
    print(df['Date'].dt.month)
    print(df['Date'].dt.day)
    print(df['Date'].dt.hour)
    print(df['Date'].dt.minute)
    print(df['Date'].dt.second)
    print(df['Date'].dt.quarter) # 季度
    print(df['Date'].dt.dayofweek + 1) # 星期,与 df['Date'].dt.weekday+1 相同
    print(df['Date'].dt.weekday + 1) # 星期 ,作用同上
  • 由datetime构成的Seriers的其中一个数据提取时间日期中的各个部分

    d = pd.to_datetime('2019-01-01 12:34:56')
    print(d)  # d ==> 2019-01-01 12:34:56
    print(type(d))  # <class 'pandas._libs.tslibs.timestamps.Timestamp'>
    print(d.year)
    print(d.month)
    print(d.day)
    print(d.hour)
    print(d.minute)
    print(d.second)
    print(d.quarter)  # 季度
    print(d.weekday())  # 星期几,与d.dayofweek相同 0是星期一 1是星期二 6是星期日
    print(d.dayofweek + 1) 

4.5 datetime类型的Seriers进行时间计算

  • datetime类型的日期可以直接进行时间计算:

    • 可以直接使用聚合函数

    • 也可以直接进行时间差运算

    # 直接调用聚合函数
    print(df['Date'].min())  # 求日期的最小值
    # 直接进行时间差运算
    #  返回时间差类型数据构成的Seriers,得到的时间差格式:12 days,是
    print(df['Date'] - df['Date'].min())# 2020-07-01 00:00:00  - 2015-01-01 00:00:00
    # 输出结果如下
    2015-01-01 00:00:00
    0          0 days
    1          1 days
    2          2 days
    3          3 days
    4          4 days
               ...   
    29526   2004 days
    29527   2005 days
    29528   2006 days
    29529   2007 days
    29530   2008 days
    Name: Date, Length: 29531, dtype: timedelta64[ns]

4.6 datetime类型数据列作为df索引

  • datetime类型数据列作为df索引可以通过具体的时间查询df子集

    # 加载数据集,设定时间类型列为索引列
    df = pd.read_csv('../data/city_day.csv', index_col='Date', parse_dates=True)
    ​
    # 对索引进行重新排序
    df = df.sort_index('Date')  # 必要步骤
    print(df.loc['2018'])  #  索引排序之后,才能按年取子集df
    print(df.loc['2016-06'])  #    按年月取子集df:所有符合条件的完整行数据
    print(df.loc['2015-3-4 22:01:01': '2016-1-1 23:45:00'])  # 按时间范围取子集
    ​
    # 输出结果如下
                         City   PM2.5    PM10  ...  Xylene    AQI  AQI_Bucket
    Date                                       ...                           
    2018-01-01      Hyderabad   57.70  119.64  ...    3.74  122.0    Moderate
    2018-01-01          Delhi  303.41  415.09  ...    0.24  462.0      Severe
    2018-01-01      Ahmedabad   84.46     NaN  ...    6.33  278.0        Poor
    2018-01-01  Visakhapatnam   59.73   99.04  ...    0.66  131.0    Moderate
    2018-01-01        Talcher     NaN     NaN  ...     NaN    NaN         NaN
    ...                   ...     ...     ...  ...     ...    ...         ...
    2018-12-31   Brajrajnagar  113.28  187.85  ...     NaN  236.0        Poor
    2018-12-31      Ahmedabad   80.54     NaN  ...    6.93  744.0      Severe
    2018-12-31        Lucknow  248.51     NaN  ...     NaN  403.0      Severe
    2018-12-31        Talcher   84.30  263.09  ...     NaN  200.0    Moderate
    2018-12-31       Amritsar   78.42  186.41  ...    9.09  184.0    Moderate
    ​
    [6471 rows x 15 columns]
                     City   PM2.5    PM10  ...  Xylene    AQI    AQI_Bucket
    Date                                   ...                             
    2016-06-01      Patna   68.89     NaN  ...    0.45  147.0      Moderate
    2016-06-01    Lucknow  138.37     NaN  ...     NaN  207.0          Poor
    2016-06-01  Ahmedabad     NaN     NaN  ...     NaN    NaN           NaN
    2016-06-01      Delhi   76.56  251.87  ...     NaN  283.0          Poor
    2016-06-01  Hyderabad   39.88     NaN  ...    0.23  111.0      Moderate
    ...               ...     ...     ...  ...     ...    ...           ...
    2016-06-30     Mumbai     NaN     NaN  ...     NaN    NaN           NaN
    2016-06-30    Lucknow   89.00     NaN  ...     NaN   59.0  Satisfactory
    2016-06-30      Patna   45.54     NaN  ...    0.17   85.0  Satisfactory
    2016-06-30      Delhi   69.65  103.25  ...     NaN  190.0      Moderate
    2016-06-30  Ahmedabad   30.16     NaN  ...    0.00  256.0          Poor
    ​
    [270 rows x 15 columns]
                     City   PM2.5    PM10  ...  Xylene    AQI  AQI_Bucket
    Date                                   ...                           
    2015-03-05      Delhi  106.57  196.19  ...   10.65  275.0        Poor
    2015-03-05  Hyderabad     NaN     NaN  ...    1.01    NaN         NaN
    2015-03-05    Lucknow     NaN     NaN  ...     NaN    NaN         NaN
    2015-03-05  Ahmedabad  173.01     NaN  ...    4.13  780.0      Severe
    2015-03-05    Chennai     NaN     NaN  ...     NaN    NaN         NaN
    ...               ...     ...     ...  ...     ...    ...         ...
    2016-01-01  Bengaluru   56.40   95.08  ...     NaN  101.0    Moderate
    2016-01-01      Delhi  295.71  476.09  ...    0.00  463.0      Severe
    2016-01-01  Hyderabad  232.83  108.20  ...    2.41  387.0   Very Poor
    2016-01-01      Patna  553.63     NaN  ...    2.34  619.0      Severe
    2016-01-01    Lucknow  203.43     NaN  ...     NaN  375.0   Very Poor
    ​
    [2372 rows x 15 columns]

5 timedelta时间差类型

5.1 Python中的timedelta类型

  • python没有原生的timedelta数据类型,需要使用datetime包

    from datetime import datetime
    ​
    t1 = datetime.now()
    t2 = datetime(2020, 1, 1)
    diff = t1 - t2
    # 时间差类型
    print(diff)
    print(type(diff))
    ​
    # 输出结果如下
    1498 days, 10:07:14.970549
    <class 'datetime.timedelta'>

5.2 Pandas中的timedelta类型

  • 两个时间Seriers相减即可得到timedelta类型数据构成的Seriers对象

    # 加载数据,指定下标为1的列为时间日期类型
    df = pd.read_csv('../data/city_day.csv', parse_dates=[1])
    # 当前日期减去数据集中最早的日期,即可得到时间差;同时赋值给新的列
    df['ref_date'] = df['Date'] - df['Date'].min()  # s对象也可以相减,得到时间差类型的s对象
    print(df['ref_date'].head())
    ​
    # 输出结果如下
    0   0 days
    1   1 days
    2   2 days
    3   3 days
    4   4 days
    Name: ref_date, dtype: timedelta64[ns]

5.3 pd.to_timedelta函数转换timedelta类型

  • timedelta类型转换为字符串类型

    s1 = df['ref_date'].astype(str)  # 将时间差类型的s对象象转为 字符串类型的S对
    print(s1)
    ​
    # 返回结果如下
    0           0 days
    1           1 days
    2           2 days
    3           3 days
    4           4 days
               ...    
    29526    2004 days
    29527    2005 days
    29528    2006 days
    29529    2007 days
    29530    2008 days
    Name: ref_date, Length: 29531, dtype: object
  • 字符串类型转换为timedelta类型

    s2 = pd.to_timedelta(s1) # 将字符串类型的S对象转为 时间差类型的s对象
    print(s2)
    ​
    # 返回结果如下
    0          0 days
    1          1 days
    2          2 days
    3          3 days
    4          4 days
               ...   
    29526   2004 days
    29527   2005 days
    29528   2006 days
    29529   2007 days
    29530   2008 days
    Name: ref_date, Length: 29531, dtype: timedelta64[ns]

5.4 timedelta类型数据作为df索引

  • 如果将timedelta类型数据作为df索引,就可以基于时间差范围来选择数据

    # 读取数据,并将下标为1的Date列设为时间类型列
    df = pd.read_csv('../data/city_day.csv', parse_dates=[1])
    # 获取印度城市德里的子集
    df2 = df.query('City=="Delhi"')
    # 将timedelta类型的Series设置为df的索引
    # df2.索引 = Date列 - Date列最早的那一天
    ​
    ​
    df2.index = df2['Date'] - df2['Date'].min()
    ​
    ​
    print(df2.head())  # 查看数据集
    # 基于时间差范围来选择数据
    print(df2['0 days':'4 days'])
    ​
    # 输出结果如下
             City       Date   PM2.5    PM10  ...  Toluene  Xylene    AQI  AQI_Bucket
    Date                                      ...                                    
    0 days  Delhi 2015-01-01  313.22  607.98  ...    24.86    9.84  472.0      Severe
    1 days  Delhi 2015-01-02  186.18  269.55  ...    20.09    4.29  454.0      Severe
    2 days  Delhi 2015-01-03   87.18  131.90  ...    10.23    1.99  143.0    Moderate
    3 days  Delhi 2015-01-04  151.84  241.84  ...     9.71    3.34  319.0   Very Poor
    4 days  Delhi 2015-01-05  146.60  219.13  ...     6.21    2.96  325.0   Very Poor
    ​
    [5 rows x 16 columns]
             City       Date   PM2.5    PM10  ...  Toluene  Xylene    AQI  AQI_Bucket
    Date                                      ...                                    
    0 days  Delhi 2015-01-01  313.22  607.98  ...    24.86    9.84  472.0      Severe
    1 days  Delhi 2015-01-02  186.18  269.55  ...    20.09    4.29  454.0      Severe
    2 days  Delhi 2015-01-03   87.18  131.90  ...    10.23    1.99  143.0    Moderate
    3 days  Delhi 2015-01-04  151.84  241.84  ...     9.71    3.34  319.0   Very Poor
    4 days  Delhi 2015-01-05  146.60  219.13  ...     6.21    2.96  325.0   Very Poor
    ​
    [5 rows x 16 columns]

总结

请对下面的内容 有印象、能找到、能理解、能看懂

1. Pandas中的数据类型

Pandas数据类型Python类型说明
objectstr字符串
int64int整数
float64float浮点数
boolbool布尔值
category无原生类型分类类型
datetime无原生类型时间日期类型
timedelta无原生类型时间差类型

2. Pandas中数据结构和数据类型的关系

  • pandas是基于numpy构建的包,所以pandas中的数据类型都是基于Numpy中的ndarray类型实现的

  • Pandas中的数据结构对象和数据类型对象:

    • dataframe 表 【数据结构】

      • series 列【数据结构】

        • object --> python str 字符串 【数据类型】

        • int64 --> python int 整数 【数据类型】

        • float64 --> python float 小数 【数据类型】

        • bool --> python bool True False 【数据类型】

        • datetime64 --> python datetime 时间日期 【数据类型】

  • timedelta[ns]--> 两个时间点之间相距的时间差,单位是纳秒 【数据类型】

  • category --> 特定分类数据类型,比如性别分为男、女、其他 【数据类型】

3. Pandas数据类型转换基本方法

  • df['列名'].astype(str)

  • 当Seriers对象使用astype函数转换的结果中数据类型不同时,使用to_numeric函数

    • pd.to_numeric(df['列名'], errors='coerce')无法转换的值返回NaN

    • pd.to_numeric(df['列名'], errors='ignore') 无法转换的值返回原值

4. category分类类型

  • 创建方式s = pd.Series(['B','D','C','A'], dtype='category')

5. datetime时间类型

  • datetime时间类型的Seriers来源两种方式:

    • 读取时指定 df = pd.read_csv('..xxx.csv', parse_dates=[1])

    • 转换 df['Date'] = pd.to_datetime(df['Date'])

  • 提取datetime时间类型的Seriers中的具体年月日时分秒星期

    • df['Date'].dt.year

    • df['Date'].dt.quarter # 季度

    • df['Date'].dt.dayofweek + 1 # 星期

  • 提取datetime时间类型的Seriers中的某一个值的具体年月日时分秒星期

    • df4['Date'][0].dayofweek+1 # 星期

  • datetime时间类型的Seriers可以进行时间计算

    • 直接调用聚合函数 df['Date'].max() # 最近的日期

    • 计算时间差 df['Date'] - df['Date'].min() # 返回时间差类型数据构成的Seriers

  • datetime时间类型的S对象作为索引的两种方式

    • df = pd.read_csv('..xxx.csv', index_col='Date', parse_dates=True)

    • df.index = df['date']

    • 注意:要对索引进行重新排序 必要步骤 df = df.sort_index()

  • datetime时间类型索引可以按照时间范围取子集

    • df['2018']

    • df['2016-06']

    • df.loc['2015-3-4 22': '2016-1-1 23:45:00']

6. timedelta时间差类型

  • timedelta时间差类型的创建:

    • df['date_diff'] = df['Date'] - df['Date'].min()

  • 字符串类型转换为时间差类型

    • s2 = pd.to_timedelta(s1)

  • timedelta时间差类型设为索引

    • df.index = df['Date'] - df['Date'].min()

  • 基于时间差范围来选择数据

    • df['0 days':'4 days']

  • 27
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值