原创

机器学习手册02---数据整理


1.简介

"数据整理"是一个被广泛使用的词,经常用于描述将原始数据转换成整洁的、组织合理的形式以供使用的过程,对于机器学习来说,它仅仅是数据“预处理”中的一个步骤。在整理数据的时候,最常见的数据结构是“数据帧(data frame)”,下面的内容我们将借助另一个常用的库pandas库来帮助我们完成一系列操作。

2.创建一个数据帧

在pandas中有很多方法可以创建一个新的数据帧对象,一个简单的方法是DataFrame创建一个空数据帧并分别定义好每一列:

import pandas as pd

# 创建数据帧
dataframe = pd.DataFrame()

# 增加列
dataframe['name'] = ['John', 'Tom']
dataframe['age'] = [38, 29]
dataframe['Driver'] = [True, False]

# 创建一行
new_person = pd.Series(['Roy', 30, True], index=['name', 'age', 'Driver'])
dataframe = dataframe.append(new_person, ignore_index=True)

print(dataframe)
   name   age  Driver
0  John   38    True
1   Tom   29   False
2   Roy   30    True

3.查看数据帧属性

# 接着上面的代码
# 查看维数
print(dataframe.shape)

#查看描述性统计量
print(dataframe.describe())
(3, 3)

          age
count   3.000000
mean   32.333333
std     4.932883
min    29.000000
25%    29.500000
50%    30.000000
75%    34.000000
max    38.000000

4.浏览数据帧

利用经典数据集:泰坦尼克号,来练习浏览这种大数据集。

import pandas as pd

# 载入准备好的泰坦尼克号数据集
dataframe = pd.read_csv('train.csv')

# 打印第一行
print(dataframe.iloc[0])

# 打印第2、3、4行
print(dataframe.iloc[1:4])

# 打印前2行
print(dataframe.iloc[:2])

PassengerId                          1
Survived                             0
Pclass                               3
Name           Braund, Mr. Owen Harris
Sex                               male
Age                                 22
Name: 0, dtype: object

   PassengerId  Survived  Pclass                          Name     Sex   Age
1            2         1       1    Cumings, Mrs. John Bradley  female  38.0
2            3         1       3        Heikkinen, Miss. Laina  female  26.0
3            4         1       1  Futrelle, Mrs. Jacques Heath  female  35.0

   PassengerId  Survived  Pclass                        Name     Sex   Age
0            1         0       3     Braund, Mr. Owen Harris    male  22.0
1            2         1       1  Cumings, Mrs. John Bradley  female  38.0

【小贴士】:若存在数据集打印不完整,中间出现...的问题,可以利用如下代码设置:

# 核心代码,设置显示的最大列、宽等参数,消掉打印不完全中间的省略号
pd.set_option('display.max_columns', 1000)
pd.set_option('display.width', 1000)
pd.set_option('display.max_colwidth', 1000)

数据帧的索引不必非得是数值型,只要是某一列在数据帧中每一行的值是唯一的,就可以将其设置为索引。举个例子,我们可以将乘客的名字设置为索引,然后通过名字在选择行:

# 将“Name”设置为索引
dataframe = dataframe.set_index(dataframe['Name'])

# 查看Name为Heikkinen, Miss. Laina的行
print(dataframe.loc['Heikkinen, Miss. Laina'])
PassengerId                         3
Survived                            1
Pclass                              3
Name           Heikkinen, Miss. Laina
Sex                            female
Age                                26
Name: Heikkinen, Miss. Laina, dtype: object

为了能选择一行或部分行,pandas提供了两个方法:

(1)loc:当数据帧的索引为一个标签(例如:一个字符串)时,比较常用。

(2)iloc:根据“行号”来查找,不管索引时数值型还是标签。

5.利用条件语句选择行

本质:利用布尔索引来筛选。

# 筛选出Sex值为female的前3名
print(dataframe[dataframe['Sex'] == 'female'].head(3))

# 筛选出Age值大于或等于55岁,且为女性的前3名
print(dataframe[(dataframe['Sex'] == 'female') & (dataframe['Age'] >= 55)].head(3))
PassengerId  Survived  Pclass                          Name     Sex   Age
1            2         1       1    Cumings, Mrs. John Bradley  female  38.0
2            3         1       3        Heikkinen, Miss. Laina  female  26.0
3            4         1       1  Futrelle, Mrs. Jacques Heath  female  35.0

PassengerId  Survived  Pclass                      Name     Sex   Age
11            12         1       1  Bonnell, Miss. Elizabeth  female  58.0
15            16         1       2             Hewlett, Mrs.  female  55.0
195          196         1       1      Lurette, Miss. Elise  female  58.0

6.替换值

# replace():前面[]是原列表中的值,后面[]是即将替换的值
print(dataframe.replace(['female', 'male'], ['women', 'men']).head(4))
PassengerId  Survived  Pclass                          Name    Sex   Age
0            1         0       3       Braund, Mr. Owen Harris    men  22.0
1            2         1       1    Cumings, Mrs. John Bradley  women  38.0
2            3         1       3        Heikkinen, Miss. Laina  women  26.0
3            4         1       1  Futrelle, Mrs. Jacques Heath  women  35.0

【小提示】:replace()可以接受正则表达式。

7.重命名列

rename(): 重命名列,接受字典参数,可以同时改变多个列名。

