《Merge, join, and concatenate》笔记

PS默认情况下,所有合并函数生成文件的方式均是新生成,即不修改原DF/Series数据。


第一、常用的merge()函数、concat()函数:

常用merge()来添加新字段(即列),concat()来添加新记录(即行)

++++++++++ merge() ++++++++++

  • pandas.merge是pandas的全功能、高性能的的内存连接操作,在习惯上非常类似于SQL之类的关系数据库。
  • 相较于其他开源软件(如R中的base::merge.data.frame), pandas.merge的性能要好得多(在某些情况下好得多一个数量级)。其原因是在DataFrame中优化的算法设计和数据的内部布局。
DataFrame.merge(
right,                                    # 右DF,即要被merge的DataFrame
how='inner',                              # 取值有4个{‘left’, ‘right’, ‘outer’, ‘inner’}
on=None, left_on=None, right_on=None,     # 如果使用左&右DF的公共字段作为key,使用参数on;如果不使用左边右边的公共字段作为key,使用参数left_on和right_on。
left_index=False, right_index=False,      # 如果left_index=True,则left左边DF的index(即索引的列名称)是用来jion的keys。如果是MultiIndex,左DF和右DF的level数必须相等。right_index的作用与之相似。
sort=False,                               # 默认不对新合并表的结果按照字顺序排序,可以节省运算时间。
suffixes=('_x', '_y'),
copy=True,
indicator=False,                          # 如果True,会添加一列,显示数据的来源表名称。
Validate=None                             # 是否检查两个merge的DFkeys是一对一关系、一对多关系,返回布尔值( 'one_to_one'/ '1:1', 'one_to_many' / '1:m', 'many_to_one' / 'm:1')。默认情况下3种关系都可以,只是没有输出。
)

例子

  • merge两个DataFrame:
>>> A              >>> Blkey value         rkey value
0   foo  1         0   foo  5
1   bar  2         1   bar  6
2   baz  3         2   qux  7
3   foo  4         3   bar  8
>>> A.merge(B, left_on='lkey', right_on='rkey', how='outer')lkey  value_x  rkey  value_y
0  foo   1        foo   5
1  foo   4        foo   5
2  bar   2        bar   6
3  bar   2        bar   8
4  baz   3        NaN   NaN
5  NaN   NaN      qux   7
  • merge多个DataFrame与之类似,直接向后添加:
A.merge(B, right_on='col_r', left_on='col_l', how='outer').merge(C, right_on='col_r1', left_on='col_l1', how='outer')

