[Python]-pandas模块-机器学习Python入门《Python机器学习手册》-03-数据整理

《Python机器学习手册——从数据预处理到深度学习》

这本书类似于工具书或者字典,对于python具体代码的调用和使用场景写的很清楚,感觉虽然是工具书,但是对照着做一遍应该可以对机器学习中python常用的这些库有更深入的理解,在应用中也能更为熟练。

以下是根据书上的代码进行实操,注释基本写明了每句代码的作用(写在本句代码之前)和print的输出结果(写在print之后)。不一定严格按照书上内容进行,根据代码运行时具体情况稍作顺序调整,也加入了一些自己的理解。

如果复制到自己的环境下跑一遍输出,相信理解会更深刻更清楚。

博客中每个代码块代表一次完整的运行结果,可以直接以此为单位复制并运行。


03-数据整理

本节主要是pandas库在数据处理时的基本应用。
在加载数据之后,要对数据进行处理,pandas库提供的dataframe数据帧格式,可以很方便地进行数据整理的操作。
包括:

  1. 数据帧浏览与筛选
  2. 数据帧修改与计算
  3. 数据帧分组
  4. 数据帧遍历与函数
  5. 连接多个数据帧

03-1 数据帧浏览与筛选

import pandas as pd

# 创建数据帧
dataframe = pd.DataFrame()  # 表
dataframe['Name'] = ['A', 'B']  # 类似字典,表头作为键值
dataframe['Age'] = [38, 25]
dataframe['Driver'] = [True, False]
print(dataframe)
#   Name  Age  Driver
# 0    A   38    True
# 1    B   25   False

# 在底部添加新的数据行
new_person = pd.Series(['C', 40, True], index = ['Name', 'Age', 'Driver'])
dataframe = dataframe.append(new_person, ignore_index = True)
print(dataframe)
#   Name  Age  Driver
# 0    A   38    True
# 1    B   25   False
# 2    C   40    True

# 查看前两行数据
print(dataframe.head(2))
#   Name  Age  Driver
# 0    A   38    True
# 1    B   25   False

# 查看维数
print(dataframe.shape)
# (3, 3)

# 查看描述性统计量(数值型数据)
print(dataframe.describe())
#             Age
# count   3.000000
# mean   34.333333
# std     8.144528
# min    25.000000
# 25%    31.500000
# 50%    38.000000
# 75%    39.000000
# max    40.000000

# 选择第一行
print(dataframe.iloc[0])
# Name         A
# Age         38
# Driver    True
# Name: 0, dtype: object

# 选择某几行(类似数组的切片,按照行号index查找)
print(dataframe.iloc[1:3])
#   Name  Age  Driver
# 1    B   25   False
# 2    C   40    True

# 根据条件语句筛选行
print(dataframe[dataframe['Driver'] == True])
#   Name  Age  Driver
# 0    A   38    True
# 2    C   40    True

# 多个条件语句筛选
print(dataframe[(dataframe['Driver'] == True) & (dataframe['Age'] < 40)])
#   Name  Age  Driver
# 0    A   38    True

# 设置数据帧的索引(与index区别:将只有唯一值的列作为索引)
print(dataframe) # 注意观察设置索引前后数据帧的变化
#   Name  Age  Driver
# 0    A   38    True
# 1    B   25   False
# 2    C   40    True
dataframe = dataframe.set_index(dataframe['Name'])
print(dataframe) # 注意观察设置索引前后数据帧的变化
#      Name  Age  Driver
# Name                  
# A       A   38    True
# B       B   25   False
# C       C   40    True

# 根据索引查看行
print(dataframe.loc['A'])
# Name         A
# Age         38
# Driver    True
# Name: A, dtype: object

loc和iloc区别:

  • loc:根据index来索引。
  • iloc:根据行号来索引,行号从0开始,逐次加1。

03-2 数据帧修改与计算

包括替换、重命名、计算描述性统计量、查找唯一值、查找缺失值、删除等操作。

import pandas as pd

# ---创建数据帧
dataframe = pd.DataFrame()  # 表
dataframe['Name'] = ['A', 'B']  # 类似字典,表头作为键值
dataframe['Age'] = [38, 25]
dataframe['Sex'] = ['Woman', 'Man']
dataframe['Code'] = ['one', 0]
print(dataframe)
#   Name  Age    Sex Code
# 0    A   38  Woman  one
# 1    B   25    Man    0

# ---替换
# 替换某列的某个值
dataframe['Sex'] = dataframe['Sex'].replace('Woman', 'female')
print(dataframe['Sex'])
# 0    female
# 1       Man
# Name: Sex, dtype: object

