Pandas
一、Pandas与Numpy的区别
- Numpy是数值计算的扩展包,能够高效处理N维数组,即处理高维数组或矩阵时会方便。Pandas是python的一个数据分析包,主要是做数据处理用的,以处理二维表格为主。但注意这不是说Numpy就处理不了二维数据,它也可以处理。
- Numpy只能存储相同类型的array,Pandas能处理不同类型的数据,例如二维表格中不同列可以是不同类型的数据,一列为整数一列为字符串。
- Numpy支持并行计算,所以TensorFlow2.0、PyTorch都能和numpy能无缝转换。Numpy底层使用C语言编写,效率远高于纯Python代码。
- Pansdas是基于Numpy的一种工具,该工具是为了解决数据分析任务而创建的。Pandas提供了大量快速便捷地处理数据的函数和方法。
二、DataFrame
-
DataFrame是Pandas 的重要数据结构之一,也是在使用 Pandas 进行数据分析过程中最常用的结构之一,可以这么说,掌握了DataFrame 的用法,你就拥有了学习数据分析的基本能力。
-
DataFrame 是一个表格型的数据结构,既有行标签(index),又有列标签(columns),它也被称异构数据表,所谓异构,指的是表格中每列的数据类型可以不同,比如可以是字符串、整型或者浮点型等。
-
DataFrame的每一列数据都可以看成一个Series结构,只不过,DataFrame 为每列数据值增加了一个列标签。因此 DataFrame 其实是从 Series 的基础上演变而来,并且他们有相同的标签,在数据分析任务中 DataFrame 的应用非常广泛,因为它描述数据的更为清晰、直观。
-
同 Series一样,DataFrame自带行标签索引,默认为"隐式索引"即从 0开始依次递增,行标签与DataFrame 中的数据项一一对应
DataFrame 数据结构的特点的总结:
- DataFrame 每一列的标签值允许使用不同的数据类型;
- DataFrame是表格型的数据结构,具有行和列;
- DataFrame 中的每个数据值都可以被修改。
- DataFrame 结构的行数、列数允许增加或者删除;
- DataFrame 有两个方向的标签轴,分别是行标签和列标签;
- DataFrame 可以对行和列执行算术运算。
1、创建DataFrame
pandas.DataFrame (data=None. index=None,columns=None.dtype=None, copy=None)
参数说明:
- data: 输入的数据,可以是 ndarray,series,list,dict,标量以及一个 DataFrame
- index:行标签,如果没有传递index值,则默认行标签是Rangelndex(0, 1, 2, …, n),n 代表 data的元素个数。
- columns:列标签,如果没有传递columns值,则默认列标签是Rangelndex(0,1,2,…,n)。
- dtype: 要强制的数据类型。只允许使用一种数据类型。如果没有,自行推断
- copy:从输入复制数据。对于dict数据,copy=True,重新复制一份。对于DataFrame或ndarray输入,类似于copy=False,使用的是试图
Pandas DataFrame是一个二维的数组结构,类似二维数组。
# 引入numpy和pandas
import numpy as np
import pandas as pd
(1)使用普通列表创建
data = [1,2,3,4,5]
df = pd.DataFrame(data)
print(df)
# 输出:
0
0 1
1 2
2 3
3 4
4 5
data = [1,2,3,4,5]
df = pd.Series(data)
print(df)
# 输出:
0 1
1 2
2 3
3 4
4 5
dtype: int64
(2)使用嵌套列表创建
# 列表中每个元素代表一行数据
data = [['xiaowang',20],['Lily', 30],['Anne', 40]]
# 未分配列标签
df= pd. DataFrame (data)
print (df)
# 输出:
0 1
0 xiaowang 20
1 Lily 30
2 Anne 40
data = [['xiaowang', 20], ['Lily', 30], ['Anne',40]]
# 分配列标签
df=pd. DataFrame (data, columns=['Name','Age'])
print (df)
# 输出:
Name Age
0 xiaowang 20
1 Lily 30
2 Anne 40
(3)指定数值元素的数据类型为float:
- 需要注意,dtype只能设置一个,设置多个列的数据类型,需要使用其他方式
(4)字典嵌套列表创建
data字典中,键对应的值的元素长度必须相同(也就是列表长度相同)。如果传递了索引,那么索引的长度应该等于数组的长度;如果没有传递索引,那么默认情况下,索引将是Rangelndex(0.1…n),其中n代表数组长度。
(5)列表嵌套字典创建DataFrame对象
列表嵌套字典可以作为数据传递给DataFrame构造函数。默认情况下,字典的键被用作列名
data = [{'a':1,'b':2},{'a':5,'b':10,'c':20}]
df = pd.DataFrame(data, index=['first','second'])
print(df)
# 输出:
a b c
first 1 2 NaN
second 5 10 20.0
注意:如果其中某个元素值缺失,也就是字典的 K e y 无法找到对应的 v a l u e ,将使用 N a N 代替 \textcolor{red}{注意:如果其中某个元素值缺失,也就是字典的Key无法找到对应的value,将使用NaN代替} 注意:如果其中某个元素值缺失,也就是字典的Key无法找到对应的value,将使用NaN代替(NaN是个float型)
(6)Series创建DataFrame对象
DataFrame创建总结:
列表出发: —————表示的一行一行数据
1.列表嵌套列表: 使用默认的列表标签
2.列表嵌套字典: 使用字典的Key作为标签
字典出发:—————表示一列一列数据
1.字典对应值是列表: 行使用默认标签
2.字典对应值是Series: 行和列都是设置的标签,并且还可以指定列的数据类型
2、列操作
DataFrame可以使用列标签来完成数据的选取、添加和删除操作。
(1)选取数据列
- 可以使用列索引,轻松实现数据选取(可以选取多列)
- 列不能使用切片选取多列 \textcolor{red}{列不能使用切片选取多列} 列不能使用切片选取多列
- 没有办法直接通过标签位置(位置索引)去获取列 \textcolor{red}{没有办法直接通过标签位置(位置索引)去获取列} 没有办法直接通过标签位置(位置索引)去获取列
data = {'Name':['关羽','刘备','张飞','曹操'],'Age':[28,34,29,42]}
# 定义行标签
index= ["rank1", "rank2", "rank3", "rank4"]
# 通过字典创建DataFrame
df = pd.DataFrame(data, index=index)
print (df)
# df['Name']:取得Name列——")
print("-----取得Name")
print(df['Name'])
# df['Age']:取得Age列——")
print("-----取得Age")
print(df['Age'])
# 输出
Name Age
rank1 关羽 28
rank2 刘备 34
rank3 张飞 29
rank4 曹操 42
-----取得Name
rank1 关羽
rank2 刘备
rank3 张飞
rank4 曹操
Name: Name, dtype: object
-----取得Age
rank1 28
rank2 34
rank3 29
rank4 42
Name: Age, dtype: int64
(2)列添加
- 使用 columns列索引标签可以实现添加新的数据列
# 使用df['列'] = 值,插入新的数据列
df['three'] = pd.Series([10,20,30],index=['a','b','c'])
# 将已经存在的数据列相加运算,从而创建一个新的列
df['four'] = df['one'] + df['three']
- 还可以使用insert()方法插入新的列
df.insert(loc,column, value, allow_duplicates=False)
- loc:整型,插入索引,必须验证0<=loc<=len(列)
- column:插入列的标签,类型可以是(字符串/数字/散列对象)
- value:数值,Series或者数组
- allow_duplicates:允许重复,可以有相同的列标签数据,默认为False
(3)删除数据列
- 通过del 和 pop() 都能够删除DataFrame中的数据列,pop有返回值
# 使用del删除
del df['one']
# 使用pop方法删除
res_pop = df.pop('one')
3、行操作
(1)标签选取
- 行操作需要借助
loc
属性来完成:按标签或布尔数组访问一组行和列
import pandas as pd
#定义字典
d={'one': pd.Series([1, 2, 3], index=['a','b','c']),
'two': pd.Series([1,2,3,4],index=['a','b','c','d'])}
# 创建DataFrame数据结构
df= pd.DataFrame(d)
print("========df原始数据======")
print (df)
# 确定标签为b的数据
print("========标签为b的数据=====")
print (df.loc['b'])
#输出:
========df原始数据======
one two
a 1.0 1
b 2.0 2
c 3.0 3
d NaN 4
========标签为b的数据=====
one 2.0
two 2.0
Name: b, dtype: float64
注意:loc允许接受两个参数分别为行和列
# b行 one列交叉的数据
df.loc['b','one']
# 输出:
2.0
- 行和列还可以使用切片
# 标签为b的行到标签为d的行,对应标签为one的列
df.loc['b':'d',"one"] # 注意使用行标签切片,包含结束的行
# 输出:
b 2.0
c 3.0
d NaN
Name: one, dtype: float64
# 注意这里和numpy整数数组索引区别
df.loc[['a','b'],["one","two"]]
# 这里两个参数,第一个代表行,第二个代表列
# 输出:
one two
a 1.0 1
b 2.0 2
(2)数值型索引和切片
- 使用数据型索引 需要使用
iloc
属性
直接使用索引,会优先查找的是列标签,如果找不到会报错。列没有位置索引 \textcolor{red}{直接使用索引,会优先查找的是列标签,如果找不到会报错。列没有位置索引} 直接使用索引,会优先查找的是列标签,如果找不到会报错。列没有位置索引
- 可以使用
iloc
:行基于整数位置的按位置选择索引
l o c ————标签 \textcolor{blue}{loc————标签} loc————标签
i l o c ————位置 \textcolor{green}{iloc————位置} iloc————位置
(3)添加数据行
使用append()
函数,可以将新的数据行添加到DataFrame中,该函数会在行末追加数据行
df.append(other, ignore_index=False, verify_integrity=False, sort=False)
将"other"追加到调用者的未尾, 返回一个新对象, "other"行中不在调用者中的列将作为新列添加.
- other: DataFrame或Series/dict类对象, 或这些对象的列表
- ignore_index: 默认为False,如果为True将不适用index 标签
- verify_integrity : 默认为False如果为True, 则在创建具有重复项的索引时引发ValueError
- sort:排序
追加列表
- 如果list是一维的,则以列的形式追加
- 如果list是二维的,则以行的形式追加
- 如果list是三维的,只添加一个值
注意 : \textcolor{red}{注意:} 注意: 使用append可能会出现相同的index,想避免的话,可以使用ignore_index=True
(4)删除数据行
可以使用行索引标签,从DataFrame 中删除某一行数据,如果索引标签存在重复,那么它们将被一起删除。
df.drop()
4、常用属性和方法汇总
名称 | 属性&方法描述 |
---|---|
T | 行和列转置 |
axes | 返回一个仅以行轴标签和列轴标签为成员的列表 |
dtypes | 返回每列数据的数据类型 |
empty | DataFrame中没有数据或者任意坐标轴的长度为0,则返回True |
columns | 返回DataFrame所有列标签 |
shape | 返回一个元组, 获取行数和列数,表示了 DataFrame 维度. |
size | DataFrame中的元素数量. |
values | 使用 numpy 数组表示 DataFrame 中的元素值 |
head() | 返回前 n 行数据 |
tail() | 返回后 n 行数据. |
rename | rename (columns=字典) ,修改列名 |
info() | 可以显示信息, 例如行数/列数,总内存使用量, 每列的数据类型以及不缺少值的元素数 |
sort_index() | 默认根据行标签对所有行排序, 或根据列标签对所有列排序, 或根据指定某列或某几列对行排序 |
sort_values() | 既可以根据列数据, 也可根据行数据排序 |
5、排序
(1)df.sort_index()
sort_index(axis=0, ascending=True, inplace=False)
作用:默认根据行标签对所有行排序,或根据列标签对所有列排序,或根据指定某列或某几列对行排序。
注意:df.sort_index()可以完成和df.sort_values()完全相同的功能,但python更推荐用只用
df.sort_index()对"根据行标签"和"根据列标签"排序,其他排序方式用df.sort_values()。
-
axis: 0按照行名排序;1按照列名排序
-
ascending:默认True升序排列;False降序排列
-
inplace:默认False,否则排序之后的数据直接替换原来的数据
(2) df.sort_values()
DataFrame.sort_values(by, axis=0, ascending=True, inplace=False, kind='quicksort', na_position='last')
作用:既可以根据列数据,也可根据行数据排序。
注意:必须指定by参数,即必须指定哪几行或哪几列;无法根据index名和columns名排序(由.sort_index()执行)
-
by:str or list or str;如果axis = 0,那么by=“列名”;如果axis=1,那么by=“行名”。
-
axis:{0 or ‘index’, 1 or ‘columns’},default 0,默认按照列排序,即纵向排序;如果为1,则是横向排序。
-
ascending:布尔型,True则升序,如果by=[‘列名1’,‘列名2’],则该参数可以是[True,False],即第一字段升序,第二个降序。
-
inplace:布尔型,是否用排序后的数据框替换现有的数据框。
-
na_position: {‘first’, ‘last’}, default ‘last’,默认缺失值排在最后面。
6、分组
(1)Groupby
group = data.groupby("xxxx")
group
输入后,会的得到一个DataFramegroupby对象
(2)agg 聚合操作
可以用来求和、均值、最大值、最小值等
函数 | 用途 |
---|---|
min | 最小值 |
max | 最大值 |
sum | 求和 |
mean | 均值 |
median | 中位数 |
std | 标准差 |
var | 方差 |
count | 计数 |
# 求和
data.groupy("xxxx").sum()
# 也可以data.groupy("xxxx").agg('sum')
三、Pandas读取文件
read_csv() | 用于读取文本文件 |
---|---|
read_excel() | 用于读取文本文件 |
read_json() | 用于读取json文件 |
read_sql_query | 读取sql语句 |
- 通用流程:
1、导入库 import pandas as pd
2、找到文件所在位置(绝对路径 = 全称) (相对路径 = 和程序在同一个文件夹中的路径的简称)
3、变量名 = pd.读写操作方法(文件路径,具体的筛选条件,…)
1、CSV
CSV 又称逗号分隔值文件,是一种简单的文件格式,以特定的结构来排列表格数据。 CSV 文件能够以纯文本形式存储表格数据,比如电表格、数据库文件,并具有数据交换的通用格式。CSV 文件会在 Excel 文件中被打开,其行和列都定义了标准的数据格式。
将CSV 中的数据转换为 DataFrame 对象是非常便捷的。和一般文件读写不一样,它不需要做打开文件、读取文件、关闭文件等操作。相反,只需要一行代码就可以完成上述所有步骤,并将数据存储在 DataFrame 中。
(1)csv导入
# 1、导入pandas
import pandas as pd
# 读取csv文件
df = pd.read_csv('path/to/your/file.csv')
可选参数:
-
filepath_or_buffer:数据输入的路径:可以是文件路径,可以是URL,也可以是实现read方法的任意对象。这个参数,就是输入的第一个参数。
-
sep: 读取csv文件时指定的分隔符,默认为逗号。注意:
csv文件的分隔符
和我们读取csv文件时指定的分隔符
一定要一致 -
header:列头行的索引
-
index_col:作为索引的列
-
usecols:要读取的列
-
dtype:指定数据类型
(2)csv导出
# 1.导入pandas
import pandas as pd
# 2.创建数据
data = {'Name':['Alice','Bob','Charlie'],
'Age':[25,30,22],
'City':['NY','BJ',"SH"]
}
df = pd.DataFrame(data)
# 3.导出到csv文件
df.to_csv('output.csv', index=False)
- 使用pandas的
to_csv
方法将DataFrame导出到csv文件。传递文件路径作为参数。 - 在这个示例中,数据将被导出到名为
output.csv
的csv 文件中。 index=False
参数指示不保存DataFrame的索引列。
2、Excel
(1)Excel导入
# 导入Pandas
import pandas as pd
# 读取Excel
df = pd.read_excel('path/to/your/file.xlsx')
可选参数:
- sheet_name:工作表名称或索引
- header:列头行的索引
- index_col:作为索引的列
- usecols:要读取的列
- dtype:指定数据类型
(2)Excel导出
# 1.入Pandas
import pandas as pd
# 2.数据
data = {'Name':['Alice','Bob','Charlie'],
'Age':[25,30,22],
'City':['NY','BJ',"SH"]
}
df = pd.DataFrame(data)
# 3.导出带Excel文件
df.to_excel('output.xlsx',index=False)
- 使用pandas的
to_excel
方法将DataFrame导出到Excel文件。传递文件路径作为参数。 - 在这个示例中,数据将被导出到名为
output.xlsx
的Excel文件中。 index=False
参数指示不保存DataFrame的索引列。
四、缺失值处理
对于缺失值一般有两种处理方式,要么删除,要么填充(用某个值代替缺失值)。缺失值一般分2种,
- 一种时某一列的数据缺失
- 另一种时整行数据都缺失,即一个空行
1、查看缺失值
df.info()
2、缺失值的判断
df.isnull()
True 表示空,False 表示非空
3、删除缺失值
df.dropna(axis=0, how='any', threshh=None, subset=None, inplace=False)
- axis:{0或’index’,1或’columns’},默认为0 确定是否删除了包含缺失值的行或列
- 0或”索引“:删除包含缺失值的行
- 1或”列“:删除包含缺失值的列
- how:{‘any’,‘all’},默认为’any’确定是否从DataFrame中删除行或列,至少一个NA或所有NA
- “any”:如果存在任何NA值,请删除该行或该列。
- “all”:如果所有值都是NA,则删除该行或列。
- tresh:int需要至少非NA值数据个数。
- subset:定义在哪些列中查找缺少的值
- inplace:是否更改源数据
4、缺失值补充
一般有用0
填充,用平均值
填充,用众数
填充(大多数的时候用这个),
向前
填充(用缺失值的上一行对应字段的值填充,比如D3单元格缺失,那么就用D2单元格的值填充)
向后
填充(与向前填充对应)
df.fillna( value=None, method=None, axis=None, inplace=False, limit=None, downcast=None)
- value:用于填充的值(例如0),或者是一个dict/Series/DataFrame值,指定每个索引(对于一个系列)或列(对于一个数据帧)使用哪个值。不在dict/Series/DataFrame中的值将不会被填充。此值不能是列表。
- method: ffill–>将上一个有效观察值向前传播 bfill->将下一个有效观察值向后传播
- axis:用于填充缺失值的轴。
- inplace:是否操作源数据
- limit :要向前/向后填充的最大连续NaN值数
五、数据合并
merge()函数
pd.merge(left, right, how: str = 'inner', on = None, left_on=None, right_on=None, left_index: bool = False, right_index: bool = False, sort: bool = True, suffixes=('_x','_y'), copy: bool = True, indicator: bool = False, validate=None)
- left/right:两个不同的DataFrame 对象。
- how :要执行的合并类型,从 {‘left’, ‘right’, ‘outer’, ‘inner’)中取值,默认为"inner"内连接。
- on: 指定用于连接的键(即列标签的名字),该键必须同时存在于左右两个 DataFrame 中,如果没有指定,并且其他参数也未指定, 那么将会以两个 DataFrame 的列名交集做为连接键。
- left_on: 指定左侧 DataFrame 中作连接键的列名。该参数在左、右列标签名不相同,但表达的含义相同时非常有用。
- right_on: 指定左侧 DataFrame 中作连接键的列名。
- left_index: 布尔参数,默认为False。如果为 True 则使用左侧 DataFrame 的行索引作为连接键
- right_index 布尔参数,默认为 False。如果为 True 则使用左侧 DataFrame 的行索引作为连接键
- sort 布尔值参数,False,则按照how给定的参数值进行排序。设置为True,它会将合并后的数据进行排序;
- suffixes:字符串组成的元组。当左右DataFrame存在相同列名时,通过该参数可以在相同的列名后附加后缀名,默认为(‘_x,’,'_y)
- copy:默认为True , 表示对数据进行复制。
(1)inner
merge的inner
的类型称为内连接,他在拼接的过程中会取两张表的键(key)的交集进行拼接。
df_1 = pd.DataFrame({
"userid":['a','b','c','d'],
"age":[23,46,32,19]
})
df_1
# 输出
userid age
0 a 23
1 b 46
2 c 32
3 d 19
df_2 = pd.DataFrame({
"userid":['a','c'],
"payment":[2000, 3500]
})
df_2
# 输出:
userid payment
0 a 2000
1 c 3500
df_1.merge(df_2,on='userid')
# 或者df.merge(df_1, df_2, on='userid')
# 输出:
userid age payment
0 a 23 2000
1 c 32 3500
(2)left和right
- left,以左边表格的键为基准进行配对,如果左边表格中的键在右边不存在,则用缺失值填充
- right同理
六、时间
Pandas提供了四种类型的生成日期时间的对象:日期时间、时间增量、时间跨度、日期偏移量
(1) 日期时间(Date Times):具有时区支持的特定日期和时间。与Python标准库中的datetime.datetime类似。如2020年12月6日13点37分50秒;
(2)时间增量(Time Deltas):绝对持续时间,用于在指定时间点基础上增加指定的增量,如在某年月日的基础上增加2天、增加2个月、减少4小时等,最后产生一个新的时间点;
(3)时间跨度(Time Span):由时间点及其相关周期定义的时间跨度,如连续产生一年四个季度的时间序列;
(4) 日期偏移(Date Offsets):以日历计算的相对持续时间,表示时间间隔,两个时间点之间的长度,如日、周、月、季度、年。
1、时间序列类型
(1)时间戳
python datetime的替代品
时间戳相当于python的Datetime,在大多数情况下可以与之互换。
该类型用于组成Datetimelndex的条目,以及pandas中其他面向时间序列的数据结构。
pandas.Timestamp (ts_input=<object object>, freq-None, tz-None, unit=None,year-None, month=None, day=None, hour=None, minute-None, second-None,
microsecond=None, nanosecond=None, tzinfo=None, *, fold=None)
- ts_input:要转换为时间戳的值
- freq:时间戳将具有的偏移量
- unit:用于转换的单位
pd.Timestamp('2023-01-01 12')
# 输出:
Timestamp('2023-01-01 12:00:00')
不能将错误的时间格式放进 T i m e s t a m p \textcolor{red}{不能将错误的时间格式放进Timestamp} 不能将错误的时间格式放进Timestamp
- unit参数为s:
这将转换以秒为单位表示Unix历元的浮点值
pd.Timestamp(time.time(),unit='s')
(2)时间间隔——实现datetime加减
表示持续时间,即两个日期或时间之间的差异
pd.Timedelta( value=<object>, unit=None, **kwargs)
- value:数值,或者Timedelta
- unit:如果输入是整数,则表示输入的单位’M’,'W,‘D’,‘t’,‘S’
ts = pd.Timestamp('2022-01-01 12')
ts
ts + pd.Timedelta(-1,'D')
# 输出:
Timestamp('2021-12-31 12:00:00')
也可以使用关键值赋值
(3)时间转换
to_datetime
转换时间戳
tp_datetime(arg, errors='rasise', dayfirst=False, yearfirst=False, utc=None, format=None, unit=None, infer_datetime_format=False, origin='unix')
函数用户将数组、序列或dict的对象转换为datetime对象
- arg:要转换为日期时间的对象
- errors:错误处理
- if ‘raise’,将引发异常
- if ‘coerce’,无效的转换,使用NaT
- if ‘ignore’,无效的转换,将使用输入的数据
- dayfirst:转换时指定日期分析顺序 (
yearfirst
) - utc:控制与时区相关的解析、本地化和转换(忽略)
- format:用于分析时间的strftime,例如"%d/%m/%Y",自定义格式
- unit:D,s,ms 将时间戳转datatime
- origin:定义参考日期。数值将被解析为自该参考日期起的单位数
1)处理各种输入格式
从一个数据帧的多个列中组装日期时间。
这些键可以是常见的缩写,
如[‘year’,‘month’,‘day’,‘minute’,‘second’,‘ms’,‘us’,‘ns’]
也可以是相同的复数形式
2) 将字符串转datatime
pd.to_datetime(['11/12/2023'])
# 输出:
DatetimeIndex(['2023-11-12'], dtype='datetime64[ns]', freq=None)
3)还可以将unix时间转为时间戳
pd.to_datetime([1349720105, 1349806505, 1349892905], unit='s')
# 输出:
DatetimeIndex(['2012-10-08 18:15:05', '2012-10-09 18:15:05',
'2012-10-10 18:15:05'],
dtype='datetime64[ns]', freq=None)
4)自动识别异常
如 230605
pd.to_datetime('230605')
# 输出:
Timestamp('2005-06-23 00:00:00')
pd.to_datetime('230605',yearfirst=True)
# 输出:
Timestamp('2023-06-05 00:00:00')
5)配合unit参数,使用非unix时间
6)不可转换日期/时间
- 如果日期不符合时间戳限制,则传递errors='ignore’将返回原始输入,而不是引发任何异常
- 除了将非日期(或不可解析的日期)强制传递给NaT之外,传递errors=‘coerce’ 还会将越界日期强制传递给NaT
- if ‘raise’,将引发异常
- if ‘coerce’,无效的转换,使用NaT
- if ‘ignore’,无效的转换,将使用输入的数据