python清理数据

流程

在进行任何清理操作之前,请先将每份数据备份,所有清理操作请在这份复件上进行,保留肮脏和/或凌乱的原始数据集以便日后查看。要在 pandas 中复制数据框,请使用copy 方法。如果原始数据框名为 df,你可以把即将清理干净的数据集复件命名为 df_clean

df_clean = df.copy()

 

 

 

import pandas as pd

df = pd.read_csv('animals.csv')

df.head()

df_clean = df.copy()

# 使用字符串分割,删除每个动物名称前面的 'bb' 
df_clean['Animal'] = df_clean['Animal'].str[2:]

# 在体重和脑重量两列,将 ! 替换为 . 
df_clean['Body weight (kg)'] = df_clean['Body weight (kg)'].str.replace('!', '.')
df_clean['Brain weight (g)'] = df_clean['Brain weight (g)'].str.replace('!', '.')

df_clean.head()

# 利用 dirty animals.csv 重新加载 df_clean 
df_clean = df.copy()

df_clean['Animal'] = df_clean['Animal'].str[2:]

df_clean.Animal.head()

df_clean['Body weight (kg)'] = df_clean['Body weight (kg)'].str.replace('!', '.')
df_clean['Brain weight (g)'] = df_clean['Brain weight (g)'].str.replace('!', '.')

df_clean.head()

 

 

收集

import pandas as pd

patients = pd.read_csv('patients.csv')
treatments = pd.read_csv('treatments.csv')
adverse_reactions = pd.read_csv('adverse_reactions.csv')

patients.info()

treatments.info()

adverse_reactions.info()

all_columns = pd.Series(list(patients) + list(treatments) + list(adverse_reactions))
all_columns[all_columns.duplicated()]

list(patients)

patients[patients['address'].isnull()]

patients.describe()

treatments.describe()

patients.sample(5)

patients.surname.value_counts()

patients.address.value_counts()

patients[patients.address.duplicated()]

patients.weight.sort_values()

weight_lbs = patients[patients.surname == 'Zaitseva'].weight * 2.20462
height_in = patients[patients.surname == 'Zaitseva'].height
bmi_check = 703 * weight_lbs / (height_in * height_in)
bmi_check

 

patients[patients.surname == 'Zaitseva'].bmi

sum(treatments.auralin.isnull())

sum(treatments.novodra.isnull())

质量

patients 表格

  • 邮编是浮点,而不是字符串
  • 邮编有时是四位数
  • Tim Neudorf 的身高是 27 英尺,而不是 72 英尺
  • 有时使用州的全称,其他用简称
  • Dsvid Gustafsson
  • 缺少人口统计信息 (地址列至联系方式列) (无法清理)
  • 错误的数据类型 (指定性别、州、邮编和出生日期列)
  • 多个手机号格式
  • John Doe 的默认数据
  • Jakobsen、Gersten、Taylor 多条记录
  • Zaitseva 体重单位是 kgs,不是 lbs

treatments 表格

  • 缺少 HbA1c 变化
  • Auralin 和 Novodra 初始剂量和最终剂量中的字母 'u'
  • 小写形式的姓和名
  • 缺少记录 (280 而不是 350)
  • 错误的数据类型 (auralin 和 novodra 列)
  • HbA1c 变化不准确 (首个 4s 误写为 9s)
  • auralin 和 novodra 列中空值用破折号 (-) 表示

adverse_reactions 表格

  • 小写形式的姓和名

清洁度

  • patients 表格中的联系方式一列包括两个变量:手机号和邮箱
  • treatments 表格两列中的三个变量 (治疗、初始剂量和最终剂量)
  • 不良反应应是 treatments 表格的一部分
  • patients 表格中的姓和名两列复制到 treatments 和 adverse_reactions 表格中

清理

patients_clean = patients.copy()
treatments_clean = treatments.copy()
adverse_reactions_clean = adverse_reactions.copy()

缺失数据

treatments:缺少记录 (280 而不是 350)

定义

将 treatments_cut.csv 导入一个 DataFrame 中,并它拼接到初始的 treatments DataFrame 中。

treatments_cut = pd.read_csv('treatments_cut.csv')
treatments_clean = pd.concat([treatments_clean, treatments_cut],
                             ignore_index=True)

