Pandas 数据清洗详解

Pandas 数据清洗详解

数据清洗概述

数据清洗是数据分析过程中至关重要的步骤,主要包括处理缺失值、异常值、重复数据、格式转换等。下面通过具体案例演示常见的数据清洗操作。

一、处理缺失值

Excel(data.xlsx)示例数据:

1、查看缺失值情况

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')

print("缺失值统计:")
print(df_data.isnull().sum())

输出:

python 复制代码
缺失值统计:
员工ID    0
姓名      1
年龄      1
部门      1
工资      1
入职日期    1
dtype: int64

2、删除缺失值

2.1 删除所有包含缺失值的行

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')

df_data_all = df_data.dropna()
print("删除所有含缺失值的行:")
print(df_data_all)

输出:

python 复制代码
删除所有含缺失值的行:
   员工ID  姓名    年龄   部门      工资     入职日期
0     1  张三  28.0  技术部  8000.0  43845.0

2.2 只删除"姓名"列缺失的行

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')

df1_drop_name = df_data.dropna(subset=['姓名'])
print("只删除'姓名'列缺失的行:")
print(df1_drop_name)

输出:

python 复制代码
只删除'姓名'列缺失的行:
   员工ID  姓名    年龄   部门      工资     入职日期
0     1  张三  28.0  技术部  8000.0  43845.0
1     2  李四   NaN  市场部  7500.0  43544.0
2     3  王五  35.0  NaN  9000.0  43291.0
4     5  赵六  29.0  技术部  8200.0      NaN

3、填充缺失值

3.1 用指定值填充

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')

df1_fill = df_data.copy()

# 方法一:直接赋值
df1_fill['部门'] = df1_fill['部门'].fillna('未知部门')  # 缺失的部门使用"未知部门"填充
df1_fill['年龄'] = df1_fill['年龄'].fillna(df1_fill['年龄'].mean())  # 用平均值填充年龄

# 方法二:使用 loc 进行明确赋值
# df1_fill.loc[:, '部门'] = df1_fill['部门'].fillna('未知部门')
# df1_fill.loc[:, '年龄'] = df1_fill['年龄'].fillna(df1_fill['年龄'].mean())

# 方法三:批量更新多个列
# df1_fill.update(df1_fill['部门'].fillna('未知部门'))
# df1_fill.update(df1_fill['年龄'].fillna(df1_fill['年龄'].mean()))

# 方法四:一次填充多个列
#df1_fill = df1_fill.fillna({
#    '部门': '未知部门',
#    '年龄': df1_fill['年龄'].mean()
#})

print("填充后的数据:")
print(df1_fill)

输出:

python 复制代码
填充后的数据:
   员工ID   姓名    年龄    部门      工资     入职日期
0     1   张三  28.0   技术部  8000.0  43845.0
1     2   李四  31.0   市场部  7500.0  43544.0
2     3   王五  35.0  未知部门  9000.0  43291.0
3     4  NaN  32.0   财务部     NaN  44328.0
4     5   赵六  29.0   技术部  8200.0      NaN

3.2 向前或向后填充

向前填充(ffill) 是指用缺失值前面的最近一个非缺失值来填充当前缺失值。
向后填充(bfill) 是指用缺失值后面的最近一个非缺失值来填充当前缺失值。

例如,要填充"工资"列的缺失值,如果是向前填充,则填充"9000",向后填充则是"8200"。

向前填充:

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')


df1_ffill = df_data.copy()
# 对工资列进行向前填充
df1_ffill['工资'] = df1_ffill['工资'].ffill()  # 用前一个值填充
print("向前填充工资列:")
print(df1_ffill)

输出:

python 复制代码
向前填充工资列:
   员工ID   姓名    年龄   部门      工资     入职日期
0     1   张三  28.0  技术部  8000.0  43845.0
1     2   李四   NaN  市场部  7500.0  43544.0
2     3   王五  35.0  NaN  9000.0  43291.0
3     4  NaN  32.0  财务部  9000.0  44328.0
4     5   赵六  29.0  技术部  8200.0      NaN

