实验目的:

掌握使用python相关的库进行数据集成融合方法以及简单应用。

实验要求:

采用Python语言(建议python 3.6以上),pycharm开发环境。

本实验要求熟练pandas库和numpy库中相关的数据集成融合方法,并能掌握方法,对实验数据集进行集成,并应用。

提交实验数据集的实验代码和效果。

实验内容:

本实验提供了运动员信息采集01.csv和运动员信息采集02.xlsx。

本实验主要利用pandas库和numpy库进行数据集成融合,主要包括集成融合方法、数据清洗以及填充,并利用集成的数据集进行体质分析应用。

主要步骤及要求:

1.读数据'file:运动员信息采集01.csv'和'file:运动员信息采集02.xlsx',采用外连接的方式合并数据

pd.merge(left=file_one,right=file_two, how='outer')

2.筛选出国籍为中国的运动员

3.检测合并的数据集中是否有重复值,删除重复值,并重新对数据进行索引。

4.筛选出项目为篮球的运动员。

5. 筛选男篮球运动员,将身高转化为cm,计算身高平均值(四舍五入取整),

利用平均值填充缺失值;计算男篮球运动员的平均体重,填充缺失值。

6筛选女篮球运动员数据,将身高转化为cm,计算女篮球运动员平均身高,

利用平均值填充缺失值;计算女篮球运动员的平均体重,填充缺失值。

7.年龄分布图。根据计算的年龄值绘制直方图。

import matplotlib.pyplot as plt

8.计算体质指数

sum_bmi = weight / (height/100)**2

统计体质指数为非正常的女篮运动员的数

print(f'体质指数小于19:{females[females < 19]}')

print(f'体质指数大于24:{females[females > 24]}')

print(f'非正常体质范围的总人数:{count}')

# 统计体质指数为非正常的男篮运动员的数量

print(f'体质指数小于20:{males[males < 20]}')

print(f'体质指数大于25:{males[males > 25]}')

print(f'非正常体质范围的总人数:{count}')

1 读数据'file:运动员信息采集01.csv'和'file:运动员信息采集02.xlsx',采用外连接的方式合并数据

注(需要源码可评论源码,或者右边微信公众号关注回复运动员数据分析源码)

import pandas as pd # 引用模块改名为pd

import numpy as np

df_data1 = pd.read_csv('运动员信息采集01.csv') # 读取数据1

df_data2 = pd.read_excel('运动员信息采集02.xlsx') # 读取数据2

df = pd.merge(left=df_data1, right=df_data2, how='outer') # 采用全外连接的方式合并数据

print(df)

df.to_csv('dreamer_all.csv', encoding='utf_8_sig') # 保存为dreamer_all.csv,并解决编码错误问题

2 筛选出国籍为中国的运动员

import pandas as pd # 引用模块改名为pd

import numpy as np

df_data1 = pd.read_csv('运动员信息采集01.csv') # 读取数据1

df_data2 = pd.read_excel('运动员信息采集02.xlsx') # 读取数据2

df = pd.merge(left=df_data1, right=df_data2, how='outer') # 采用全外连接的方式合并数据

# 行选取数据为中国的数据

result = df.query('(国籍== "中国")')

result.to_csv('dreamer_2.csv', encoding='utf_8_sig')

print(result)

3 检测合并的数据集中是否有重复值,删除重复值,并重新对数据进行索引。

# 先删除重复的行,只保留第一次出现的,得到一个 行唯一 的数据集,再使用 drop_duplicates() 删除掉 df 中存在重复的所有数据,

# 这次不保留第一次出现的重复值,将上述两个结果集进行合并,使用 drop_duplicates() 对新生成的数据集进行去重,即可得到重复行的数据。

# 列出重复值

result = df.drop_duplicates(keep="first")\

.append(df.drop_duplicates(keep=False))\

.drop_duplicates(keep=False)

print(result)

import pandas as pd # 引用模块改名为pd

import numpy as np

df_data1 = pd.read_csv('运动员信息采集01.csv') # 读取数据1

