特征预处理在不同的数据下有不同的方法,常见有这么几种:
对于数值型数据:
归一化
标准化
缺失值的处理
对于时间型数据:
时间的切分
对于类别型数据:
One-Hot编码
其中One-Hot编码
在上一章已经讨论过了,我们这里主要讨论其他几种方法。
我们用scikit-learn
和Pandas
进行特征的预处理。
归一化
首先,我们讨论归一化
为什么要做归一化
假设存在如下的数据:
城市
面积(平方千米)
机场数量
火车站数量
上海
6340.5
2
4
南昌
7402
1
2
北京
16410.54
2
5
我们现在想用两点之间的距离公式,来衡量不同城市之间的相似度。显然,城市面积在这里占了非常大的比重,甚至我们只需要比较城市面积即可。
但,假如三个特征同等重要。这时候便需要进行归一化。
即:归一化的目的是避免某个特征对结果造成了更大的影响。
特别注意:不是所有算法都需要对数据进行归一化。概率模型(树形模型)不需要归一化,因为它们不关心变量的值,而是关心变量的分布和变量之间的条件概率,如决策树、随机森林。
我们会有专门的文章讨论决策树和随机森林:
归一化的计算
归一化的定义:通过数学方法把原始数据映射到一定的区间之间,默认[0,1]。
归一化的公式
x ′ = x − m i n m a x − m i n x' = \frac{x - min}{max - min}
x ′ = m a x − m i n x − m i n
x ′ ′ = x ′ ∗ ( m x − m i ) + m i x'' = x' * (mx - mi) + mi
x ′ ′ = x ′ ∗ ( m x − m i ) + m i
其中
m a x max m a x 代表所在列的最大值
m i n min m i n 代表所在列的最小值
m x mx m x 代表指定区间的上限,默认为1
m i mi m i 代表指定区间的下限,默认为0
以上述的数据为例。
上海面积在进行归一化后
x ′ = 6340.5 − 6340.5 16410.54 − 6340.5 = 0 x' = \frac{6340.5 - 6340.5}{16410.54 - 6340.5} = 0
x ′ = 1 6 4 1 0 . 5 4 − 6 3 4 0 . 5 6 3 4 0 . 5 − 6 3 4 0 . 5 = 0
x ′ ′ = 0 ∗ ( 1 − 0 ) + 0 = 0 x'' = 0 * (1 - 0) + 0 = 0
x ′ ′ = 0 ∗ ( 1 − 0 ) + 0 = 0
MinMaxScaler
我们用scikit-learn
工具进行进行归一化。
1 from sklearn.preprocessing import MinMaxScaler
示例代码:
1 2 3 4 from sklearn.preprocessing import MinMaxScalermm = MinMaxScaler() data = [[6340.5 ,2 ,4 ],[7402 ,1 ,2 ],[16410.54 ,2 ,5 ]] print(mm.fit_transform(data))
运行结果:
1 2 3 [[0. 1. 0.66666667] [0.1054117 0. 0. ] [1. 1. 1. ]]
我们也可以把
修改为
1 mm = MinMaxScaler(feature_range=[0,10])
以此来指定区间。
运行结果:
1 2 3 [[ 0. 10. 6.66666667] [ 1.05411696 0. 0. ] [10. 10. 10. ]]
归一化的缺点
假设数据中存在异常点,例如:
城市
面积(平方千米)
机场数量
火车站数量
上海
6340.5
2
4
南昌
7402
1
2
北京
16410.54
2
5
异常
100000000
8
-10000
我们在对数据进行归一化之后,结果如下
1 2 3 4 [[0.00000000e+00 1.42857143e+00 9.99900050e+00] [1.06156731e-04 0.00000000e+00 9.99700150e+00] [1.00706785e-03 1.42857143e+00 1.00000000e+01] [1.00000000e+01 1.00000000e+01 0.00000000e+00]]
这时候,我们看到因为存在一个面积为100000000
的异常
,导致其他城市的面积都非常接近0,显然,面积在这里的作用微乎其微。
同理,因为存在一个火车站数量为-10000
的异常
,导致其他城市的火车站数量也都非常接近1,显然,火车站数量在这里的几乎没有作用。
即,我们得出结论如下:
因为最大值与最小值非常容易受异常点影响,所以归一化的健壮性较差。通常,归一化只适合精确小数据场景。
标准化
为避免归一化缺点所造成的影响,我们引入标准化。
标准化的计算
标准化的定义:通过数学方法把原始数据映射到均值为0,方差为1的范围内。
标准化的公式
x ′ = x − m e a n σ x' = \frac{x - mean}{\sigma}
x ′ = σ x − m e a n
其中
m e a n mean m e a n 代表平均值
σ \sigma σ 代表标准差
方差 = ( x 1 − m e a n ) 2 + ( x 2 − m e a n ) 2 + ⋅ ⋅ ⋅ 样本总数 \text{方差} = \frac{(x_1 - mean)^2 + (x_2 - mean)^2 + ···}{\text{样本总数}}
方差 = 样本总数 ( x 1 − m e a n ) 2 + ( x 2 − m e a n ) 2 + ⋅ ⋅ ⋅
标准差 = 方差 \text{标准差} = \sqrt{\text{方差}}
标准差 = 方差
这里和正态分布标准化公式进行比较。都是减去均值,除以标准差。 若随机变量X X X 的概率密度函数为
p ( x ) = 1 2 π σ e ( x − μ ) 2 2 σ 2 , − ∞ < x < ∞ p(x) = \frac{1}{\sqrt{2\pi}\sigma}e^{\frac{(x-\mu)^2}{2\sigma^2}}, -\infty < x < \infty p ( x ) = 2 π σ 1 e 2 σ 2 ( x − μ ) 2 , − ∞ < x < ∞
则称随机变量X X X 服从均值为μ \mu μ ,标准差为σ \sigma σ 的正态分布,计作X ∼ N ( μ , σ 2 ) X \sim N(\mu,\sigma^2) X ∼ N ( μ , σ 2 ) 。 当μ = 0 \mu=0 μ = 0 ,σ = 1 \sigma=1 σ = 1 时的正态分布N ( 0 , 1 ) N(0,1) N ( 0 , 1 ) 被称为标准正态分布。 正态分布的标准化公式为 若X ∼ N ( μ , σ ) X \sim N(\mu,\sigma) X ∼ N ( μ , σ )
U = X − μ σ U=\frac{X - \mu}{\sigma} U = σ X − μ
则,U ∼ N ( 0 , 1 ) U \sim N(0,1) U ∼ N ( 0 , 1 )
同样,我们以这个数据为例
城市
面积(平方千米)
机场数量
火车站数量
上海
6340.5
2
4
南昌
7402
1
2
北京
16410.54
2
5
上海的飞机场的数量 = 2 − 5 3 ( 2 − 5 3 ) 2 + ( 1 − 5 3 ) 2 + ( 2 − 5 3 ) 2 3 = 2 2 ≈ 0.7071 \text{上海的飞机场的数量} = \frac{2-\frac{5}{3}}{\sqrt{\frac{(2-\frac{5}{3})^2 + (1-\frac{5}{3})^2 + (2-\frac{5}{3})^2}{3}}} = \frac{\sqrt{2}}{2} \approx 0.7071
上海的飞机场的数量 = 3 ( 2 − 3 5 ) 2 + ( 1 − 3 5 ) 2 + ( 2 − 3 5 ) 2 2 − 3 5 = 2 2 ≈ 0 . 7 0 7 1
StandardScaler
我们可以用scikit-learn
工具进行标准化。
1 from sklearn.preprocessing import StandardScaler
示例代码:
1 2 3 4 from sklearn.preprocessing import StandardScalerss = StandardScaler() data = [[6340.5 ,2 ,4 ],[7402 ,1 ,2 ],[16410.54 ,2 ,5 ]] print(ss.fit_transform(data))
运行结果:
1 2 3 [[-0.8213285 0.70710678 0.26726124] [-0.58636365 -1.41421356 -1.33630621] [ 1.40769214 0.70710678 1.06904497]]
示例代码:
1 2 3 4 5 from sklearn.preprocessing import StandardScalerss = StandardScaler() data = [[6340.5 , 2 , 4 ], [7402 , 1 , 2 ], [16410.54 , 2 , 5 ], [100000000 , 8 , -10000 ]] print(ss.fit_transform(data))
运行结果:
1 2 3 4 [[-0.57743597 -0.45083482 0.5774272 ] [-0.57741145 -0.81150267 0.57696549] [-0.57720339 -0.45083482 0.57765806] [ 1.7320508 1.71317231 -1.73205075]]
这看起来,也没有解决问题啊。
因为!要求在大样本。
归一化和标准化的比较
对于归一化,如果出现了异常点,影响了最大值和最小值,会对结果产生显著影响。
对于标准化,在大样本的情况下,少量的异常点不会对平均值产生显著影响,也不会对方差产生显著影响,所以也不会对结果产生的显著影响。
缺失值的处理
缺失值的处理方法
删除,当某行或某列的缺失值到达一定比例的时候,考虑删除整行或整列。
插补,用中位数、平均数或众数来填补缺失值。
实际上,对于缺失值的处理,还很有很多种方法。比如通过kNN进行缺失值的填补。
缺失值的处理工具
我们有两种工具可以处理缺失值。
scikit-learn
pandas
scikit-learn
网上会充斥这大量的这种方法。
1 from sklearn.preprocessing import Imputer
但是,实际上,在scikit-learn 0.22.2
中,已经没有sklearn.preprocessing.Imputer
了。 取而代之的是
1 from sklearn.impute import SimpleImputer
示例代码:
1 2 3 4 5 from sklearn.impute import SimpleImputerimport numpy as npim = SimpleImputer(missing_values=np.nan,strategy='mean' ) data = [[6340.5 ,2 ,4 ],[7402 ,np.nan,2 ],[16410.54 ,2 ,5 ]] print(im.fit_transform(data))
运行结果:
1 2 3 [[6.340500e+03 2.000000e+00 4.000000e+00] [7.402000e+03 2.000000e+00 2.000000e+00] [1.641054e+04 2.000000e+00 5.000000e+00]]
pandas
我们基于pandas.DataFrame
进行缺失值的操作,实际上更多的时候,我们也是用pandas
进行缺失值处理,而不是scikit-learn
。
关于pandas
的更多讨论,我们可以参考《用Python分析数据的方法和技巧:3.pandas》
在这里,我们主要讨论这些方法
DataFrame
isnull
notnull
用布尔索引进行处理
用dropna进行处理
用fillna进行处理
特殊字符的处理
DataFrame
示例代码:
1 2 3 4 5 6 7 import pandas as pdimport numpy as npdf = pd.DataFrame({'city' : ['上海' , '南昌' , '北京' ], 'area' : [6340.5 ,7402 ,16410.54 ], 'airport' : [2 , np.NaN, 2 ], 'station' : [4 ,2 , 5 ]}) print(df)
运行结果:
1 2 3 4 city area airport station 0 上海 6340.50 2.0 4 1 南昌 7402.00 NaN 2 2 北京 16410.54 2.0 5
isnull
示例代码:
运行结果:
1 2 3 4 city area airport station 0 False False False False 1 False False True False 2 False False False False
notnull
示例代码:
运行结果:
1 2 3 4 city area airport station 0 True True True True 1 True True False True 2 True True True True
用布尔索引进行处理
示例代码:
1 print(df[pd.notnull(df['airport' ])])
运行结果:
1 2 3 city area airport station 0 上海 6340.50 2.0 4 2 北京 16410.54 2.0 5
用dropna进行处理
处理DataFrame
示例代码:
1 2 3 print(df.dropna(axis=0 )) print(df.dropna(axis=0 ,how='any' )) print(df.dropna(axis=0 ,how='all' ))
运行结果:
1 2 3 4 5 6 7 8 9 10 city area airport station 0 上海 6340.50 2.0 4 2 北京 16410.54 2.0 5 city area airport station 0 上海 6340.50 2.0 4 2 北京 16410.54 2.0 5 city area airport station 0 上海 6340.50 2.0 4 1 南昌 7402.00 NaN 2 2 北京 16410.54 2.0 5
处理Series对象
示例代码:
1 2 3 se=pd.Series([4 ,None ,8 ,None ,5 ]) print(se) se.dropna()
运行结果:
1 2 3 4 5 6 7 8 9 10 11 0 4.0 1 NaN 2 8.0 3 NaN 4 5.0 dtype: float64 0 4.0 2 8.0 4 5.0 dtype: float64
默认how='any'
默认how='any'
,去除任意列为None的行。
how='any'
,示例代码:
1 2 3 4 df=pd.DataFrame([[1 ,2 ,3 ],[None ,None ,2 ],[None ,None ,None ],[8 ,8 ,None ]]) print(df) df = df.dropna(how='any' ) print(df)
运行结果:
1 2 3 4 5 6 7 0 1 2 0 1.0 2.0 3.0 1 NaN NaN 2.0 2 NaN NaN NaN 3 8.0 8.0 NaN 0 1 2 0 1.0 2.0 3.0
默认how='any'
,示例代码:
1 2 3 4 df=pd.DataFrame([[1 ,2 ,3 ],[None ,None ,2 ],[None ,None ,None ],[8 ,8 ,None ]]) print(df) df = df.dropna() print(df)
运行结果:
1 2 3 4 5 6 7 0 1 2 0 1.0 2.0 3.0 1 NaN NaN 2.0 2 NaN NaN NaN 3 8.0 8.0 NaN 0 1 2 0 1.0 2.0 3.0
how=‘all’
how='all'
,过滤全为NaN的行。
示例代码:
1 2 3 4 df=pd.DataFrame([[1 ,2 ,3 ],[None ,None ,2 ],[None ,None ,None ],[8 ,8 ,None ]]) print(df) df = df.dropna(how='all' ) print(df)
运行结果:
1 2 3 4 5 6 7 8 9 0 1 2 0 1.0 2.0 3.0 1 NaN NaN 2.0 2 NaN NaN NaN 3 8.0 8.0 NaN 0 1 2 0 1.0 2.0 3.0 1 NaN NaN 2.0 3 8.0 8.0 NaN
axis=1
axis=1
,滤除列。
axis=1
,示例代码:
1 2 3 4 df=pd.DataFrame([[1 ,2 ,3 ],[None ,None ,2 ],[None ,None ,None ],[8 ,8 ,None ]]) print(df) df = df.dropna(axis=1 ) print(df)
运行结果:
1 2 3 4 5 6 7 8 0 1 2 0 1.0 2.0 3.0 1 NaN NaN 2.0 2 NaN NaN NaN 3 8.0 8.0 NaN Empty DataFrame Columns: [] Index: [0, 1, 2, 3]
df.dropna(axis=1,how="all")
,示例代码:
1 2 3 4 df=pd.DataFrame([[1 ,2 ,3 ,None ],[None ,None ,2 ,None ],[None ,None ,None ,None ],[8 ,8 ,None ,None ]]) print(df) df = df.dropna(axis=1 ,how="all" ) print(df)
运行结果:
1 2 3 4 5 6 7 8 9 10 0 1 2 3 0 1.0 2.0 3.0 None 1 NaN NaN 2.0 None 2 NaN NaN NaN None 3 8.0 8.0 NaN None 0 1 2 0 1.0 2.0 3.0 1 NaN NaN 2.0 2 NaN NaN NaN 3 8.0 8.0 NaN
subset
subset
,指定列。
示例代码:
1 2 3 4 df=pd.DataFrame([[1 ,2 ,3 ,None ],[None ,None ,2 ,None ],[None ,None ,None ,None ],[8 ,8 ,None ,None ]]) print(df) df = df.dropna(subset=[2 ],how="any" ) print(df)
运行结果:
1 2 3 4 5 6 7 8 0 1 2 3 0 1.0 2.0 3.0 None 1 NaN NaN 2.0 None 2 NaN NaN NaN None 3 8.0 8.0 NaN None 0 1 2 3 0 1.0 2.0 3.0 None 1 NaN NaN 2.0 None
inplace=True
inplace=True
,原地修改。
示例代码:
1 2 3 4 df=pd.DataFrame([[1 ,2 ,3 ,None ],[None ,None ,2 ,None ],[None ,None ,None ,None ],[8 ,8 ,None ,None ]]) print(df) df.dropna(subset=[2 ],how="any" ,inplace=True ) print(df)
运行结果:
1 2 3 4 5 6 7 8 0 1 2 3 0 1.0 2.0 3.0 None 1 NaN NaN 2.0 None 2 NaN NaN NaN None 3 8.0 8.0 NaN None 0 1 2 3 0 1.0 2.0 3.0 None 1 NaN NaN 2.0 None
注意,这时候一定不能用参数去接收。示例代码:
1 2 3 4 df=pd.DataFrame([[1 ,2 ,3 ,None ],[None ,None ,2 ,None ],[None ,None ,None ,None ],[8 ,8 ,None ,None ]]) print(df) df=df.dropna(subset=[2 ],how="any" ,inplace=True ) print(df)
运行结果:
1 2 3 4 5 6 0 1 2 3 0 1.0 2.0 3.0 None 1 NaN NaN 2.0 None 2 NaN NaN NaN None 3 8.0 8.0 NaN None None
用fillna进行处理
快速开始
示例代码:
1 2 3 4 5 print(df.fillna(0 )) print(df.fillna(df.mean())) df['airport' ] = df['airport' ].fillna(df['airport' ].mean()) print(df)
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 city area airport station 0 上海 6340.50 2.0 4 1 南昌 7402.00 0.0 2 2 北京 16410.54 2.0 5 city area airport station 0 上海 6340.50 2.0 4 1 南昌 7402.00 2.0 2 2 北京 16410.54 2.0 5 city area airport station 0 上海 6340.50 2.0 4 1 南昌 7402.00 2.0 2 2 北京 16410.54 2.0 5
参数详解
1 fillna(value=None , method=None , axis=None , inplace=False , limit=None )
value
: 表示填充的值,可以是一个指定值,也可以是字典, Series或DataFrame。
method:
填充的方式,默认为None,有ffill
、pad
、bfill
、bfill
四种填充方式可以使用。
ffill
和pad
表示用缺失值的前一个值填充,如果axis=0
,则用空值上一行的值填充,如果axis=1
,则用空值左边的值填充。假如空值在第一行或第一列,以及空值前面的值全都是空值,则无法获取到可用的填充值,填充后依然保持空值。
bfill
和backfill
表示用缺失值的后一个值填充,axis
的用法以及找不到填充值的情况同ffill
和pad
。
注意!当指定填充方式method
时,不能同时指定填充值value
,否则报错。
axis
: 通常配合method
参数使用,axis=0
表示按行,axis=1
表示按列。
limit
: 表示填充执行的次数。如果是按行填充,则填充一行表示执行一次,按列同理。
填充计算值
填充列的平均值,示例代码:
1 2 3 4 5 6 7 8 df = pd.DataFrame([[np.nan, 2 , np.nan, 0 ], [3 , 4 , np.nan, 1 ], [np.nan, np.nan, np.nan, 5 ], [np.nan, 3 , np.nan, 4 ]], columns=list('ABCD' )) print(df) df = df.fillna(df.mean()) print(df)
运行结果:
1 2 3 4 5 6 7 8 9 10 A B C D 0 NaN 2.0 NaN 0 1 3.0 4.0 NaN 1 2 NaN NaN NaN 5 3 NaN 3.0 NaN 4 A B C D 0 3.0 2.0 NaN 0 1 3.0 4.0 NaN 1 2 3.0 3.0 NaN 5 3 3.0 3.0 NaN 4
和groupby配合使用
假设存在数据如下:
类别
col1
col2
col3
A
NaN
NaN
e
A
d
NaN
NaN
A
NaN
NaN
NaN
A
NaN
c
NaN
B
NaN
Y
NaN
B
NaN
NaN
NaN
B
X
NaN
Z
需要根据类别排序,对缺失值进行填充,如下:
类别
col1
col2
col3
A
d
c
e
A
d
c
e
A
d
c
e
A
d
c
e
B
X
Y
Z
B
X
Y
Z
B
X
Y
Z
分析,有些在前面的行,有些在后面的行。
思路,用groupby
进行分组,分组后填充数据用method='bfill'
先向后填充,再用method='ffill'
向前填充,以此完成所有缺失值位置的填充。
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 df = pd.DataFrame([['A' , None , None , 'e' ], ['A' , 'd' , None , None ], ['A' , None , None , None ], ['A' , None , 'c' , None ], ['B' , None , 'Y' , None ], ['B' , None , None , None ], ['B' , 'X' , None , 'Z' ]], columns=['类别' , 'col1' , 'col2' , 'col3' ]) print(df) df = df.groupby('类别' , group_keys=False ).apply(lambda x: x.fillna(method='bfill' )) df = df.groupby('类别' , group_keys=False ).apply(lambda x: x.fillna(method='ffill' )) print(df)
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 类别 col1 col2 col3 0 A None None e 1 A d None None 2 A None None None 3 A None c None 4 B None Y None 5 B None None None 6 B X None Z 类别 col1 col2 col3 0 A d c e 1 A d c e 2 A d c e 3 A d c e 4 B X Y Z 5 B X Y Z 6 B X Y Z
还可以简写,示例代码:
1 2 3 4 5 6 7 8 9 10 11 df = pd.DataFrame([['A' , None , None , 'e' ], ['A' , 'd' , None , None ], ['A' , None , None , None ], ['A' , None , 'c' , None ], ['B' , None , 'Y' , None ], ['B' , None , None , None ], ['B' , 'X' , None , 'Z' ]], columns=['类别' , 'col1' , 'col2' , 'col3' ]) print(df) df = df.groupby('类别' , group_keys=False ).apply(lambda x: x.fillna(method='bfill' ).fillna(method='ffill' )) print(df)
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 类别 col1 col2 col3 0 A None None e 1 A d None None 2 A None None None 3 A None c None 4 B None Y None 5 B None None None 6 B X None Z 类别 col1 col2 col3 0 A d c e 1 A d c e 2 A d c e 3 A d c e 4 B X Y Z 5 B X Y Z 6 B X Y Z
指定列
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 df_dic = { 'g' : [1 , 1 , 2 , 2 , 1 ], 'a' : [1 , 2 , 11 , None , None ], 'b' : [3 , None , 12 , None , None ], 'c' : [31 , None , 32 , None , None ] } df = pd.DataFrame(df_dic) print(df) df['b' ] = df.groupby('g' , group_keys=False )['b' ].apply(lambda x: x.fillna(method='ffill' )) print(df)
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 g a b c 0 1 1.0 3.0 31.0 1 1 2.0 NaN NaN 2 2 11.0 12.0 32.0 3 2 NaN NaN NaN 4 1 NaN NaN NaN g a b c 0 1 1.0 3.0 31.0 1 1 2.0 3.0 NaN 2 2 11.0 12.0 32.0 3 2 NaN 12.0 NaN 4 1 NaN 3.0 NaN
特殊字符的处理
这里我们以?
为例。演示一个小技巧,即replace
函数。
示例代码:
1 2 3 4 5 6 7 8 9 10 import pandas as pdimport numpy as npdf = pd.DataFrame({'city' : ['上海' , '南昌' , '北京' ], 'area' : [6340.5 ,7402 ,16410.54 ], 'airport' : [2 , '?' , 2 ], 'station' : [4 ,2 , 5 ]}) print(df) print(pd.notnull(df)) df = df.replace('?' ,np.nan) print(df.fillna(df.mean()))
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 city area airport station 0 上海 6340.50 2 4 1 南昌 7402.00 ? 2 2 北京 16410.54 2 5 city area airport station 0 True True True True 1 True True True True 2 True True True True city area airport station 0 上海 6340.50 2.0 4 1 南昌 7402.00 2.0 2 2 北京 16410.54 2.0 5
时间的切分
时间的切分同样基于pandas,举例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import pandas as pddf = pd.DataFrame({'姓名' : ['甲' , '乙' , '丙' ],'交易时间' : [pd.Timestamp('2020-02-02 11:22:33' ),pd.Timestamp('2019-03-03 12:23:34' ),pd.Timestamp('2018-08-08 08:09:10' )]}) print(df) rnt['日期' ] =df['交易时间' ].dt.date rnt['时间' ] =df['交易时间' ].dt.time rnt['年' ] = df['交易时间' ].dt.year rnt['季节' ] = df['交易时间' ].dt.quarter rnt['月' ] = df['交易时间' ].dt.month rnt['周' ]=df['交易时间' ].dt.week rnt['日' ] = df['交易时间' ].dt.day rnt['小时' ] =df['交易时间' ].dt.hour rnt['分钟' ] =df['交易时间' ].dt.minute rnt['秒' ] = df['交易时间' ].dt.second rnt['一年第几天' ] =df['交易时间' ].dt.dayofyear rnt['一年第几周' ] = df['交易时间' ].dt.weekofyear rnt['一周第几天' ] = df['交易时间' ].dt.dayofweek rnt['一个月含有多少天' ] = df['交易时间' ].dt.days_in_month rnt['星期名称' ] =df['交易时间' ].dt.weekday_name print(rnt)
运行结果:
为方便阅读,运行结果以表格的形式展示。
姓名
交易时间
日期
时间
年
季节
月
周
日
小时
分钟
秒
一年第几天
一年第几周
一周第几天
一个月含有多少天
星期名称
0
甲
2020-02-02 11:22:33
2020-02-02
11:22:33
2020
1
2
5
2
11
22
33
33
5
6
29
Sunday
1
乙
2019-03-03 12:23:34
2019-03-03
12:23:34
2019
1
3
9
3
12
23
34
62
9
6
31
Sunday
2
丙
2018-08-08 08:09:10
2018-08-08
08:09:10
2018
3
8
32
8
8
9
10
220
32
2
31
Wednesday
特别注意:在部分新版本的pandas上可能会报错AttributeError: 'DatetimeProperties' object has no attribute 'weekday_name'
。 把倒数第二行的
1 rnt['星期名称'] =df['交易时间'].dt.weekday_name
修改为
1 rnt['星期名称'] =df['交易时间'].dt.day_name()
即可。