1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > pandas -表的横向合并 纵向合并

pandas -表的横向合并 纵向合并

时间:2020-12-29 20:33:42

相关推荐

pandas -表的横向合并 纵向合并

《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的DataFramehow='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 value0 foo 1 0 foo 51 bar 2 1 bar 62 baz 3 2 qux 73 foo 4 3 bar 8

>>> A.merge(B, left_on='lkey', right_on='rkey', how='outer')lkey value_x rkey value_y0 foo 1 foo 51 foo 4 foo 52 bar 2 bar 63 bar 2 bar 84 baz 3 NaN NaN5 NaN NaNqux 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')

注:

截止到上半年,merge()函数仍然会合并左右表的NaNNone,详见 GH22491 和GH22618。假如要删除NaNNone,使用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或者1join='outer',# join只能取值innor或outersort=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……数字作为indexverify_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 30 5 NaN NaN NaN1 6 NaN NaN NaN2 7 NaN NaN NaN3 8 NaN NaN NaN4 X0 X1 X2 X30 A B C X Y0 5.0 NaN NaN NaN NaN NaN1 6.0 NaN NaN NaN NaN NaN2 7.0 NaN NaN NaN NaN NaN3 8.0 NaN NaN NaN NaN NaN4 NaN 1.0 2.0 3.0 4.0 NaN5 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、或者一个列表的DataFrameon=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()主要有三处不同
左连接 VS 内连接:df1.join(df2)默认使用左连接 保留左表df1的所有行,但是df.merge(df1, df2)默认使用内连接 保留df1df2共有的行。如果需要从右表拉数据的话:默认情况,df1.join(df2)只能用df2的index,但是df1.merge(df2)即可以用df2的单列/多列,也可以通过right_index=True使用df2的index;如果需要从左表拉数据的话:代码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功能。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。