df_data2 = pd.read_excel('运动员信息采集02.xlsx') # 读取数据2

df = pd.merge(left=df_data1, right=df_data2, how='outer') # 采用外连接的方式合并数据

'''

# 行选取数据为中国的数据

result = df.query('(国籍== "中国")')

result.to_csv('dreamer_2.csv', encoding='utf_8_sig')

print(result)

'''

# 先删除重复的行,只保留第一次出现的,得到一个 行唯一 的数据集,再使用 drop_duplicates() 删除掉 df 中存在重复的所有数据,

# 这次不保留第一次出现的重复值,将上述两个结果集进行合并,使用 drop_duplicates() 对新生成的数据集进行去重,即可得到重复行的数据。

# 列出重复值

df.drop_duplicates(keep="first")\

.append(df.drop_duplicates(keep=False))\

.drop_duplicates(keep=False)

result = df.drop_duplicates(ignore_index=True)

# 通过drop_duplicates()方法处理重复值,删除所有列的重复项,重新设置行索引。

print(result)

result.to_csv('dreamer_3.csv', encoding='utf_8_sig')

4 筛选出项目为篮球的运动员。

result = df.query('(项目 == "篮球")')

result = result.drop_duplicates(ignore_index=True)

print(result)

result.to_csv('dreamer_4.csv', encoding='utf_8_sig')

5 筛选男篮球运动员,将身高转化为cm,计算身高平均值(四舍五入取整),利用平均值填充缺失值;计算男篮球运动员的平均体重,填充缺失值。

平均身高

import pandas as pd # 引用模块改名为pd

df_data1 = pd.read_csv('运动员信息采集01.csv') # 读取数据1

df_data2 = pd.read_excel('运动员信息采集02.xlsx') # 读取数据2

df = pd.merge(left=df_data1, right=df_data2, how='outer') # 采用外连接的方式合并数据

'''

# 行选取数据为中国的数据

result = df.query('(国籍== "中国")')

result.to_csv('dreamer_2.csv', encoding='utf_8_sig')

print(result)

'''

'''

# 先删除重复的行,只保留第一次出现的,得到一个 行唯一 的数据集,再使用 drop_duplicates() 删除掉 df 中存在重复的所有数据,

# 这次不保留第一次出现的重复值,将上述两个结果集进行合并,使用 drop_duplicates() 对新生成的数据集进行去重,即可得到重复行的数据。

# 列出重复值

df.drop_duplicates(keep="first")\

.append(df.drop_duplicates(keep=False))\

.drop_duplicates(keep=False)

result = df.drop_duplicates(ignore_index=True)

# 通过drop_duplicates()方法处理重复值,删除所有列的重复项,重新设置行索引。

print(result)

result.to_csv('dreamer_3.csv', encoding='utf_8_sig')

'''

'''

result = df.query('(项目 == "篮球")')

result = result.drop_duplicates(ignore_index=True)

print(result)

result.to_csv('dreamer_4.csv', encoding='utf_8_sig')

'''

male_data = df.query('(项目 == "篮球") and (性别 == "男")') # 筛选男篮运动员数据

male_data = male_data.copy()

male_height = male_data['身高'].dropna() # 计算平均身高前,要先删掉空值数

fill_male_height = round(male_height.apply(lambda x: x[0:-2]).astype(int).mean())

# round方法是四舍五入,astype()是类型转换,mean()是求平均数

fill_male_height = str(int(fill_male_height)) + 'cm'

print("男篮平均身高为:" + fill_male_height)

# 用平均值填充缺失值

male_data.loc[:, '身高'] = male_data.loc[:, '身高'].fillna(fill_male_height)

# 为方便后期使用,这里将身高数据转换为整数

male_data.loc[:, '身高'] = male_data.loc[:, '身高'].apply(lambda x: x[0:-2]).astype(int)

# 重命名列标签索引

male_data.rename(columns={'身高': '身高/cm'}, inplace=True)

print(male_data)

male_data.to_csv('dreamer_5.csv', encoding='utf_8_sig')