注:

  • 截止到2019上半年,merge()函数仍然会合并左右表的NaN 和 None,详见 GH22491 和GH22618。
  • 假如要删除NaN 和 None,使用new_df.dropna(subset=['key_or_keys], inplace=True)
"""NaN是float,None是object,虽然都可以在numpy中运行、但是None会把numpy计算性能拉到底,NaN不会。"""
s_bad = pd.Series([1, None], dtype=object)
s_good = pd.Series([1, np.nan])

print(s_bad)
print(s_good)
# 结果如下:
0 1
1 None
dtype: object
0 1.0
1 NaN
dtype: float64

print(s_bad.dropna())
print(s_good.dropna())
# 结果如下
0 1
dtype: object
0 1.0
dtype: float64

print(s_bad.isnull())
print(s_good.isnull())
# 结果如下
0 False
1 True
dtype: bool
0 False
1 True
dtype: bool

++++++++++ concat() ++++++++++

  • 默认按照axis=0执行合并,即默认向df1添加行。
  • 如果df2有df1没有的列,也添加列。

concat()函数一边按照an axis执行所有的复杂合并命令,同时(如果有的话)按其他axes执行运算,还执行参数"join"的设定 innor | outer命令。注意,之所以说“如果有”,是因为Series只有一个axis。

pandas.concat(
objs,                       # 要纵向合并的DataFrame列表。append也有(4个共同参数)
axis=0,                     # axis只能取值0或者1
join='outer',               # join只能取值innor或outer
sort=None,                  # append()也有(共4个共同参数),即默认空白。可取值为False/True,从23.0版本开始,不输入取值的话会收到warning提示,之前的版本中默认sort只等于True。
gnore_index=False,         # append()也有(共4个共同参数)
# 以下参数不太常用
verify_integrity=False,    # append()也有(共4个共同参数)
join_axes=None, keys=None, levels=None, names=None,copy=True)
其他参数(一下不怎么用得到,浏览一下即可):
  • 多个DataFrame的话,多注意 “按axes(即第一个axis之外的axis/axes)的合并”,还有“设置更多条件的合并”(axisjoin进一步有sort操作,且未来的join不再默认执行sort=True,需要主动设置)、
  • join = innor/outer操作的是axis(它其实是实际意义上的index,如果你对该函数较熟悉的话)。
  • 搭配keys合并后的表,可以快速的提取数据,key的对象随axis的取值变化而改变。
  • ignore_index搭配axis:实现用递增的数字,作为新DF的字段名称;
  • 把参数index换成参数join_axes可以实现相当于SQL的left join功能,即只保左边表df1的index。例如result = pd.concat([df1, df4], axis=1, join_axes=[df1.index])


第二、join()函数、append()函数(他俩不常用,仅供了解)

++++++++++ append() ++++++++++
功能:简化版的concat()(实际上比concat诞生的早)。同样是用来处理Dataframe/Series。

DataFrame.append(
other,                       # 其他的对象(Series/DF)
sort=None,                   # 是否排序
ignore_index=False,          # 是否使用原index。取值True会用0,1,2……数字作为index
verify_integrity=False)

附注:一个Series合并到一个DataFrame
如果我们要把一个Series合并到一个DataFrame的话,用DataFrame.assign()可以得到相同的结果。
但是对于任意数量的DataFrame/Series对象,请使用concat()

  • concat()append()通用的:
    – 比如2个表的index一个是[i, ii, iii, iv],一个是[a, b, c, d],通过设定ignore_index=True,即用新的index[0, 1, 2, 3]来添加合并对象。
    -仅适用于 concat()的:
    ignore_index=True搭配axis=1(行名称变成了事实上的Column,列名称反而成了事实上的index),可以在合并结果中用数字序号作为列名称

  • 仅适用于append()的:
    – 直接把一个手写Series 的列 或者一个dict 的列集,合并到DataFrame 行的后边得到一个新的DF。虽然不是特别有效率(因为函数应用的对象Series/DF需要手工码出来)。
    — e.g. 手写Series类型数据,手写dict类型数据。其结果不容易理解,一般使用merge或者concat:

import pandas as pd

df1 = pd.DataFrame([5, 6, 7, 8], index=[‘A’, ‘B’, ‘C’, ‘Y’])
print(df1)

s2 = pd.Series([‘X0’, ‘X1’, ‘X2’, ‘X3’])
print(s2)

dicts = [{‘A’: 1, ‘B’: 2, ‘C’: 3, ‘X’: 4},
{‘A’: 5, ‘B’: 6, ‘C’: 7, ‘Y’: 8}]
print(dicts)

# 结果如下
0
A 5
B 6
C 7
Y 8

0 X0
1 X1
2 X2
3 X3
dtype: object

[{‘A’: 1, ‘B’: 2, ‘C’: 3, ‘X’: 4}, {‘A’: 5, ‘B’: 6, ‘C’: 7, ‘Y’: 8}]

result = df1.append(s2, ignore_index=True)
print(result)b = df1.append(dicts, ignore_index=True)
print(b) # 结果如下0    1    2    3
0   5  NaN  NaN  NaN
1   6  NaN  NaN  NaN
2   7  NaN  NaN  NaN
3   8  NaN  NaN  NaN
4  X0   X1   X2   X30    A    B    C    X    Y
0  5.0  NaN  NaN  NaN  NaN  NaN
1  6.0  NaN  NaN  NaN  NaN  NaN
2  7.0  NaN  NaN  NaN  NaN  NaN
3  8.0  NaN  NaN  NaN  NaN  NaN
4  NaN  1.0  2.0  3.0  4.0  NaN
5  NaN  5.0  6.0  7.0  NaN  8.0

++++++++++ JOIN() ++++++++++
它通过索引或者指定的列把来自其他DaraFrame的列添加到左DF上。
如果只按照索引进行join的话,可以迅速的同时jion多个DataFrame。

DataFrame.join(            # 如果第一个参数"other"传入的是"一个列表的DataFrame",参数"on", "lsuffix", "rsuffix"失效。
other,                     # 要jion的对象,可以是DataFrame、带有名称字段集合的Series、或者一个列表的DataFrame
on=None,                   # 指明join使用的column(s)。系统默认使用index。
how='left',                # 取值有4个{'left', 'right', 'outer', 'inner'}。默认值是'left'。
lsuffix='',
rsuffix='',
sort=False                  # 默认False,即保留左DF的排序。True则按join的列对生成的DF进行排序
)

例子:
new_df = left.join(right, on=key_or_keys)

  • 等价于 new_df = pd.merge(left, right, left_on=key_or_keys, right_index=True, how='left', sort=False)
  • 还等价于new_df = left.merge(right, on=key_or_keys, how='left')

附注: join和merge有什么异同?stackoverflow链接
- pandas.merge()是所有用来merge/join的底层函数。

DataFrame提供了pandas.DataFrame.merge()pandas.DataFrame.join()作为使用pandas.merge()的快捷方式。
例如df1.merge(right=df2, ...),也即pandas.merge(left=df1, right=df2, ...)

- 不同点:df.join()df.merge()主要有三处不同
  1. 左连接 VS 内连接:df1.join(df2)默认使用左连接 保留左表df1的所有行,但是df.merge(df1, df2)默认使用内连接 保留df1df2共有的行。
  2. 如果需要从右表拉数据的话:默认情况,df1.join(df2)只能用df2的index,但是df1.merge(df2)即可以用df2的单列/多列,也可以通过right_index=True使用df2的index;
  3. 如果需要从左表拉数据的话:代码df1.join(df2, on=key_or_keys)df1.merge(df2, left_index=True)。默认情况,df1.join(df2)使用df1的index,同样df1.merge(df2)用的是df2的(单列的/多列的)index,;
杂项(待查证续写):DataFrame.assign()和map()

两者都能按照行名称匹配出新的一列。

  • map()在知道所有映射关系后,能方便快捷的匹配映射数据。
  • 貌似有很多路径可以实现类似EXCEL的VLOOKUP功能。

pandas -表的横向合并 纵向合并相关推荐

  1. latex表格横向、纵向合并问题

    1.横向多列合并:\multicolumn{2}{c}{predicted value} (2是需要合并的列数,c是居中对齐) 2.纵向多行合并:\multirow{2}*{true value} ( ...

  2. html td 的横向与纵向合并

    colspan是横向合并:rowspan是纵向合并. 如 <td class="subject" colspan="2">回复觉得很分阶段方< ...

  3. mysql 横向分表_mysql横向和纵向的数据库分表

    分表是分散数据库压力的好方法. 分表,最直白的意思,就是将一个表结构分为多个表,然后,可以再同一个库里,也可以放到不同的库. 当然,首先要知道什么情况下,才需要分表.个人觉得单表记录条数达到百万到千万 ...

  4. html导出excel合并单元格,JS导出EXCEL,动态设置单元格格式,合并单元格(横向或纵向)等操作...

    参考链接: https://blog.csdn.net/weixin_33724046/article/details/89611397 https://www.cnblogs.com/lvsk/p/ ...

  5. css 纵向合并_excel只能合并横向单元格

    excel怎么将横向和纵向合并在一个单元格 在B2单元格输入以下公式,然后向右向下填充公式 =B$1&$A2 详见附图示例 excel在有合并单元格的表怎么只选一列? 就是表格顶部有合并单元格 ...

  6. JAVA导出Excel通用工具类——第一篇:详细介绍POI 导出excel的多种复杂情况,包括动态设置筛选、动态合并横向(纵向)单元格等多种复杂情况——保姆级别,真的不能再详细了,代码拿来即用)

    JAVA导出Excel通用工具--第一篇:详细介绍POI 导出excel的多种复杂情况,包括动态设置筛选.动态合并横向(纵向)单元格等多种复杂情况--保姆级别,真的不能再详细了,封装通用工具类,代码拿 ...

  7. R语言dplyr包使用bind_rows函数纵向合并两个dataframe(行生长)、使用bind_cols函数横向合并两个dataframe(列生长)

    R语言dplyr包使用bind_rows函数纵向合并两个dataframe(行生长).使用bind_cols函数横向合并两个dataframe(列生长) 目录

  8. pandas使用pd.concat纵向合并多个dataframe实战:纵向合并(ignore_index参数)、为纵向合并的多个dataframe设置标识符指定数据来源(通过字典方式设置数据来源键)

    pandas使用pd.concat纵向合并多个dataframe实战:多个dataframe的纵向合并(ignore_index参数).为纵向合并的多个dataframe设置标识符指定数据来源(通过字 ...

  9. pandas使用pd.concat纵向合并多个dataframe实战:多个dataframe的纵向合并、为纵向合并的多个dataframe设置标识符指定数据来源

    pandas使用pd.concat纵向合并多个dataframe实战:多个dataframe的纵向合并.为纵向合并的多个dataframe设置标识符指定数据来源 目录

最新文章

  1. IDEA统一设置编码为utf-8编码及tomcat 乱码问题的解决
  2. vc项目中加载多个lib遇到的问题
  3. 通向架构师的道路(第七天)之漫谈使用ThreadLocal改进你的层次的划分
  4. vivo手机解锁工具_点燃解锁的多一份激情,vivo NEX双屏版解锁体验报告
  5. 牛客网--19校招--获得最多的奖金
  6. 《纲要》落地,东方通教你挖数据金矿
  7. 【英语学习】【Daily English】U14 Transportation L04 I'm going to go screen
  8. 1191 消灭兔子(贪心+优先队列)
  9. 正则表达式 详解---2017-04-16
  10. 戴尔BIOS 爆多个高危漏洞,影响Inspiron 等数百万系统
  11. myeclipse编程技巧--中编辑器输入任何字母都出现提示功能
  12. php异步学习(2)
  13. python心脏线绘制代码_JavaScript图形实例:曲线方程
  14. Jeecg Boot 2.2.1 版本发布,基于SpringBoot的低代码平台
  15. Java八大基础数据类型转换
  16. AD18原理图到PCB流程
  17. 5个最佳网络安全监控工具、 你知道哪些
  18. 招商银行网络科技笔试
  19. 荒野乱斗好友系统分析
  20. 瑞萨e2studio(6)----编译调试

热门文章

  1. pyhon 数据类型转换函数
  2. MAPREDUCE实践篇(2)
  3. 深入探索JVM自动资源管理
  4. [转]启动Tomcat提示:指定的服务未安装
  5. Vi/Vim查找替换使用方法
  6. 图像热点(图像地图)
  7. 更改Webshpere的profile端口及删除profile
  8. 下面首先来看GCD的使用
  9. edittext 监听无效_Android中EditText 设置 imeOptions 无效问题的解决方法
  10. PyTorch 实现孪生网络识别面部相似度