向后填充:

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')


df1_bfill = df_data.copy()
# 对工资列进行向前填充
df1_bfill['工资'] = df1_bfill['工资'].bfill()  # 用前一个值填充
print("向前填充工资列:")
print(df1_bfill)

输出:

python 复制代码
向前填充工资列:
   员工ID   姓名    年龄   部门      工资     入职日期
0     1   张三  28.0  技术部  8000.0  43845.0
1     2   李四   NaN  市场部  7500.0  43544.0
2     3   王五  35.0  NaN  9000.0  43291.0
3     4  NaN  32.0  财务部  8200.0  44328.0
4     5   赵六  29.0  技术部  8200.0      NaN

二、处理重复值

Excel(data.xlsx)示例数据:

1、检查重复数据

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')

print("重复行统计:", df_data.duplicated().sum())
print("重复行详情:")
print(df_data[df_data.duplicated()])

输出:

python 复制代码
重复行统计: 2
重复行详情:
    订单号 客户名称   产品  数量    金额
2  A001  客户A  产品A  10  1000
4  A002  客户B  产品B   5   500

2、删除完全重复的行

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')

df2 = df_data.copy()
df2_dedup = df2.drop_duplicates()
print("删除完全重复行后:")
print(df2_dedup)

输出:

python 复制代码
删除完全重复行后:
    订单号 客户名称   产品  数量    金额
0  A001  客户A  产品A  10  1000
1  A002  客户B  产品B   5   500
3  A003  客户C  产品C   8   800
5  A004  客户A  产品D  12  1200

3、根据指定列删除重复行

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')

df2 = df_data.copy()
df2_dedup_order = df2.drop_duplicates(subset=['订单号'])
print("根据'订单号'删除重复行:")
print(df2_dedup_order)

输出:

python 复制代码
根据'订单号'删除重复行:
    订单号 客户名称   产品  数量    金额
0  A001  客户A  产品A  10  1000
1  A002  客户B  产品B   5   500
3  A003  客户C  产品C   8   800
5  A004  客户A  产品D  12  1200

4、保留重复行中的第一条或最后一条

保留重复行中的最后一条

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')

df2 = df_data.copy()

df2_keep_last = df2.drop_duplicates(subset=['订单号'], keep='last')
# 保留'订单号'重复的第一条记录
# df2_keep_last = df2.drop_duplicates(subset=['订单号'], keep='first') 
print("保留'订单号'重复的最后一条记录:")
print(df2_keep_last)

输出:

python 复制代码
保留'订单号'重复的最后一条记录:
    订单号 客户名称   产品  数量    金额
2  A001  客户A  产品A  10  1000
3  A003  客户C  产品C   8   800
4  A002  客户B  产品B   5   500
5  A004  客户A  产品D  12  1200

三、数据类型转换

Excel(data.xlsx)示例数据:

1、日期格式转换

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')

df3 = df_data.copy()

df3['日期'] = pd.to_datetime(df3['日期'], errors='coerce') # errors='coerce',将错误解析的转换为 NaT (Not a Time)
print("日期转换后:")
print(df3['日期'])

输出:

python 复制代码
日期转换后:
0   2023-01-15
1   2023-02-20
2   2023-03-10
3   2023-04-05
4   2023-05-18
Name: 日期, dtype: datetime64[ns]

2、数值类型转换

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')

df3 = df_data.copy()

# 将 '价格' 和 '数量' 列的数据转换为数值类型(int64或float64)
df3['价格'] = pd.to_numeric(df3['价格'], errors='coerce')
df3['数量'] = pd.to_numeric(df3['数量'], errors='coerce')
print("数值转换后数据类型:")
print(df3.dtypes)

输出:

python 复制代码
数值转换后数据类型:
ID               int64
日期      datetime64[ns]
价格             float64
数量               int64
是否有效            object
dtype: object

3、布尔值转换

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')

df3 = df_data.copy()