平均体重,同理

6 筛选女篮球运动员数据,将身高转化为cm,计算女篮球运动员平均身高,利用平均值填充缺失值;计算女篮球运动员的平均体重,填充缺失值。

根据第五的做法,只需修改对应筛选条件和参数同理可得

# 求女篮的平均数据及填充平均值

female_data_height = df.query('(项目 == "篮球") and (性别 == "女")') # 筛选女篮运动员数据

female_data_height = female_data_height.copy()

# 由于女生身高数据格式差异大,也没有现成工具,所以只能用字典手动处理特殊格式

data = {'191cm': '191厘米', '1米89公分': '189厘米', '2.01米': '201厘米', '187公分': '187厘米', '1.97M': '197厘米', '1.98米': '198厘米',

'192cm': '192厘米'}

female_data_height.loc[:, '身高'] = female_data_height.loc[:, '身高'].replace(data)

female_height = female_data_height['身高'].dropna() # 计算平均身高前,要先删掉空值数

fill_female_height = round(female_height.apply(lambda x: x[0:-2]).astype(int).mean())

# round方法是四舍五入,astype()是类型转换,mean()是求平均数

fill_female_height = str(int(fill_female_height)) + 'cm'

print("女篮平均身高为:" + fill_female_height)

# 用平均值填充缺失值

female_data_height.loc[:, '身高'] = female_data_height.loc[:, '身高'].fillna(fill_female_height)

# 为方便后期使用,这里将身高数据转换为整数

female_data_height.loc[:, '身高'] = female_data_height.loc[:, '身高'].apply(lambda x: x[0:-2]).astype(int)

# 重命名列标签索引

female_data_height.rename(columns={'身高': '身高/cm'}, inplace=True)

#print(female_data_height)

female_data_weight = female_data_height.copy()

# 采用前向填充的方式,替换体重为 8 的异常值

female_data_weight['体重'].replace(to_replace='8kg', method='pad', inplace=True)

female_weight = female_data_weight['体重'].dropna() # 计算平均体重前,要先删掉空值数

fill_female_weight = round(female_weight.apply(lambda x: x[0:-2]).astype(int).mean())

# round方法是四舍五入,astype()是类型转换,mean()是求平均数

fill_female_weight = str(int(fill_female_weight)) + 'kg'

print("女篮平均体重为:" + fill_female_weight)

# 用平均值填充缺失值

female_data_weight.loc[:, '体重'] = female_data_weight.loc[:, '体重'].fillna(fill_female_weight)

# 为方便后期使用,这里将数据转换为整数

female_data_weight.loc[:, '体重'] = female_data_weight.loc[:, '体重'].apply(lambda x: x[0:-2]).astype(int)

# 重命名列标签索引

female_data_weight.rename(columns={'体重': '体重/kg'}, inplace=True)

print(female_data_weight)

female_data_weight.to_csv('女篮身高体重整改.csv', encoding='utf_8_sig')

7 年龄分布图。根据计算的年龄值绘制直方图。

整理全年龄数据,将其全部转换为“x年x月x日”形式显示的日期

全部代码如下

import pandas as pd # 引用模块改名为pd

import datetime

import matplotlib.pyplot as plt

df_data1 = pd.read_csv('运动员信息采集01.csv') # 读取数据1

df_data2 = pd.read_excel('运动员信息采集02.xlsx') # 读取数据2

df = pd.merge(left=df_data1, right=df_data2, how='outer') # 采用外连接的方式合并数据

data = df.dropna()

data = data.copy()

# 将以“x”天显示的日期转换成以“x年x月x日”形式显示的日期

initial_time = datetime.datetime.strptime('1900-01-01', "%Y-%m-%d")

for i in data.loc[:, '出生日期']:

if type(i) == int:

new_time = (initial_time + datetime.timedelta(days=i)).strftime('%Y{y}%m{m}%d{d}').format(y='年', m='月', d='日')

data.loc[:, '出生日期'] = data.loc[:, '出生日期'].replace(i, new_time)

