Anacoda&Jupyter DAY 04 pandas合并补充&pandas数据处理
Anacoda&Jupyter DAY 04 重点知识总结pandas合并补充&pandas数据处理一 pandas合并之 pd.merge()merge()和concat()的区别在于 merge需要依据某一共同的行或者列来进行合并使用pd.merge()合并时 会自动根据两者相同的columns名称的那一列 作为key来进行合并 注意每一列的元素顺序不要求一致一般来说 最普通的
Anacoda&Jupyter DAY 04 重点知识总结 pandas合并补充&pandas数据处理
一 pandas合并之 pd.merge()
merge()和concat()的区别在于 merge需要依据某一共同的行或者列来进行合并
使用pd.merge()合并时 会自动根据两者相同的columns名称的那一列 作为key来进行合并 注意每一列的元素顺序不要求一致
-
一般来说 最普通的合并方式分为一对一合并 多对一合并 多对多合并
- 一对一合并 只有一列是有关联的 并且列索引的名字可以相同也可以不同
如果两边列索引名字相同 则使用:
pd.merge(df1,df2)
如果两边列索引名字不相同 则使用:
pd.merge(df1,df2,left_on = ‘name1’,right_on = ‘name2’)
这里就涉及到一个合并操作了 后面会讲述 - 多对一合并 或 多对多合并 多对一合并时出现两个表分别有一列有联系 但是值有重复 如果需要连接起来 连接方式和上面先攻 则会产生笛卡尔积
- 一对一合并 只有一列是有关联的 并且列索引的名字可以相同也可以不同
-
key的规范化
使用on = 显示指定那一列为key 这是在当有多个key相同的时候使用 说的清楚一些 比如由 name 和 id 两个表都有相应的列索引 并且有联系 我们如果使用这两个同时进行索引 必定只能匹配到name和id 都匹配的一模一样的部分 显然这是不合理的
一般来说我们在这种情况下会使用一种列索引进行合并 使用on = key 即可完成
pd.merge(df1,df2,on = ‘name’) -
内合并与外合并
- 内合并 : 只保留两者都有的key (默认模式)
如果两个表的列索引不一样长 行索引也不一样长 那么如果需要连接起来 会只保留匹配的部分 不匹配的部分将会不显示 - 外合并 : 都显示 how = ‘outer’
在这个方式下 保留的是所有的数据 就算两边长度不一样 无法匹配 那么将会以NaN的形式最后显示在表格中 - 外合并: how = ‘left’ 和 how = ‘right’ 左合并 右合并
这个有点像sql语句中的 left join 和 right join , 在外连接中 以其中的一个表格为参照 主要显示这个表格中的所有索引的项目 如果不匹配 则会使用NaN进行填充
- 内合并 : 只保留两者都有的key (默认模式)
-
列冲突的解决
当列冲突的时候 及有多个列的名称相同时 需要使用 on = 来指定哪个列作为key 并且配合suffixes指定冲突的命名 可以分别命名其后缀 用于分辨两组数中不同的列索引的内容
书写格式为
df1.merge(df2,on = ‘name’,suffixes = [’_df1’,’_df2’]) # 添加后缀
对suffixes的书写解释 :
suffixes : 2-length sequence (tuple, list, …) -
行索引的连接
刚刚使用的索引方法大多都是使用在列上的 如果时两个表中的行索引之间有联系 或者说 一个表的行索引和另一个表的列索引有联系并且需要进行连接 需要使用 left_index = True 或者 right_index = True 进行操作
比如df1的行索引’ item ’ 与 df2 中的列索引 ‘item1’ 有联系需要对这两个表通过此建立联系 可以使用该方法
df1.merge(df2,left_index = True,right_on = ‘items’) -
join() 方法
提一下join() 方法 该方法与merge方法类似 与concat的方法的区别就是 这个可以指定连接的列索引 与merge方式不一样的地方是表达的方式 (merge的表达方式为 suffixes 而join的表示方法为lsuffix 和 rsuffix)
通常我们可以使用merge方法那就使用merge方法 如果我们可以使用concat方法就少使用append方法 因为功能相似 而前者功能更全
二 pandas的数据处理
- 删除重复行
使用duplicated() 函数进行检测重复的行 返回的元素为bool类型(True or False) 每个元素对应一行 如果改行不是第一次出现 则返回的元素为 True (不要记反了!)
书写规则:
df1.duplicated() # 返回的是每一行对应bool类型 如果非第一次出现将会返回True-
keep
这样写默认从上向下进行查找 即从上向下的时候第一次出现的时候返回的是False 第二次出现的是True (检测重复的行在下方)
如果使用 keep = ‘last’ 则是从表的下方向上方进行查找 所以对应的是 重复的部分是在非重复的上面
如果使用 keep = False 则会将所有的有重复的所有项标为True 不论在上面还是下面 -
subset
如果我们只需要查找指定列的数据是否为重复数据的时候 我们可以使用subset设置查找的列 我需要查找的是列索引分别为A,B,C 列 那么在书写的时候需要写 subset = [‘A’,‘B’,‘C’]这里提一下 如何取反 比如 我返回的是True 我如何将其取反变为False 一般采用两种方法
- ~cond # (cond为变量) 使用’~'这个符号 相当于取反
- np.logical_not(cond) # 这里使用的是numpy的逻辑非属性取反
- 以上两种的返回结果是相同的
-
使用drop_duplicates() 函数删除重复的行
Return DataFrame with duplicate rows removed, optionally only considering certain columns
可以使用subset控制查重的行 subset的概况在上面有描述
-
- 映射
映射的含义 : 创建一个映射关系列表 把values元素和一个特定的标签或者字符串绑定
包含三种操作 :
replace() : 替换新元素
map() : 新建一列
rename() : 替换索引- replace函数 : 替换元素
使用replace函数 对values进行操作的格式是:
df.replace({3:99,45:200},inplace = True,limit = 2)- 第一个填写的是一个字典 字典中存储的数据
key = 目前的表中的某一个需要更改的数据 (如果该数据不出现在当前表内 也不会报错 但是不会修改目前数据的值) - inplace = True # 这里指的是是否需要替换当前的变量 默认inplace是为False的 如果inplace默认值 那么如果在后面的程序中使用这次修改后的表 需要使用一个新的变量来接收
- replace经常用来替换NaN元素 也可以将某个特定的值更改为NaN # 之前的文章中有些到另外一种方式处理NaN的 使用的方法为fillna 可以在之前的文章中详细查看
- limit 限制每一行最多更改多少次
- 我们需要该其中的数据其实有很多方法 比如之前提到的找到那个数的所有 并且使用赋值的方式对该数据进行处理 即可更改原来表格内的值 但是如果使用这种方法 可以一次性更改很多值 也不需要找到更改这个值的索引 所以总体来说是很方便的
- 第一个填写的是一个字典 字典中存储的数据
- map() 函数 新建一列
- 使用map函数 由已有的列中新建一个新列 适合处理某一个单独的列
df[‘python’] = df[‘Java’].map({64:100,20:103})
这行代码的意思是 使用Java的数据对python进行填充 填充的时候 需要更改数据 如 Java中的64数据将会更改为100 在python中体现出来 (如果不更改值 将会以NaN来显示) - map函数中可以使用lambda函数
df[‘等级’] = df[‘数学’].map(lambda x:‘优秀’ if x>=80 else ‘一般’) - 当然 如果是复杂的函数将可以在map中被调用
def fn():
pass
df[‘等级’] = df[‘数学’].map(fn)
- 使用map函数 由已有的列中新建一个新列 适合处理某一个单独的列
- rename() 函数 替换索引
该函数可以更改列索引和行索引的名字 格式如下
df.rename(index = {old_name:new_name})
df.rename(columns = {old_name:new_name})
- replace函数 : 替换元素
- 异常值的检测和过滤
- 异常值的检测和过滤的思路:
确定异常的检测标准
写成条件的形式 使用条件去过滤原始的数据
- 异常值的检测和过滤的思路:
# 创建表格
df = DataFrame(np.random.randn(10000,3))
df.head()
#
'''
0 1 2
0 0.463836 0.128646 -1.627846
1 0.443790 0.951944 1.213783
2 0.167262 0.179322 -0.691701
3 1.838812 -0.082356 -1.579476
4 2.051879 0.915174 -0.114157
'''
# 找到偏差大于三倍标准差的数
cond = df.abs() > 3 * df.std()
cond = cond.any(axis = 1)
cond.head()
'''
0 False
1 False
2 False
3 False
4 False
'''
# 过滤掉
df.loc[~cond]
- 抽样
- 使用take函数进行抽样
df.take([1,0,3,2]) # 对行进行排序
df.take([1,0,2,3],axis = 1) # 对列进行排序
中间的数字列表为索引
其实可以使用iloc方法 可以执行类似的操作 - 随机抽样的排序方式有两种
- 第一种类似于不放回排序 这种排序方法实际上就是打乱顺序 但是一定不会重复
可以使用 np.random.permutation([1,2,3,4])
返回一个乱序的列表
tips: random模块中也有一个随机打乱顺序的方法 random.shuffle() 这两种方法有不一样- 首先permutation是有返回值的 返回的是打乱后的列表 但是shuffle是没有返回值的(None)
- 一般来说shuffle传入的是列表的变量 直接打乱列表 而permutation 传入的是列表 返回的是乱序的列表
- 两者都是有打乱列表的功能 有细微的差别需要在实践中应用
- df2.take(np.random.permutation([0,1,2,3]))
- 随机抽样
这种抽样的方式类似于放回抽样 意思就是说在某个区间内随机取一个数 并且该数有可能会与之前抽到的值相同 这样取到的可能会出现重复
这是由放回的抽样 可能是重复的 :
df2.take(np.random.randint(0,4,size = 4))
- 第一种类似于不放回排序 这种排序方法实际上就是打乱顺序 但是一定不会重复
- 使用take函数进行抽样
- 数据聚合
数据聚合是数据处理的最后一步 通常要使每一个数组生成一个单一的数值- 数据分类处理:
分组: 先把数据按照某个索引分为几组 (groupby)
用函数进行处理 : 为不同组的数据应用不同的函数以进行转换数据
合并 : 把不同组得到的数据合并起来
数据分类处理的核心 : groupby() 函数
这个分组的思想和sql语句中的很像 我们这里分组的操作是使用一个行或者列的索引进行分组 使用该索引进行分组之后 分组的那个部分将会同类合并 数据将会按照按照后面指定的部分进行
tips: 这里再分组之后 我们在调用函数对数据进行处理之前我们无法看到分组后的表格 返回的值为一个object 我们在使用函数方法后 将会显示函数处理后的数据
关于分组思想这里就不多赘述了 sql语句的时候有详解
- 数据分类处理:
#
'''
item color weight price
0 萝卜 白 10 0.99
1 白菜 青 20 1.99
2 辣椒 红 30 2.99
3 冬瓜 白 40 3.99
4 萝卜 青 50 4.99
5 白菜 红 60 5.99
6 辣椒 白 70 6.99
7 冬瓜 青 80 7.99
'''
weight_sum = ddd.groupby(by = 'item')[['weight']].sum()
price_mean = ddd.groupby(by='item')[['price']].mean()
display(weight_sum,weight_sum.loc[['萝卜']],price_mean)
'''
weight
item
冬瓜 120
白菜 80
萝卜 60
辣椒 100
weight
item
萝卜 60
price
item
冬瓜 5.99
白菜 3.99
萝卜 2.99
辣椒 4.99
'''
ddd.groupby(by = 'item').sum()
'''
weight price
item
冬瓜 120 11.98
白菜 80 7.98
萝卜 60 5.98
辣椒 100 9.98
'''

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)