# 替换某列的多个值
dataframe['Sex'] = dataframe['Sex'].replace(['Woman', 'Man'], ['female', 'male'])
print(dataframe['Sex'])
# 0    female
# 1      male
# Name: Sex, dtype: object

# 在整个数据帧中进行替换
dataframe = dataframe.replace('one', 1)
print(dataframe)
#   Name  Age    Sex  Code
# 0    A   38  Woman     1
# 1    B   25    Man     0

# ---重命名
# 重命名列,参数是字典,可以同时重命名多个列
dataframe = dataframe.rename(columns = {'Code': 'Num'})
print(dataframe)
#   Name  Age     Sex  Num
# 0    A   38  female    1
# 1    B   25    male    0

# 同时为所有的列重命名,创建一个列名的字典
import collections
column_names = collections.defaultdict(str)
for name in dataframe.columns:
    column_names[name]
print(column_names)
# defaultdict(<class 'str'>, {'Name': '', 'Age': '', 'Sex': '', 'Num': ''})
column_names['Name'] = '姓名'
column_names['Age'] = '年龄'
column_names['Sex'] = '性别'
column_names['Num'] = '代码'
dataframe = dataframe.rename(columns = column_names)
print(dataframe)
#   姓名  年龄      性别  代码
# 0  A  38  female   1
# 1  B  25    male   0

# ---描述性统计量
# 计算常见的描述性统计量
print(dataframe.describe())
#               年龄        代码
# count   2.000000  2.000000
# mean   31.500000  0.500000
# std     9.192388  0.707107
# min    25.000000  0.000000
# 25%    28.250000  0.250000
# 50%    31.500000  0.500000
# 75%    34.750000  0.750000
# max    38.000000  1.000000

# 分别计算最大值、最小值、总和、平均值、计数值
print('MaxNum: ', dataframe['年龄'].max())
print('MinNum: ', dataframe['年龄'].min())
print('Mean: ', dataframe['年龄'].mean())
print('Sum: ', dataframe['年龄'].sum())
print('Count: ', dataframe['年龄'].count())
# MaxNum:  38
# MinNum:  25
# Mean:  31.5
# Sum:  63
# Count:  2

# 也可以对整个数据帧应用这些方法
print(dataframe.count())
# 姓名    2
# 年龄    2
# 性别    2
# 代码    2
# dtype: int64

# 还有其他的一些描述性统计量计算函数
print(dataframe.var()) # 方差
# 年龄    84.5
# 代码     0.5
# dtype: float64
print(dataframe.std()) # 标准差
# 年龄    9.192388
# 代码    0.707107
# dtype: float64
print(dataframe.sem()) # 平均值标准误差
# 年龄    6.5
# 代码    0.5
# dtype: float64
print(dataframe.median()) # 中位数
# 年龄    31.5
# 代码     0.5
# dtype: float64
print(dataframe.mode()) # 众数
# print(dataframe.kurt()) # 峰态
# print(dataframe.skew()) # 偏态

# ---唯一值
# 使用unique来查看由某一列中全部的唯一值组成的数组
# 添加一行
new_person = pd.Series(['C', 40, 'male', 1], index = ['姓名', '年龄', '性别', '代码'])
dataframe = dataframe.append(new_person, ignore_index = True)
print(dataframe)
#   姓名  年龄      性别  代码
# 0  A  38  female   1
# 1  B  25    male   0
# 2  C  40    male   1

# 筛选出唯一值
print(dataframe['性别'].unique())
# ['female' 'male']

# 显示唯一值并计数
print(dataframe['性别'].value_counts())
# male      2
# female    1
# Name: 性别, dtype: int64

# 查看唯一值的个数
print(dataframe['性别'].nunique())
# 2

# ---缺失值
# 查找缺失值
# 添加一行
new_person = pd.Series(['D', 20, 'female'], index = ['姓名', '年龄', '性别'])
dataframe = dataframe.append(new_person, ignore_index = True)
print(dataframe)
#   姓名  年龄      性别   代码
# 0  A  38  female  1.0
# 1  B  25    male  0.0
# 2  C  40    male  1.0
# 3  D  20  female  NaN

# 检查出缺失值
print(dataframe.isnull())
#       姓名     年龄     性别     代码
# 0  False  False  False  False
# 1  False  False  False  False
# 2  False  False  False  False
# 3  False  False  False   True

# 替换缺失值NaN,此方法同样可以用来替换-999\null\''2022-09-16 15:47:50 星期五等缺失值
import numpy as np
dataframe = dataframe.replace(np.nan, 0)
print(dataframe)
#   姓名  年龄      性别   代码
# 0  A  38  female  1.0
# 1  B  25    male  0.0
# 2  C  40    male  1.0
# 3  D  20  female  0.0