df3['是否有效'] = df3['是否有效'].map({'是': True, '否': False})
print("布尔值转换后:")
print(df3)

输出:

python 复制代码
布尔值转换后:
   ID         日期     价格  数量   是否有效
0   1 2023-01-15  12.50  10   True
1   2 2023-02-20   8.75   5  False
2   3 2023-03-10  15.00   8   True
3   4 2023-04-05   9.99  12   True
4   5 2023-05-18  20.00   3  False

4、使用astype转换

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')

df3 = df_data.copy()

df3['ID'] = df3['ID'].astype('int32')
print("使用astype转换ID列类型:")
print(df3.dtypes)

输出:

python 复制代码
使用astype转换ID列类型:
ID               int32
日期      datetime64[ns]
价格             float64
数量               int64
是否有效            object
dtype: object

四、字符串处理

Excel(data.xlsx)示例数据:

1、字符串大小写转换

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')

df4 = df_data.copy()

df4['产品编号'] = df4['产品编号'].str.upper()
df4['产品名称'] = df4['产品名称'].str.lower()
print("大小写转换后:")
print(df4[['产品编号', '产品名称']])

输出:

python 复制代码
大小写转换后:
    产品编号       产品名称
0  P-001       苹果手机
1  P-002      华为笔记本
2  P-003  samsung电视
3  P-004       小米手环
4  P-005      戴尔显示器

2、去除空格

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')

df4 = df_data.copy()

df4['规格'] = df4['规格'].str.strip()
print("去除空格后:")
print(df4['规格'])

输出:

python 复制代码
去除空格后:
0       128GB
1    16G/512G
2         55寸
3         标准版
4        27英寸
Name: 规格, dtype: object

3、字符串替换

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')

df4 = df_data.copy()

df4['产品名称'] = df4['产品名称'].str.replace('手机', '智能手机')
print("字符串替换后:")
print(df4['产品名称'])

输出:

python 复制代码
字符串替换后:
0       苹果智能手机
1        华为笔记本
2    SAMSUNG电视
3         小米手环
4        戴尔显示器
Name: 产品名称, dtype: object

4、字符串分割

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')

df4 = df_data.copy()

df4['产地_主要'] = df4['产地'].str.split(',').str[0]
print("字符串分割后:")
print(df4[['产地', '产地_主要']])

输出:

python 复制代码
字符串分割后:
      产地 产地_主要
0     中国    中国
1  中国,深圳    中国
2     韩国    韩国
3  中国,北京    中国
4     美国    美国

5、字符串提取

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')

df4 = df_data.copy()

df4['规格_数字'] = df4['规格'].str.extract(r'(\d+)')
print("提取数字后:")
print(df4[['规格', '规格_数字']])

输出:

python 复制代码
提取数字后:
         规格 规格_数字
0     128GB   128
1  16G/512G    16
2       55寸    55
3       标准版   NaN
4      27英寸    27

6、字符串包含检查

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')

df4 = df_data.copy()

df4['是否国产'] = df4['产地'].str.contains('中国')
print("是否国产检查:")
print(df4[['产地', '是否国产']])

输出:

python 复制代码
是否国产检查:
      产地   是否国产
0     中国   True
1  中国,深圳   True
2     韩国  False
3  中国,北京   True
4     美国  False

五、处理异常值

Excel(data.xlsx)示例数据:

1、描述性统计

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')

df5 = df_data.copy()

print("描述性统计:")
print(df5.describe())

输出:

python 复制代码
描述性统计:
             语文成绩       数学成绩        英语成绩          年龄
count    7.000000   7.000000    7.000000    7.000000
mean    87.857143  74.571429   86.571429   42.000000
std     17.082433  36.156406   12.272695   69.675438
min     65.000000  -5.000000   68.000000   15.000000
25%     80.000000  77.000000   79.000000   15.000000
50%     88.000000  88.000000   88.000000   16.000000
75%     91.000000  93.500000   93.500000   16.500000
max    120.000000  98.000000  105.000000  200.000000

