目录:
知道Pandas中都有哪些数据类型和数据结构,并知道数据类型和数据结构之间的关系
知道时间日期类型作为索引的数据集可以基于时间范围来选取子集
知道时间差类型索引的数据集可以基于时间差范围来选取子集
| Pandas数据类型 | Python类型 | 说明 |
|---|---|---|
| object | str | 字符串 |
| int64 | int | 整数 |
| float64 | float | 浮点数 |
| bool | bool | 布尔值 |
| 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
-
- # 加载印度城市空气质量数据集
- # index_col='Date' 指定Date列作为索引列
- # parse_dates=True 将Date列中的数据解析为时间类型
- city_day = pd.read_csv('../datas/data_set/city_day.csv', parse_dates=True, index_col='Date')
-
- # 查看数据集各列及各自的数据类型
- print(city_day.info())
astype函数
to_numeric函数
astype方法是通用函数,可用于把DataFrame中的任何列(Series)转换为其他dtype;可以向astype方法提供任何内置类型或numpy类型来转换列(Series)的数据类型
- import pandas as pd
-
- # 加载印度城市空气质量数据集
- # index_col='Date' 指定Date列作为索引列
- # parse_dates=True 将Date列中的数据解析为时间类型
- city_day = pd.read_csv('../datas/data_set/city_day.csv', parse_dates=True, index_col='Date')
-
- print(city_day['PM2.5'].astype(str))
- print(city_day['PM2.5'].astype(object))
- import pandas as pd
-
- # 加载印度城市空气质量数据集
- # index_col='Date' 指定Date列作为索引列
- # parse_dates=True 将Date列中的数据解析为时间类型
- city_day = pd.read_csv('../datas/data_set/city_day.csv', parse_dates=True, index_col='Date')
-
- city_day2 = city_day.head(10).copy()
- print(city_day2)
- # 创造包含'missing'为缺失值的数据,批量替换第1、3、5、7、9行中NO列的值为字符串'missing'
- city_day2.loc[::2, 'NO'] = 'missing'
- # 查看数据集
- print(city_day2)
- # 查看NO列的数据类型,返回dtype('O')表示object类型
- print(city_day2['NO'].dtypes)
此时运行下面的代码会报错ValueError: could not convert string to float: 'missing',无法使用astype函数进行类型转换;这个时候我们可以使用to_numeric函数
city_day2['NO'].astype(float)
- import pandas as pd
-
- city_day = pd.read_csv('../datas/data_set/city_day.csv', parse_dates=True, index_col='Date')
-
- city_day2 = city_day.head(10).copy()
- city_day2.loc[::2, 'NO'] = 'missing'
-
- # 使用 to_numeric 函数转换 'NO' 列的值,无法转换的值会变为 NaN
- city_day2['NO'] = pd.to_numeric(city_day2['NO'], errors='coerce')
-
- print(city_day2['NO'].astype(float))
pd.to_numeric函数的参数errors, 它决定了当该函数遇到无法转换的数值时该如何处理
默认情况下,该值为raise,如果to_numeric遇到无法转换的值时,会抛错
coerce: 如果to_numeric遇到无法转换的值时,会返回NaN
ignore: 如果to_numeric遇到无法转换的值时会放弃转换,什么都不做
- import pandas as pd
-
- city_day = pd.read_csv('../datas/data_set/city_day.csv', parse_dates=True, index_col='Date')
- city_day2 = city_day.head(10).copy()
- print(city_day2)
- city_day2.loc[::2, 'NO'] = 'missing'
-
- # 无法转换的值返回NaN
- print(pd.to_numeric(city_day2['NO'], errors='coerce'))
- # 无法转换的值返回原值
- print(pd.to_numeric(city_day2['NO'], errors='ignore'))
比较特殊数据类型,是由固定的且有限数量的变量组成的,比如性别,分为男、女、保密;转换方法可以使用astype函数
category类型的数据中的分类是有顺序的
方式1
- s = pd.Series(
- pd.Categorical(
- ["a", "b", "c", "d"],
- categories=["c", "b", "a"]
- )
- )
- s
- # 输出结果如下
- 0 a
- 1 b
- 2 c
- 3 NaN
- dtype: category
- Categories (3, object): ['c', 'b', 'a']
方式2
- s2 = pd.Series(['B','D','C','A'], dtype='category')
- s2
- # 输出结果如下
- 0 B
- 1 D
- 2 C
- 3 A
- dtype: category
- Categories (4, object): ['A', 'B', 'C', 'D']
- s.astype(str)
- # 输出结果如下
- 0 a
- 1 b
- 2 c
- 3 nan
- dtype: object
python没有原生的datetime数据类型,需要使用datetime包
- from datetime import datetime
-
- now = datetime.now()
- someday = datetime(2020, 1, 1)
-
- print(now)
- print(someday)
读取数据集时,使用参数parse_dates=[列下标]直接将转为datetime类型
- import pandas as pd
-
- df = pd.read_csv('../datas/data_set/city_day.csv', parse_dates=[1])
- print(df['Date'])
- import pandas as pd
-
- # 正常加载数据集
- df = pd.read_csv('../datas/data_set/city_day.csv')
- # 查看Date列数据类型
- print(df['Date'])
- # 将Date列数据转换为时间类型
- df['Date'] = pd.to_datetime(df['Date'])
- print(df['Date'])
由datetime构成的Seriers提取时间日期中的各个部分
- import pandas as pd
-
- # 正常加载数据集
- df = pd.read_csv('../datas/data_set/city_day.csv')
- df['Date'] = pd.to_datetime(df['Date'])
- # 报错
- # 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)
- # 星期,与 df['Date'].dt.weekday+1 相同
- print(df['Date'].dt.dayofweek + 1)
- # 星期
- print(df['Date'].dt.weekday + 1)
由datetime构成的Seriers的其中一个数据提取时间日期中的各个部分
- import pandas as pd
-
- # 正常加载数据集
- df = pd.read_csv('../datas/data_set/city_day.csv')
- df['Date'] = pd.to_datetime(df['Date'])
-
- # d ==> Timestamp('2020-06-20 00:00:00')
- d = pd.to_datetime('2020-06-20')
- print(d)
- print(d.year)
- print(d.month)
- print(d.day)
- print(d.hour)
- print(d.minute)
- print(d.second)
- # 季度
- print(d.quarter)
- # 星期几,与d.dayofweek相同 0是星期一 1是星期二 6是星期日
- print(d.weekday())
- print(d.dayofweek + 1)
datetime类型的日期可以直接进行时间计算:
可以直接使用聚合函数
也可以直接进行时间差运算
- import pandas as pd
-
- # 正常加载数据集
- df = pd.read_csv('../datas/data_set/city_day.csv')
- df['Date'] = pd.to_datetime(df['Date'])
-
- # 直接调用聚合函数
- # 返回 Timestamp('2015-01-01 00:00:00')
- print(df['Date'].min())
- # 直接进行时间差运算
- # 返回时间差类型数据构成的Seriers
- print(df['Date'] - df['Date'].min())
datetime类型数据列作为df索引可以通过具体的时间查询df子集
- import pandas as pd
-
- # 加载数据集,设定时间类型列为索引列
- df = pd.read_csv('../datas/data_set/city_day.csv', index_col='Date', parse_dates=True)
- # 对索引进行重新排序
- # 必要步骤
- df = df.sort_index()
- print(df)
- # 索引排序之后,才能按年取子集df
- print(df.loc['2018-01-01':'2018-12-31'])
- # # 按年月取子集df:所有符合条件的完整行数据
- print(df.loc['2016-06-01':'2016-06-30'])
- # # 按时间范围取子集
- print(df.loc['2015-3-4 22': '2016-1-1 23:45:00'])
python没有原生的timedelta数据类型,需要使用datetime包
- from datetime import datetime
-
- t1 = datetime.now()
- t2 = datetime(2020, 1, 1)
- diff = t1 - t2
- # 时间差类型
- # datetime.timedelta(days=600, seconds=67613, microseconds=847617)
- print(diff)
两个时间Seriers相减即可得到timedelta类型数据构成的Seriers对象
- import pandas as pd
-
- # 加载数据,指定下标为1的列为时间日期类型
- df2 = pd.read_csv('../datas/data_set/city_day.csv', parse_dates=[1])
- # 当前日期减去数据集中最早的日期,即可得到时间差;同时赋值给新的列
- df2['ref_date'] = df2['Date'] - df2['Date'].min()
- # 查看
- print(df2['ref_date'])
timedelta类型转换为字符串类型
- import pandas as pd
-
- # 加载数据,指定下标为1的列为时间日期类型
- df2 = pd.read_csv('../datas/data_set/city_day.csv', parse_dates=[1])
- # 当前日期减去数据集中最早的日期,即可得到时间差;同时赋值给新的列
- df2['ref_date'] = df2['Date'] - df2['Date'].min()
-
- s1 = df2['ref_date'].astype(str)
- print(s1)
字符串类型转换为timedelta类型
- import pandas as pd
-
- # 加载数据,指定下标为1的列为时间日期类型
- df2 = pd.read_csv('../datas/data_set/city_day.csv', parse_dates=[1])
- # 当前日期减去数据集中最早的日期,即可得到时间差;同时赋值给新的列
- df2['ref_date'] = df2['Date'] - df2['Date'].min()
-
- s1 = df2['ref_date'].astype(str)
- print(s1)
-
- s2 = pd.to_timedelta(s1)
- print(s2)
如果将timedelta类型数据作为df索引,就可以基于时间差范围来选择数据
- import pandas as pd
-
- # 读取数据,并将下标为1的Date列设为时间类型列
- df3 = pd.read_csv('../datas/data_set/city_day.csv', parse_dates=[1])
- # 获取印度城市德里的子集
- df4 = df3.query('City=="Delhi"')
- # 将timedelta类型的Series设置为df的索引
- # df4.索引 = Date列 - Date列最早的那一天
- df4.index = df4['Date'] - df4['Date'].min()
- # 查看数据集
- print(df4.head())
- # 基于时间差范围来选择数据
- print(df4['0 days':'4 days'])
| Pandas数据类型 | Python类型 | 说明 |
|---|---|---|
| object | str | 字符串 |
| int64 | int | 整数 |
| float64 | float | 浮点数 |
| bool | bool | 布尔值 |
| 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 --> 特定分类数据类型,比如性别分为男、女、其他 【数据类型】
df['列名'].astype(str)
当Seriers对象使用astype函数转换的结果中数据类型不同时,使用to_numeric函数
pd.to_numeric(df['列名'], errors='coerce')无法转换的值返回NaN
pd.to_numeric(df['列名'], errors='ignore') 无法转换的值返回原值
创建方式s = pd.Series(['B','D','C','A'], dtype='category')
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']
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']