treatments_clean.head()

treatments_clean.tail()

treatments:缺少 HbA1c 变化和 HbA1c 变化不准确 (首个 4s 误写为 9s)

定义

重新计算 hba1c_change 一列:hba1c_start 减去 hba1c_end

treatments_clean.hba1c_change = (treatments_clean.hba1c_start - 
                                 treatments_clean.hba1c_end)

treatments_clean.hba1c_change.head()

 

清洁度

patients 表格中的联系方式一列包括两个变量:手机号和邮箱

定义

使用正则表达式和 pandas 的 str.extract 方法,从 联系方式 一列提取变量手机号 和 邮箱 。完成后删除 联系方式 一列。

patients_clean['phone_number'] = patients_clean.contact.str.extract('((?:\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4})', expand=True)
patients_clean['email'] = patients_clean.contact.str.extract('([a-zA-Z][a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.][a-zA-Z]+)', expand=True)
# Note: axis=1 表明我们参考的是一列,而不是一行
patients_clean = patients_clean.drop('contact', axis=1)

# 确认联系方式一列可以运行
list(patients_clean)

patients_clean.phone_number.sample(25)

# 确认没有邮箱以整数开头 (正则表达式不能匹配整数)
patients_clean.email.sort_values().head()

treatments 表格两列中的三个变量 (治疗、初始剂量和最终剂量)

定义

在 auralin 和 novodra 两列中加入 治疗 和 剂量 列 (这时剂量仍然包含初始剂量和最终剂量)。然后使用破折号 ' - ' 把剂量列切分,得到 初始剂量 和 最终剂量 两列。删除中间使用的 剂量 一列。

treatments_clean = pd.melt(treatments_clean, id_vars=['given_name', 'surname', 'hba1c_start', 'hba1c_end', 'hba1c_change'],
                           var_name='treatment', value_name='dose')
treatments_clean = treatments_clean[treatments_clean.dose != "-"]
treatments_clean['dose_start'], treatments_clean['dose_end'] = treatments_clean['dose'].str.split(' - ', 1).str
treatments_clean = treatments_clean.drop('dose', axis=1)

treatments_clean.head()

不良反应应是 treatments 表格的一部分

定义

将 不良反应 一列合并到 treatments 表格中,按照 名* 和 *姓进行合并。

treatments_clean = pd.merge(treatments_clean, adverse_reactions_clean,
                            on=['given_name', 'surname'], how='left')

treatments_clean

patients 表格中的姓和名两列复制到 treatments 和 adverse_reactions 表格中,以及小写形式的姓和名

定义

我们不再需要不良反应表格,所以忽略这部分内容。在 patients 表格中,提取病人编号和姓名,然后把这些名字改为小写形式,加入到 treatments 表格中。然后删除治疗表格中的姓和名两列 (这样小写形式不再是问题了)。

id_names = patients_clean[['patient_id', 'given_name', 'surname']]
id_names.given_name = id_names.given_name.str.lower()
id_names.surname = id_names.surname.str.lower()
treatments_clean = pd.merge(treatments_clean, id_names, on=['given_name', 'surname'])
treatments_clean = treatments_clean.drop(['given_name', 'surname'], axis=1)

# 确认进行了正确融合
treatments_clean

# Patient ID should be the only duplicate column
all_columns = pd.Series(list(patients_clean) + list(treatments_clean))
all_columns[all_columns.duplicated()]

质量

邮编是浮点,而不是字符串,有时是四位数

定义

Convert the zip code column's data type from a float to a string 使用 astype 把邮件一列的数据类型从浮点转换为字符串,使用字符串分割删除 '.0'。在四位数邮编前面加上 0。

patients_clean.zip_code = patients_clean.zip_code.astype(str).str[:-2].str.pad(5, fillchar='0')
# 对于上面代码转化后的'0000n'非数字条目,进行再次转化
patients_clean.zip_code = patients_clean.zip_code.replace('0000n', np.nan)

patients_clean.zip_code.head()

Tim Neudorf 的身高是 27 英尺,而不是 72 英尺

定义

在 patients 表格中身高为 27 英尺 (仅有一个) 的一行身高,替换为72英尺。

patients_clean.height = patients_clean.height.replace(27, 72)

# 应为空
patients_clean[patients_clean.height == 27]