2、使用分位数识别异常值

IQR(Interquartile Range)是统计学中检测异常值的常用方法:
Q1(第一四分位数):数据的25%分位点
Q3(第三四分位数):数据的75%分位点
IQR(四分位距):Q3 - Q1,表示中间50%数据的范围

异常值边界计算

下限:Q1 - 1.5 × IQR

上限:Q3 + 1.5 × IQR

任何低于下限或高于上限的值通常被视为异常值。

python 复制代码
import pandas as pd

# 读取数据
df_data = pd.read_excel('data.xlsx')

# 创建副本,避免修改原始数据
df5 = df_data.copy()

# 1. 计算Q1(第一四分位数)
Q1 = df5[['语文成绩', '数学成绩', '英语成绩']].quantile(0.25)
# 结果:每个科目25%分位点的值

# 2. 计算Q3(第三四分位数)
Q3 = df5[['语文成绩', '数学成绩', '英语成绩']].quantile(0.75)
# 结果:每个科目75%分位点的值

# 3. 计算IQR(四分位距)
IQR = Q3 - Q1
# 结果:每个科目中间50%数据的范围

# 4. 计算异常值边界
lower_bound = Q1 - 1.5 * IQR  # 下边界
upper_bound = Q3 + 1.5 * IQR  # 上边界

# 5. 打印结果
print("异常值边界:")
print("语文成绩:", (lower_bound['语文成绩'], upper_bound['语文成绩']))
print("数学成绩:", (lower_bound['数学成绩'], upper_bound['数学成绩']))
print("英语成绩:", (lower_bound['英语成绩'], upper_bound['英语成绩']))

输出:

python 复制代码
异常值边界:
语文成绩: (np.float64(63.5), np.float64(107.5))
数学成绩: (np.float64(52.25), np.float64(118.25))
英语成绩: (np.float64(57.25), np.float64(115.25))

3、标记异常值

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')

df5 = df_data.copy()

Q1 = df5[['语文成绩', '数学成绩', '英语成绩']].quantile(0.25)
Q3 = df5[['语文成绩', '数学成绩', '英语成绩']].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR

df5['语文异常'] = (df5['语文成绩'] < lower_bound['语文成绩']) | (df5['语文成绩'] > upper_bound['语文成绩'])
df5['数学异常'] = (df5['数学成绩'] < lower_bound['数学成绩']) | (df5['数学成绩'] > upper_bound['数学成绩'])
df5['英语异常'] = (df5['英语成绩'] < lower_bound['英语成绩']) | (df5['英语成绩'] > upper_bound['英语成绩'])
df5['年龄异常'] = (df5['年龄'] < 10) | (df5['年龄'] > 30)

print("异常值标记:")
print(df5[['学生ID', '姓名', '语文异常', '数学异常', '英语异常', '年龄异常']])

输出:

python 复制代码
异常值标记:
   学生ID  姓名   语文异常   数学异常   英语异常   年龄异常
0  S001  张三  False  False  False  False
1  S002  李四  False  False  False  False
2  S003  王五  False  False  False  False
3  S004  赵六   True  False  False  False
4  S005  钱七  False   True  False  False
5  S006  孙八  False  False  False   True
6  S007  周九  False  False  False  False

4、处理异常值

替换超出边界的成绩 - 替换为边界值

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')

df5 = df_data.copy()

Q1 = df5[['语文成绩', '数学成绩', '英语成绩']].quantile(0.25)
Q3 = df5[['语文成绩', '数学成绩', '英语成绩']].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR

for col in ['语文成绩', '数学成绩', '英语成绩']:
    lower = lower_bound[col]
    upper = upper_bound[col]
    df5[col] = df5[col].clip(lower, upper)
print(df5)

输出:

python 复制代码
   学生ID  姓名   语文成绩   数学成绩  英语成绩   年龄      Unnamed: 6