# 重命名列,并打印前两行
print(dataframe.rename(columns={'Pclass': 'Passenger Class'}).head(2))

print(dataframe.rename(columns={'Pclass': 'Passenger Class', 'Sex': 'Gender'}).head(2))

8.最值、总和、平均值、计数值

print('Max:', dataframe['Age'].max())
print('Min:', dataframe['Age'].min())
print('Mean:', dataframe['Age'].mean())
print('Sum:', dataframe['Age'].sum())
print('Count:', dataframe['Age'].count())    

print('Mode:', dataframe['Age'].mode())      //众数
print('Median:', dataframe['Age'].median())  //中位数
print('Var:', dataframe['Age'].var())        //方差
print('Std:', dataframe['Age'].std())        //标准差
Max: 80.0
Min: 0.42
Mean: 29.69911764705882
Sum: 21205.17
Count: 714

Mode: 0    24.0
dtype: float64
Median: 28.0
Var: 211.01912474630802
Std: 14.526497332334042

9.查找唯一值并统计个数

unique()与nunique()方法

# 查看Sex中的唯一值
print(dataframe['Sex'].unique())

# 统计Sex和Pclass中每个唯一值的个数
print(dataframe['Sex'].value_counts())
print(dataframe['Pclass'].value_counts())

# 统计Pclass中唯一值的个数
print(dataframe['Pclass'].nunique())
['male' 'female']

male      577
female    314
Name: Sex, dtype: int64

3    491
1    216
2    184
Name: Pclass, dtype: int64

3

10.处理缺失值

实际应用当中,大部分数据中都存在缺失值,如果不对缺失值处理,直接进行数据分析,有可能会造成不可估量的影响,所以处理缺失值很重要。最常见的解决方案:isnullnotnull都能返回布尔类型的值,来表示一个值是否有缺失:

# 筛选出缺失值,查看前3行
print(dataframe[dataframe['Age'].isnull()].head(3))
PassengerId  Survived  Pclass                          Name     Sex  Age
5             6         0       3              Moran, Mr. James    male  NaN
17           18         1       2  Williams, Mr. Charles Eugene    male  NaN
19           20         1       3       Masselmani, Mrs. Fatima  female  NaN

在数据整理中,缺失值是很常见的问题,很多人都低估了处理缺失值的难度。Pandas使用Numpy的NaN("Not A Number",意为“不是一个数字”)来表示缺失值,但是Pandas本身并没有实现NaN,如果直接使用,便会得到一条错误信息:

dataframe['Sex'] = dataframe['Sex'].replace('male', NaN)
Traceback (most recent call last):
    dataframe['Sex'] = dataframe['Sex'].replace('male', NaN)
NameError: name 'NaN' is not defined

因此,要想使用NaN,就需要导入NumPy库:

# 导入numpy库,再使用NaN
import numpy as np

print(dataframe.replace('male', np.NaN).head(1))

数据集中还会使用其他特殊值来表示缺失值:NONE、-999或者 . 。

11.删除列

drop():删除列

# 参数axis=1为列
# 删除标签为'Age'的列
print(dataframe.drop('Age', axis=1).head(2))

# 删除标签为'Age'和'Sex'的列
print(dataframe.drop(['Age', 'Sex'], axis=1).head(2))

# 利用columns:通过列的下标来指定列
print(dataframe.drop(dataframe.columns[1], axis=1).head(2))
    PassengerId  Survived  Pclass                        Name     Sex
0            1         0       3     Braund, Mr. Owen Harris    male
1            2         1       1  Cumings, Mrs. John Bradley  female

   PassengerId  Survived  Pclass                        Name
0            1         0       3     Braund, Mr. Owen Harris
1            2         1       1  Cumings, Mrs. John Bradley

   PassengerId  Pclass                        Name     Sex   Age
0            1       3     Braund, Mr. Owen Harris    male  22.0
1            2       1  Cumings, Mrs. John Bradley  female  38.0

还有一种删除方法是del dataframe['Age'], 它是在pandas内部调用方式,不建议使用。

【小提示】:不要使用inplace=True参数,会将数据帧视为可变对象;而在不设置参数时,则默认是为不可变对象,这会为我们省去很多麻烦。

12.删除行

可以利用drop()方法,但是更实用的是利用布尔条件

# 删除:标签Sex为‘male’的行
dataframe = dataframe[dataframe['Sex'] != 'male']

# 删除:标签Name为‘Mr. Owen Harris’的行
dataframe = dataframe[dataframe['Name'] != 'Mr. Owen Harris']

# 删除:行下标为0的行
dataframe = dataframe[dataframe.index != 0]

13.删除“重复”行

drop_duplicates()方法:处理重复行

# 无任何参数的时候,drop_duplicates()只会删除完全一样的行
dataframe = dataframe.drop_duplicates()

# subset参数:选择根据哪个标签判断是否为重复行
dataframe = dataframe.drop_duplicates(subset=['Sex'])
print(dataframe)
# 此使,仅剩下2行数据
PassengerId  Survived  Pclass                        Name     Sex   Age
0            1         0       3     Braund, Mr. Owen Harris    male  22.0
1            2         1       1  Cumings, Mrs. John Bradley  female  38.0

  • 作者:李延松(联系作者)
  • 发表时间:2020-07-19 14:05
  • 版本声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
  • 公众号转载:请在文末添加作者公众号二维码

评论

留言