# 确认完成替换
patients_clean[patients_clean.surname == 'Neudorf']

有时使用州的全称,其他用简称

定义

使用函数,将 California (加利福尼亚)、New York (纽约)、Illinois (伊利诺伊)、Florida (佛罗里达) 和 Nebrask (内布拉斯加) 等州的全称转变为简称。

# 从州的全称映射到简称
state_abbrev = {'California': 'CA',
                'New York': 'NY',
                'Illinois': 'IL',
                'Florida': 'FL',
                'Nebraska': 'NE'}

# 使用的函数
def abbreviate_state(patient):
    if patient['state'] in state_abbrev.keys():
        abbrev = state_abbrev[patient['state']]
        return abbrev
    else:
        return patient['state']
    
patients_clean['state'] = patients_clean.apply(abbreviate_state, axis=1)

patients_clean.state.value_counts()

Dsvid Gustafsson

Define

在 patients 表格中含有名 'Dsvid' 的一行里替换为'David'。

patients_clean.given_name = patients_clean.given_name.replace('Dsvid', 'David')

patients_clean[patients_clean.surname == 'Gustafsson']

错误的数据类型 (指定性别、州、邮编和出生日期列) 和错误的数据类型 (auralin 和 novodra 列),以及 Auralin 和 Novodra 初始剂量和最终剂量中的字母 'u'

Define

将指定性别和州转化为分类数据类型。上面已经解决了邮编的数据类型。把出生日期转化为 datetime 数据类型。在初始剂量和最终剂量中添加字母 'u',并把这些列转化为整数数据类型。

# 转为分类数据类型
patients_clean.assigned_sex = patients_clean.assigned_sex.astype('category')
patients_clean.state = patients_clean.state.astype('category')

# 转为 datetime 类型
patients_clean.birthdate = pd.to_datetime(patients_clean.birthdate)

# 添加 u 并转为整数类型
treatments_clean.dose_start = treatments_clean.dose_start.str.strip('u').astype(int)
treatments_clean.dose_end = treatments_clean.dose_end.str.strip('u').astype(int)

patients_clean.info()

treatments_clean.info()

多个手机号格式

定义

增加所有的 " "、 "-"、"(", ")" 和 "+",存储所有没有格式的数字。如果手机号只有 10 位数,在手机号前添加 1 (我们需要国家编号)。

patients_clean.phone_number = patients_clean.phone_number.str.replace(r'\D+', '').str.pad(11, fillchar='1')

patients_clean.phone_number.head()

John Doe 的默认数据

定义

从 patients 表格中删除不可恢复的 John Doe 记录。

patients_clean = patients_clean[patients_clean.surname != 'Doe']

# 应该没有 Doe 记录
patients_clean.surname.value_counts()

# 应该没有 123 Main Street 记录
patients_clean.address.value_counts()

Jakobsen、Gersten、Taylor 多条记录

定义

从 patients 表格中删除 Jake Jakobsen、Pat Gersten 和 Sandy Taylor。这些是昵称,不应该出现在 treatments 表格中 (删除错误名字可以保证 patients和 treatments 表格的一致性问题)。这些是复制后第二次出现。这些是唯一出现的非空值复制地址。

# 波浪符号表示否: http://pandas.pydata.org/pandas-docs/stable/indexing.html#boolean-indexing
patients_clean = patients_clean[~((patients_clean.address.duplicated()) & patients_clean.address.notnull())]

patients_clean[patients_clean.surname == 'Jakobsen']

patients_clean[patients_clean.surname == 'Gersten']

patients_clean[patients_clean.surname == 'Taylor']

Zaitseva 体重单位是 kgs,不是 lbs

定义

使用 高级索引 把姓是 Zaitseva 的行隔离出来,并把体重单元格中的 kg 改为 lbs。

weight_kg = patients_clean.weight.sort_values()[210]
mask = patients_clean.surname == 'Zaitseva'
column_name = 'weight'
patients_clean.loc[mask, column_name] = weight_kg * 2.20462

# 48.8 不应该是最低的
patients_clean.weight.sort_values()

 

清理数据有两种:

  • 人工清理 (不推荐,除非问题只会发生一次)
  • 程序清理