0  S001  张三   85.0  92.00    78   15             NaN
1  S002  李四   90.0  88.00    95   16             NaN
2  S003  王五   75.0  82.00    80   15             NaN
3  S004  赵六  107.5  95.00    88   17  # 异常:语文成绩超过100
4  S005  钱七   88.0  52.25    92   16     # 异常:数学成绩负数
5  S006  孙八   92.0  98.00   105  200      # 异常:年龄不合理
6  S007  周九   65.0  72.00    68   15             NaN

替换不合理的年龄 - 替换为平均值

python 复制代码
import pandas as pd
import numpy as np

df_data = pd.read_excel('data.xlsx')
df5 = df_data.copy()

# 计算30岁及以下学生的平均年龄
age_mean = df5[df5['年龄'] <= 30]['年龄'].mean()

# 四舍五入为整数(或者使用 np.round, np.floor, np.ceil 等)
age_mean_int = int(round(age_mean))

# 将30岁以上学生的年龄替换为整数平均值
df5.loc[df5['年龄'] > 30, '年龄'] = age_mean_int

print("处理异常值后:")
print(df5[['学生ID', '姓名', '语文成绩', '数学成绩', '英语成绩', '年龄']])

输出:

python 复制代码
处理异常值后:
   学生ID  姓名  语文成绩  数学成绩  英语成绩  年龄
0  S001  张三    85    92    78  15
1  S002  李四    90    88    95  16
2  S003  王五    75    82    80  15
3  S004  赵六   120    95    88  17
4  S005  钱七    88    -5    92  16
5  S006  孙八    92    98   105  16
6  S007  周九    65    72    68  15

5、删除异常值

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')
df5 = df_data.copy()

print("删除年龄异常前:")
print(df5[['学生ID', '姓名', '语文成绩', '数学成绩', '英语成绩', '年龄']])

# 基于原始年龄删除异常
# 1. 先创建副本
df5_drop = df5.copy()

# 2. 添加原始年龄列
df5_drop['原始年龄'] = df5['年龄'].copy()

# 3. 筛选原始年龄≤30的行
df5_drop = df5_drop[df5_drop['原始年龄'] <= 30]

# 4. 删除临时列
df5_drop = df5_drop.drop('原始年龄', axis=1)

print("\n删除年龄异常后:")
print(df5_drop[['学生ID', '姓名', '语文成绩', '数学成绩', '英语成绩', '年龄']])

输出:

python 复制代码
删除年龄异常前:
   学生ID  姓名  语文成绩  数学成绩  英语成绩   年龄
0  S001  张三    85    92    78   15
1  S002  李四    90    88    95   16
2  S003  王五    75    82    80   15
3  S004  赵六   120    95    88   17
4  S005  钱七    88    -5    92   16
5  S006  孙八    92    98   105  200
6  S007  周九    65    72    68   15

删除年龄异常后:
   学生ID  姓名  语文成绩  数学成绩  英语成绩  年龄
0  S001  张三    85    92    78  15
1  S002  李四    90    88    95  16
2  S003  王五    75    82    80  15
3  S004  赵六   120    95    88  17
4  S005  钱七    88    -5    92  16
6  S007  周九    65    72    68  15

六、数据规范化与标准化

Excel(data.xlsx)示例数据:

1、最小-最大规范化

最小-最大规范化(Min-Max Normalization),也称为离差标准化或线性函数归一化,是一种常用的数据标准化方法。它的核心思想是 将原始数据线性变换到指定的范围内(通常是[0, 1]区间)。

最小-最大规范化的目的:

  • 将不同量纲、不同范围的数据转换到统一的范围
  • 消除数据尺度差异,使数据具有可比性

对于将数据规范到 [0, 1] 区间:
x n o r n = x − x m i n x m a x − x m i n x_{\mathrm{norn}}={\frac{x-x_{\mathrm{min}}}{x_{\mathrm{max}}-x_{\mathrm{min}}}} xnorn=xmax−xminx−xmin

