数据分析(3)数据重构

本文介绍数据重构中的合并数据集方法,包括stack、concat、join、append和merge。通过实例演示了如何使用这些方法进行数据的拼接、连接和组合,并通过groupby进行数据分组和聚合操作,帮助理解数据处理过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

task3——数据重构

学习参考资料:datawhale动手学数据分析

学习链接:https://github.com/datawhalechina/hands-on-data-analysis

学习目标:

  • 了解数据重构的方法
  • 学会使用groupby作数据运算

什么是数据重构?
数据重构:指数据从一种格式到另一种格式的转换,包括结构转换、格式变化、类型替换等,以解决空间数据在结构、格式和类型上的统一,实现多源和异构数据的联接与融合。

合并数据集

【知识部分】

stack

使用pandas进行数据重排时,经常用到stack和unstack两个函数。stack的意思是堆叠,堆积,unstack即“不要堆叠”。
常见的数据层次化结构有:花括号和表格。

表格在行列方向上均有索引(类似于DataFrame)。
花括号结构只有“列方向”上的索引(类似于层次化的Series)。
stack函数会将数据从”表格结构“变成”花括号结构“,即将其行索引变成列索引,反之,unstack函数将数据从”花括号结构“变成”表格结构“,即要将其中一层的列索引变成行索引。

方法介绍
stackstack函数会将数据从”表格结构“变成”花括号结构“ ,将列索引转为行索引,完成层级索引
unstackunstack函数将数据从”花括号结构“变成”表格结构“,层级索引展开 ,默认操作内层索引
df_obj = pd.DataFrame(np.random.randint(0,10, (5,2)), columns=['data1', 'data2'])
df_obj

在这里插入图片描述

stacked = df_obj.stack()
print(stacked)
stackedd=stacked.unstack()
print(stacked)

代码效果如下所示·:
在这里插入图片描述

concat

Pandas中的pd.concat与np.concatenate类似,但可选参数更多,功能更为强大。

pd.concat可以简单地合并一维的对象:

ser1 = pd.Series(['A', 'B', 'C'], index=[1, 2, 3])
ser2 = pd.Series(['D', 'E', 'F'], index=[4, 5, 6])
pd.concat([ser1, ser2])

多维数据合并:

df1 = make_df('AB', [1, 2])
df2 = make_df('AB', [3, 4])
display('df1', 'df2', 'pd.concat([df1, df2])')

concat函数的参数:

参数说明
objs参与连接pandas对象的列表或字典
axis连接指明的轴向
join指明其他轴向上的索引是按交集还是并集进行合并
join_axes指明用于其他n-1条轴向上的层次化索引。可以是任意值的列表或数组,元组数组,数组列表
levels指定用作层次化索引各级别上的索引 (如果设置外层索引)
names用于创建分层的名字
verify_integrity检查结果对象新轴上的重复情况
ignore_index不保留连接轴上的索引,产生一组新索引range(total_length)

numpy中concatenate和pd.concat的很像。
他俩的主要差异就在于pd.concat在合并时会保留索引,即使索引是重复的。但是pandas中也提供了检查重复索引和忽略索引的参数,见上表。
【代码实现】

#构造一个函数,方便后面表示
x = make_df('AB', [0, 1])
y = make_df('AB', [2, 3])
y.index = x.index # 复制索引
display('x', 'y', 'pd.concat([x, y])')
#捕捉索引重复
try:
    pd.concat([x, y], verify_integrity=True)
except ValueError as e:
    print("ValueError:", e)
#忽略索引
display('x', 'y', 'pd.concat([x, y], ignore_index=True)')
#增加多级索引
display('x', 'y', "pd.concat([x, y], keys=['x', 'y'])")

join

通过索引或者指定的列连接两个DataFrame,通过一个list可以一次高效的连接多个DataFrame。

DataFrame.join(other, on=None, how=’left’, lsuffix=, rsuffix=, sort=False)

相关参数

参数介绍
other【DataFrame,或者带有名字的Series,或者DataFrame的list】如果传递的是Series,那么其name属性应当是一个集合,并且该集合将会作为结果DataFrame的列名
on【列名称,或者列名称的list/tuple,或者类似形状的数组】连接的列,默认使用索引连接
how【{‘left’, ‘right’, ‘outer’, ‘inner’}, default: ‘left’】连接的方式,默认为左连接
lsuffix【string】左DataFrame中重复列的后缀
rsuffix【string】右DataFrame中重复列的后缀
sort【boolean, default False】按照字典顺序对结果在连接键上排序。如果为False,连接键的顺序取决于连接类型(关键字)。

小结:
DataFrame的join默认为左连接
DataFrame的join连接时,caller的关键列默认为index,可以使用参数on指定别的列为关键列,但是other的关键列永远都是index,所有使用别的列为关键列是,常常使用set_index()

append

append是series和dataframe的方法,使用它就是默认沿着列进行凭借(axis = 0,列对齐)

DataFrame.append(*other*, *ignore_index=False*, *verify_integrity=False*, *sort=None*)

相关参数:

参数介绍
other要添加的数据,可以是dataframe,dict,Seris,list等
ignore_index参数为True时将在数据合并后,按照0,1,2,3…的顺序重新设置索引,忽略了旧索引
verify_integrity参数为True时,如果合并的数据与原数据包含索引相同的行,将报错

需要注意的是与Python列表中的append()或extend()方法不同,Pandas的append()方法不会直接更新原有的值,而是创建一个新的对象,所以如果需要进行多个append操作,这样的效率就会比较低,建议先创建一个DataFrame列表,再用concat()进行合并。

merge

pd.merge()函数可实现可实现三种数据连接:一对一、多对一和多对多。
一对一连接