数据程序清理流程:

  1. 确定方案:将评估结果转化为具体的清理任务。这些确定下来的方案可作为指引列表,供他人 (或未来的你) 观察你的工作并重现操作。
  2. 编写代码:将定下来的方案转化为代码并运行。
  3. 检验效果:检验你的数据集,你可以直接用肉眼观察或使用代码来检验,确保清理操作起到了应有的效果。

在进行清理之前,请千万对原始数据进行备份!

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,我可以为您提供一些关于使用Python清理Excel数据的方法。一般而言,我们可以使用Pythonpandas库来读取和处理Excel文件。以下是清理Excel数据的一些常见步骤: 1. 导入pandas库: ```python import pandas as pd ``` 2. 使用pandas的read_excel函数读取Excel文件: ```python df = pd.read_excel('your_file.xlsx') ``` 3. 删除不必要的行或列: ```python df = df.drop(columns=['column_name']) df = df.drop(index=[0, 1]) ``` 4. 筛选出需要的数据: ```python df = df[df['column_name'] == 'desired_value'] ``` 5. 处理缺失值: ```python df = df.fillna('new_value') ``` 6. 格式化数据: ```python df['column_name'] = pd.to_datetime(df['column_name'], format='%Y-%m-%d') ``` 7. 导出清理后的数据: ```python df.to_excel('new_file.xlsx', index=False) ``` 以上是一些基本的Excel数据清理步骤,您可以根据具体情况进行调整和细化。希望对您有所帮助! ### 回答2: Python是一种强大的编程语言,可以方便地进行数据清理工作,尤其是在处理Excel数据方面。 首先,我们需要安装一个名为PandasPython库,它提供了很多有用的函数和工具来处理数据。安装完成后,我们可以使用Pandas读取Excel文件,并将数据加载到一个名为DataFrame的数据结构中。 在数据清理过程中,我们可能会遇到一些常见的问题,例如缺失值、重复值、错误值等。Pandas提供了很多函数来快速识别和处理这些问题。 针对缺失值,我们可以使用dropna()函数删除缺失值,或使用fillna()函数填充缺失值。对于重复值,我们可以使用drop_duplicates()函数删除重复行。 在数据清理过程中,我们还可能需要更改数据类型、重命名列名、删除不必要的列等。Pandas提供了相应的函数来实现这些操作,例如astype()函数用于更改数据类型,rename()函数用于重命名列名,drop()函数用于删除列。 另外,Python还有其他一些用于数据清理的有用库,如openpyxl、xlrd等。这些库提供了更多的功能和工具,可以帮助我们更加高效地进行Excel数据清理工作。 总之,Python是一个非常适合进行Excel数据清理的工具。它提供了丰富的库和函数,可以帮助我们快速、方便地处理Excel数据中的各种问题,使得数据清理工作变得更加简单和高效。 ### 回答3: Python可以通过一些库和工具进行Excel数据清理工作。以下是一种可能的方法: 1. 导入所需的库: ``` import pandas as pd import numpy as np import openpyxl ``` 2. 读取Excel文件并转换为DataFrame对象: ``` data = pd.read_excel('文件路径/文件名.xlsx') ``` 3. 检查数据的结构和内容: ``` data.head() # 查看前几行数据 data.info() # 查看数据的基本信息,如列名和数据类型 data.describe() # 查看数据的统计摘要信息 ``` 4. 处理缺失值: ``` data.isnull().sum() # 统计每列的缺失值数量 data = data.dropna() # 删除包含缺失值的行 ``` 5. 数据类型转换: ``` data['列名'] = data['列名'].astype('新的数据类型') # 将指定列转换为新的数据类型 ``` 6. 重命名列名: ``` data.rename(columns={'旧列名': '新列名'}, inplace=True) # 将指定列名进行重命名 ``` 7. 去除重复值: ``` data.drop_duplicates(inplace=True) # 删除重复的行 ``` 8. 剔除异常值: ``` data = data[(data['列名'] > 下界) & (data['列名'] < 上界)] # 按指定条件剔除异常值 ``` 9. 导出清理后的数据到新的Excel文件: ``` data.to_excel('保存路径/保存文件名.xlsx', index=False) ``` 通过以上步骤,可以使用Python对Excel数据进行清理、转换和处理,以提高数据的质量和准确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值