# ---删除
# 为了方便多次测试,并没有传回删除后的结果。 传回:dataframe = dataframe.drop()
# 删除一列
print(dataframe.drop('代码', axis = 1))  # axis表示维度,axis = 1 指列,axis = 0 指行
#   姓名  年龄      性别
# 0  A  38  female
# 1  B  25    male
# 2  C  40    male
# 3  D  20  female

# 删除多列
print(dataframe.drop(['年龄', '性别'], axis = 1))
#   姓名   代码
# 0  A  1.0
# 1  B  0.0
# 2  C  1.0
# 3  D  0.0

# 按列下标删除某列(某列可能没有名字)
print(dataframe.drop(dataframe.columns[1], axis = 1))
#   姓名      性别   代码
# 0  A  female  1.0
# 1  B    male  0.0
# 2  C    male  1.0
# 3  D  female  0.0

# 按条件删除某行,类似根据条件语句筛选行
print(dataframe[dataframe['性别'] != 'male'])
#   姓名  年龄      性别   代码
# 0  A  38  female  1.0
# 3  D  20  female  0.0

# 按条件删除某行,查找下标,删除第一行
print(dataframe[dataframe.index != 0])
#   姓名  年龄      性别   代码
# 1  B  25    male  0.0
# 2  C  40    male  1.0
# 3  D  20  female  0.0

# 删除重复的行
print(dataframe.drop_duplicates())  # 只会删除一模一样的两行
#   姓名  年龄      性别   代码
# 0  A  38  female  1.0
# 1  B  25    male  0.0
# 2  C  40    male  1.0
# 3  D  20  female  0.0
print(dataframe.drop_duplicates(subset = ['代码']))  # 默认按照行序,删除'代码'这列重复的行,多个行时加入行名到参数列表即可
#   姓名  年龄      性别   代码
# 0  A  38  female  1.0
# 1  B  25    male  0.0
print(dataframe.drop_duplicates(subset = ['代码'], keep = 'last'))  # 保留最末的行,删除'代码'这列重复的行
#   姓名  年龄      性别   代码
# 2  C  40    male  1.0
# 3  D  20  female  0.0
print(dataframe.duplicated(subset = ['代码']))  # 查看重复情况,类似isnull()
# 0    False
# 1    False
# 2     True
# 3     True
# dtype: bool

03-3 数据帧分组

import pandas as pd

# ---创建数据帧
dataframe = pd.DataFrame()  # 表
dataframe['Name'] = ['A', 'B', 'C', 'D']  # 类似字典,表头作为键值
dataframe['Age'] = [38, 25, 40, 20]
dataframe['Sex'] = ['Woman', 'Man', 'Woman', 'Man']
dataframe['Code'] = [1, 0, 1, 1]
print(dataframe)
#   Name  Age    Sex  Code
# 0    A   38  Woman     1
# 1    B   25    Man     0
# 2    C   40  Woman     1
# 3    D   20    Man     1

# 对行进行分组,然后对每组应用一个函数
print(dataframe.groupby('Sex').mean())
#         Age  Code
# Sex              
# Man    22.5   0.5
# Woman  39.0   1.0
print(dataframe.groupby('Sex')['Code'].sum()) # 先按sex分组,然后对每组的code算总和
# Sex
# Man      1
# Woman    2
# Name: Code, dtype: int64
print(dataframe.groupby(['Sex', 'Code'])['Age'].sum()) # 先按sex分组,再按code分组,然后对每组的age算总和
# Sex    Code
# Man    0       25
#        1       20
# Woman  1       78
# Name: Age, dtype: int64

使用resample按照时间段进行分组

import pandas as pd 
import numpy as np

# 创建日期范围
time_index = pd.date_range('09/15/2022', periods = 100000, freq = '30s') # 参数分别为:起始时间、总数、间隔时间
print(time_index, len(time_index))
# DatetimeIndex(['2022-09-15 00:00:00', '2022-09-15 00:00:30',
#                '2022-09-15 00:01:00', '2022-09-15 00:01:30',
#                '2022-09-15 00:02:00', '2022-09-15 00:02:30',
#                '2022-09-15 00:03:00', '2022-09-15 00:03:30',
#                '2022-09-15 00:04:00', '2022-09-15 00:04:30',
#                ...
#                '2022-10-19 17:15:00', '2022-10-19 17:15:30',
#                '2022-10-19 17:16:00', '2022-10-19 17:16:30',
#                '2022-10-19 17:17:00', '2022-10-19 17:17:30',
#                '2022-10-19 17:18:00', '2022-10-19 17:18:30',
#                '2022-10-19 17:19:00', '2022-10-19 17:19:30'],
#               dtype='datetime64[ns]', length=100000, freq='30S') 100000