对于将数据规范到 [a, b] 区间:
x n o r m = a + ( x − x min ⁡ ) × ( b − a ) x max ⁡ − x min ⁡ x_{\mathrm{norm}}=a+{\frac{(x-x_{\operatorname*{min}})\times(b-a)}{x_{\operatorname*{max}}-x_{\operatorname*{min}}}} xnorm=a+xmax−xmin(x−xmin)×(b−a)

python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')

df6_minmax = df_data.copy()
numeric_cols = ['GDP(亿元)', '人口(万人)', '面积(平方公里)']

for col in numeric_cols:
    min_val = df6_minmax[col].min()
    max_val = df6_minmax[col].max()
    df6_minmax[f'{col}_minmax'] = (df6_minmax[col] - min_val) / (max_val - min_val)

print("最小-最大规范化后:")
# 输出城市列和所有规范化后的列
output_cols = ['城市'] + [f'{col}_minmax' for col in numeric_cols]
print(df6_minmax[output_cols])

输出:

python 复制代码
最小-最大规范化后:
   城市  GDP(亿元)_minmax  人口(万人)_minmax  面积(平方公里)_minmax
0  北京        0.880894        0.646235             0.568273
1  上海        1.000000        1.000000             0.282303
2  广州        0.369314        0.150532             0.382652
3  深圳        0.491679        0.000000             0.000000
4  成都        0.000000        0.497755             1.000000

结果解读:

最小-最大规范化(Min-Max Normalization) 将原始数据线性转换到[0,1]区间:

  • 0 表示该城市在该指标上处于最小值位置
  • 1 表示该城市在该指标上处于最大值位置

GDP(亿元)指标:

  • 上海(1.0)GDP最高
    成都(0.0)GDP最低
    北京(0.88)接近最高水平

人口(万人)指标:

  • 上海(1.0)人口最多
    深圳(0.0)人口最少(但需注意深圳面积也最小)
    成都(0.50)人口处于中间位置

面积(平方公里)指标:

  • 成都(1.0)面积最大
    深圳(0.0)面积最小
    上海(0.28)面积较小,但其GDP和人口密度很高

2、Z-score标准化

Z-score标准化(也叫标准差标准化或零-均值标准化)是一种统计方法,用于将数据转换为具有均值为0、标准差为1的标准正态分布。

核心公式为: z = x − μ σ z={\frac{x-\mu}{\sigma}} z=σx−μ

  • z:标准化后的值(Z分数) x:原始值 μ:该列的均值 σ:该列的标准差
python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')

df6_zscore = df_data.copy()

# 定义数值列
numeric_cols = ['GDP(亿元)', '人口(万人)', '面积(平方公里)']

for col in numeric_cols:
    mean_val = df6_zscore[col].mean()
    std_val = df6_zscore[col].std()
    df6_zscore[f'{col}_zscore'] = (df6_zscore[col] - mean_val) / std_val

print("Z-score标准化后:")
# 输出城市列和所有标准化后的列
output_cols = ['城市'] + [f'{col}_zscore' for col in numeric_cols]
print(df6_zscore[output_cols])

输出:

python 复制代码
Z-score标准化后:
   城市  GDP(亿元)_zscore  人口(万人)_zscore  面积(平方公里)_zscore
0  北京         0.716238        0.328726             0.255240
1  上海         1.288371        1.352782            -0.469163
2  广州        -0.438185       -0.831754             0.003027
3  深圳         0.026692       -1.036339            -1.391226
4  成都        -1.593116        0.186584             1.602122

结果解读:

Z-score标准化将数据转换为均值为0,标准差为1的正态分布:

  • 正值表示高于平均值
  • 负值表示低于平均值
  • 数值大小表示距离均值的标准差倍数

GDP(亿元)指标:

  • 上海(1.29)最高,比平均GDP高出约1.29个标准差
    成都(-1.59)最低,比平均GDP低约1.59个标准差
    北京(0.72)明显高于平均值
    广州(-0.44)略低于平均值

人口(万人)指标:

  • 上海(1.35)人口最多,显著高于平均水平
    深圳(-1.04)人口最少,明显低于平均水平
    北京(0.33)略高于平均值
    成都(0.19)接近平均水平