df1 = pd.DataFrame({'employee': ['Bob', 'Jake', 'Lisa', 'Sue'],
                    'group': ['Accounting', 'Engineering', 'Engineering', 'HR']})
df2 = pd.DataFrame({'employee': ['Lisa', 'Bob', 'Jake', 'Sue'],
                    'hire_date': [2004, 2008, 2012, 2014]})
display('df1', 'df2')
df3 = pd.merge(df1, df2)
df3

pd.merge()方法会发现两个数据集都包含了employee列,会自动以这列作为键进行合并。需要注意的是,pd.merge()会默认丢弃原来的行索引,不过也可以自定义。
多对一连接

df4 = pd.DataFrame({'group': ['Accounting', 'Engineering', 'HR'],
                    'supervisor': ['Carly', 'Guido', 'Steve']})
display('df3', 'df4', 'pd.merge(df3, df4)')

多对多连接

df5 = pd.DataFrame({'group': ['Accounting', 'Accounting',
                              'Engineering', 'Engineering', 'HR', 'HR'],
                    'skills': ['math', 'spreadsheets', 'coding', 'linux',
                               'spreadsheets', 'organization']})
display('df1', 'df5', "pd.merge(df1, df5)")

pd.merge()默认会将两个数据集的一个或多个共同的列作为键进行合并,但通常要合并的列不是同名的,所以pd.merge()也提供了一些参数来处理这个问题。
参数说明:

参数介绍
on这个参数只有在两个数据集有共同的列名才可使用,可将on参数设置为列名字符串或包含多个列名的列表
left_on ,right_on用left_on与right_on参数来指定列名
left_index right_index可以通过left_index和right_index参数将所有设置为键进行合并

实战部分:
准备工作:

import numpy as np
import pandas as pd
# 载入data文件中的:train-left-up.csv
df=pd.read_csv(r'.\data\train-left-up.csv')
df.head()

一、数据的合并
任务一:将data文件夹里面的所有数据都载入,观察数据的之间的关系

text_left_up = pd.read_csv("data/train-left-up.csv")
text_left_down = pd.read_csv("data/train-left-down.csv")
text_right_up = pd.read_csv("data/train-right-up.csv")
text_right_down = pd.read_csv("data/train-right-down.csv")

任务二:使用concat方法:将数据train-left-up.csv和train-right-up.csv横向合并为一张表,并保存这张表为result_up

list_up = [text_left_up,text_right_up]
result_up = pd.concat(list_up,axis=1)
result_up.head()

任务三:使用concat方法:将train-left-down和train-right-down横向合并为一张表,并保存这张表为result_down。然后将上边的result_up和result_down纵向合并为result。

list_down=[text_left_down,text_right_down]
result_down = pd.concat(list_down,axis=1)
result = pd.concat([result_up,result_down])
result.head()

任务四:使用DataFrame自带的方法join方法和append:完成任务二和任务三的任务

resul_up = text_left_up.join(text_right_up)
result_down = text_left_down.join(text_right_down)
result = result_up.append(result_down)
result.head()

任务五:使用Panads的merge方法和DataFrame的append方法:完成任务二和任务三的任务

result_up = pd.merge(text_left_up,text_right_up,left_index=True,right_index=True)
result_down = pd.merge(text_left_down,text_right_down,left_index=True,right_index=True)
result = resul_up.append(result_down)
result.head()

任务六:完成的数据保存为result.csv

result.to_csv('result.csv')

任务七:将我们的数据变为Series类型的数据

unit_result=text.stack().head(20)

groupby

groupby()用法:
根据DataFrame本身的某一列或多列内容进行分组聚合

  • 若按某一列聚合,则新DataFrame将根据某一列的内容分为不同的维度进行拆解,同时将同一维度的再进行聚合。
  • 若按某多列聚合,则新DataFrame将是多列之间维度的笛卡尔积,例如:“key1”列,有a和b两个维度,而“key2”有one和two两个维度,则按“key1”列和“key2”聚合之后,新DataFrame将有四个group;

注意:groupby默认是在axis=0上进行分组的,通过设置axis=1,也可以在其他任何轴上进行分组。
有关函数

函数适用场景
.mean()求均值
.count()计数
.min()最小值
.mean().unstack()求均值,聚合表的层次索引不堆叠
.size()计算分组大小

通过几个任务熟悉groupby
任务一:计算泰坦尼克号男性与女性的平均票价

df  = text['Fare'].groupby(text['Sex'])
means = df.mean()
means

任务二:统计泰坦尼克号中男女的存活人数

survived_sex = text['Survived'].groupby(text['Sex']).sum()
survived_sex.head()

任务三:计算客舱不同等级的存活人数

survived_pclass = text['Survived'].groupby(text['Pclass'])
survived_pclass.sum()

任务四:统计在不同等级的票中的不同年龄的船票花费的平均值

text.groupby(['Pclass','Age'])['Fare'].mean().head()

任务五:将任务二和任务三的数据合并

result = pd.merge(means,survived_sex,on='Sex')
result

任务六:得出不同年龄的总的存活人数,然后找出存活人数的最高的年龄,最后计算存活人数最高的存活率(存活人数/总人数)

#不同年龄的存活人数
survived_age = text['Survived'].groupby(text['Age']).sum()
survived_age.head()
#找出最大值的年龄段
survived_age[survived_age.values==survived_age.max()]
_sum = text['Survived'].sum()
print(_sum)
#首先计算总人数
_sum = text['Survived'].sum()

print("sum of person:"+str(_sum))

precetn =survived_age.max()/_sum

print("最大存活率:"+str(precetn))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值