# 为保证出生日期的一致性,这里统一使用只保留到年份的日期

data.loc[:, '出生日期'] = data['出生日期'].apply(lambda x: x[:5])

data['出生日期']

# 设置图表中文字的字体为黑体

plt.rcParams['font.sans-serif'] = ['SimHei']

# 根据出生日期计算年龄

ages = 2022 - data['出生日期'].apply(lambda x: x[0:-1]).astype(int)

# 根据计算的年龄值绘制直方图

ax = ages.plot(kind='hist')

# 设置直方图中x轴、y轴的标签为“年龄(岁)”和“频数”

ax.set_xlabel('年龄(岁)')

ax.set_ylabel('频数')

# 设置x轴的刻度为“ages的最小值, ages的最小值+2, ..., ages最大值+1”

ax.set_xticks(range(ages.min(),ages.max()+1, 2))

plt.show()

8 计算体质指数 sum_bmi = weight / (height/100)**2

注:个人是把数据进行平均值填充,以及整理一些如8kg离谱的数据后,进行计算,可能结果会有所不同。(理解过程即可)

# 增加“体质指数”一列,并初始化为0

统计体质指数为非正常的女篮运动员的数量

import pandas as pd # 引用模块改名为pd

df = pd.read_csv('女篮身高体重整改.csv') # 读取数据,由前面题6计算格式整合填充得出女篮数据

# 增加“体质指数”一列,初始化为0

df['体质指数'] = 0

# 计算女生体质指数

def outer(num):

weight = df['体重/kg']

height = df['身高/cm']

def ath_bmi(sum_bmi):

sum_bmi = weight / (height / 100) ** 2

return num + sum_bmi

return ath_bmi

df['体质指数'] = df[['体质指数']].apply(outer(df['体质指数'])).round(1)

fenale_result = df.query('(项目 == "篮球") and (性别 == "女")')

fenale_result.to_csv('dreamer_8_1.csv', encoding='utf_8_sig') # 筛选输出带有体质指数的女篮球运动员

# 按性别分组,然后遍历输出带体质指数的数据

groupby_obj = df.groupby('性别')

for i in groupby_obj:

print(i)

# 以下为女篮运动员体质指数的统计,不在19~24范围内的都视为非正常

# dict是字典,有key和value两个属性

females = dict([x for x in groupby_obj])['女']['体质指数'].values

# 统计体质指数为非正常的女篮运动员的数量

count = females[females < 19].size + females[females > 24].size

print(f'体质指数小于19:{females[females < 19]}')

print(f'体质指数大于24:{females[females > 24]}')

print(f'非正常体质指数范围的总人数:{count}')

统计体质指数为非正常的男篮运动员的数量

同理,男篮把之前题6整合好的数据再一步进行即可

import pandas as pd # 引用模块改名为pd

df = pd.read_csv('男篮身高体重整改.csv') # 读取数据,由前面题6计算格式整合填充得出女篮数据

# 增加“体质指数”一列,初始化为0

df['体质指数'] = 0

# 计算男生体质指数

def outer(num):

weight = df['体重/kg']

height = df['身高/cm']

def ath_bmi(sum_bmi):

sum_bmi = weight / (height / 100) ** 2

return num + sum_bmi

return ath_bmi

df['体质指数'] = df[['体质指数']].apply(outer(df['体质指数'])).round(1)

male_result = df.query('(项目 == "篮球") and (性别 == "男")')

male_result.to_csv('dreamer_8_2.csv', encoding='utf_8_sig') # 筛选输出带有体质指数的男篮球运动员

# 按性别分组,然后遍历输出带体质指数的数据

groupby_obj = df.groupby('性别')

for i in groupby_obj:

print(i)

males = dict([x for x in groupby_obj])['男']['体质指数'].values

# 统计体质指数为非正常的男篮运动员的数量

count = males[males < 20].size + males[males > 25].size

print(f'体质指数小于20:{males[males < 20]}')

print(f'体质指数大于25:{males[males > 25]}')

print(f'非正常体质范围的总人数:{count}')