面积(平方公里)指标:

  • 成都(1.60)面积最大,显著大于平均面积
    深圳(-1.39)面积最小,显著小于平均面积
    上海(-0.47)面积略小于平均值
    北京(0.26)面积略大于平均值

3、小数定标规范化

小数定标规范化(Decimal Scaling) 通过移动数据的小数点位置,将数据转换到[-1,1]或[0,1]区间:

  • 方法:除以10的k次幂,其中k是使所有数据的绝对值都小于1的最小整数 保留了数据的分布形状,只是调整了量级
python 复制代码
import pandas as pd

df_data = pd.read_excel('data.xlsx')

df6_decimal = df_data.copy()
# 定义数值列
numeric_cols = ['GDP(亿元)', '人口(万人)', '面积(平方公里)']

for col in numeric_cols:
    max_abs = abs(df6_decimal[col]).max()
    k = len(str(int(max_abs)))
    df6_decimal[f'{col}_decimal'] = df6_decimal[col] / (10 ** k)

print("小数定标规范化后:")
# 输出城市列和所有规范化后的列
output_cols = ['城市'] + [f'{col}_decimal' for col in numeric_cols]
print(df6_decimal[output_cols])

输出:

python 复制代码
小数定标规范化后:
   城市  GDP(亿元)_decimal  人口(万人)_decimal  面积(平方公里)_decimal
0  北京         0.361026        0.218930          0.164105
1  上海         0.387006        0.248709          0.063405
2  广州         0.250191        0.186766          0.074344
3  深圳         0.276702        0.175601          0.019975
4  成都         0.170127        0.211920          0.143350

结果解读:

GDP(亿元)指标:

  • 最大值:38700.58(5位数)
    k = 5,所以除以10⁵(100,000)
    规范化后数值在1.7-3.87之间

人口(万人)指标:

  • 最大值:2487.09(4位数)
    k = 4,所以除以10⁴(10,000)
    规范化后数值在0.175-0.249之间

面积(平方公里)指标:

  • 最大值:16410.54(5位数)
    k = 5,所以除以10⁵(100,000)
    规范化后数值在0.20-1.64之间

所有数据被缩放到相对接近的范围内,不同指标之间可以更直观地比较。

对比不同规范化方法:

  • 最小-最大规范化:将数据映射到[0,1]区间,强调相对位置
  • Z-score标准化:以标准差为单位表示距离均值的远近,适合正态分布数据
  • 小数定标规范化:通过移动小数点简化数据,适合数据量级差异大的情况
相关推荐
万粉变现经纪人9 小时前
如何解决 pip install 代理报错 SOCKS5 握手失败 ReadTimeoutError 问题
java·python·pycharm·beautifulsoup·bug·pandas·pip
晨晨渝奇10 小时前
pandas 中将两个 DataFrame 分别导出到同一个 Excel 同一个工作表(sheet1)的 A1 单元格和 D1 单元格
excel·pandas
jarreyer2 天前
python,numpy,pandas和matplotlib版本对应关系
python·numpy·pandas
写代码的【黑咖啡】2 天前
Python中的Pandas:数据分析的利器
python·数据分析·pandas
laocooon5238578864 天前
对传入的 x , y 两个数组做折线图, x 对应 x 轴, y 对应 y 轴。并保存到 Task1/image1/T2.png
python·numpy·pandas·matplotlib
Maxwell_li15 天前
新冠检测例子学习查准率和召回率
学习·机器学习·数据分析·回归·numpy·pandas
渡我白衣5 天前
Python 与数据科学工具链入门:NumPy、Pandas、Matplotlib 快速上手
人工智能·python·机器学习·自然语言处理·numpy·pandas·matplotlib
IT北辰6 天前
用 Python 自动解析药品规格并计算包装总容量 —— pandas + 正则实战
开发语言·python·pandas
lbb 小魔仙6 天前
Python 读取 Excel 文件:openpyxl 与 pandas 实战对比
python·excel·pandas