# 创建数据帧
dataframe = pd.DataFrame(index = time_index)  # 默认行号0-n变为时间time_index中的内容
dataframe['Sale_Amount'] = np.random.randint(1, 10, 100000) # 随机生成1-10中的整数
print(dataframe.head(5))
#                      Sale_Amount
# 2022-09-15 00:00:00            2
# 2022-09-15 00:00:30            8
# 2022-09-15 00:01:00            7
# 2022-09-15 00:01:30            4
# 2022-09-15 00:02:00            8

# 按周对行分组,计算每一周的总和
print(dataframe.resample('W').sum())
#             Sale_Amount
# 2022-09-18        57265
# 2022-09-25       101364
# 2022-10-02       100891
# 2022-10-09       100686
# 2022-10-16       101337
# 2022-10-23        39322
print(dataframe.resample('2W').sum())
#             Sale_Amount
# 2022-09-18        57562
# 2022-10-02       201239
# 2022-10-16       201288
# 2022-10-30        38938
print(dataframe.resample('M').sum())
#             Sale_Amount
# 2022-09-30       230240
# 2022-10-31       268787
# 默认情况resample返回的日期索引是时间组右边界的值,加入label参数,改成返回左边界
print(dataframe.resample('M', label = 'left').sum())
#             Sale_Amount
# 2022-08-31       229518
# 2022-09-30       269099

03-4 数据帧遍历与函数

import pandas as pd

# ---创建数据帧
dataframe = pd.DataFrame()  # 表
dataframe['Name'] = ['a', 'b', 'c', 'd']  # 类似字典,表头作为键值
dataframe['Age'] = [38, 25, 40, 20]
dataframe['Sex'] = ['Woman', 'Man', 'Woman', 'Man']
dataframe['Code'] = [1, 0, 1, 1]
print(dataframe)
#   Name  Age    Sex  Code
# 0    a   38  Woman     1
# 1    b   25    Man     0
# 2    c   40  Woman     1
# 3    d   20    Man     1

# 遍历某列
for name in dataframe['Name']:
    print(name.upper())
# A
# B
# C
# D

# 对某列的所有元素应用某个函数
def uppercase(X):
    return  X.upper()

print(dataframe['Name'].apply(uppercase))
# 0    A
# 1    B
# 2    C
# 3    D
# Name: Name, dtype: object

# 对所有分组应用一个函数
print(dataframe.groupby('Sex').apply(lambda x: x.count()))
#        Name  Age  Sex  Code
# Sex                        
# Man       2    2    2     2
# Woman     2    2    2     2

03-5 连接多个数据帧

import pandas as pd

# ---创建数据帧
data_a = {'id': ['1', '2', '3'],
          'first': ['Alex', 'Amy', 'Allen'],
          'last': ['Anderson', 'Axkerman', 'Ali']}
dataframe_a = pd.DataFrame(data_a, columns = ['id', 'first', 'last'])
print(dataframe_a)
#   id  first      last
# 0  1   Alex  Anderson
# 1  2    Amy  Axkerman
# 2  3  Allen       Ali

data_b = {'id': ['4', '5', '6'],
          'first': ['Billy', 'Brian', 'Bran'],
          'last': ['Bonder', 'Black', 'Balwner']}
dataframe_b = pd.DataFrame(data_b, columns = ['id', 'first', 'last'])
print(dataframe_b)
#   id  first     last
# 0  4  Billy   Bonder
# 1  5  Brian    Black
# 2  6   Bran  Balwner

# 沿着行的方向连接两个数据帧
print(pd.concat([dataframe_a, dataframe_b], axis = 0))
#   id  first      last
# 0  1   Alex  Anderson
# 1  2    Amy  Axkerman
# 2  3  Allen       Ali
# 0  4  Billy    Bonder
# 1  5  Brian     Black
# 2  6   Bran   Balwner

# 沿着列的方向连接两个数据帧
print(pd.concat([dataframe_a, dataframe_b], axis = 1))
#   id  first      last id  first     last
# 0  1   Alex  Anderson  4  Billy   Bonder
# 1  2    Amy  Axkerman  5  Brian    Black
# 2  3  Allen       Ali  6   Bran  Balwner
posted @ 2022-09-14 22:56  CAMILIA  阅读(46)  评论(0编辑  收藏  举报