本节目标:学会多个数据表的合并
本节技术点:join,melt,merge,compare
本节阅读需要(20)min。
本节实操需要(20)min。
这一节的内容是数据表之间的操作.因为客观上很多的数据表是相互关联的.
比如收入工资的表单和各种绩效的表肯定是挂钩的.
所以我们需要根据某个共有的特性,连接两个表的内容.
比如说根据名字,通过绩效表去计算工资!!!
import pandas as pd
import io
csv = '''
breed,size,kids,longevity,price
Beagle,small,high,12.3,288.0
Samoyed,medium,high,12.44,1162.0
Golden Retriever,medium,high,12.04,958.0
Yorkshire Terrier,small,low,12.6,1057.0
Boxer,medium,high,8.81,700.0
Dachshund,small,low,12.63,423.0
'''
ppl = pd.DataFrame({'name': ['Sam', 'Tina', 'Jeff', 'Kirsten'],
'likes': ['Samoyed', 'Dachshund', 'Beagle', 'Golden Retriever']})
ppl = ppl.set_index('likes') # 将某一列设为行标
dogs = pd.read_csv(io.StringIO(csv), index_col='breed')['price']
ppl.join(dogs)
DataFrame.join(other, on=None, how=’left’, lsuffix=”, rsuffix=”, sort=False)
on:【列名称,或者列名称的list/tuple,或者类似形状的数组】连接的列,默认使用行索引连接
how:【{‘left’, ‘right’, ‘outer’, ‘inner’}, default: ‘left’】连接的方式,默认为左连接
连接方式本质是集合概念. left是按照左边的index,右边的多余的删除,没有的补齐.
其他几个类似,outer是index取交集.inner取的是并集.
sort:【boolean, default False】按照字典顺序对结果在连接键上排序。如果为False,顺序就是连接方式默认的.
lsuffix:【string】左DataFrame中重复列的后缀
rsuffix:【string】右DataFrame中重复列的后缀
这个一般用不到,是为了防止合并的时候列重名所以一般添加后缀,其实在合并之前就需要单独处理添加前缀或后缀了.
注意:
join的结果还是df所以join可以串联一次合并多个数据表
pd.merge(left, right, how=‘inner’, on=None, left_on=None, right_on=None,left_index=False, right_index=False, sort=True,suffixes=(‘_x’, ‘_y’), copy=True)
on 指定用于连接的键(即列标签的名字),该键必须同时存在于左右两个 DataFrame 中,如果没有指定,并且其他参数也未指定, 那么将会以两个 DataFrame 的列名交集做为连接键
left_on,right_on用于指定合并用的键.尤其是名称不一致,但意义一致的情形.
但是其实应该读入时候就预处理成一样的!!!
suffixes 字符串组成的元组。当左右 DataFrame 存在相同列名时,通过该参数可以在相同的列名后附加后缀名,默认为(‘_x’,‘_y’)。
要执行的合并类型,从 {‘left’, ‘right’, ‘outer’, ‘inner’} 中取值,默认为“inner”内连接。
默认merge之后是产生新的df. 所以copy=True
import pandas as pd
left = pd.DataFrame({
'id':[1,2,3,4],
'Name': ['Smith', 'Maiki', 'Hunter', 'Hilen'],
'subject_id':['sub1','sub2','sub4','sub6']})
right = pd.DataFrame({
'id':[1,2,3,4],
'Name': ['William', 'Albert', 'Tony', 'Allen'],
'subject_id':['sub2','sub4','sub3','sub6']})
#通过on参数指定合并的键
print(pd.merge(left,right,on='id'))
Pandas 通过 concat() 函数能够轻松地将 Series 与 DataFrame 对象组合在一起
pd.concat(objs,axis=0,join=‘outer’,join_axes=None,ignore_index=False)
用到的比较多的是同样类型的表型数据串联。比如每个班的学习成绩合并成整个年级的学习成绩,
然后去做各种处理等等。
import pandas as pd
a= pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3'],
'C': ['C0', 'C1', 'C2', 'C3'],
'D': ['D0', 'D1', 'D2', 'D3']},
index=[0, 1, 2, 3])
b= pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],
'B': ['B4', 'B5', 'B6', 'B7'],
'C': ['C4', 'C5', 'C6', 'C7'],
'D': ['D1', 'D2', 'D5', 'D6']},
index=[2,3,4,5])
#连接a与b,设置 ignore_index 等于 True
print(pd.concat([a,b],keys=['x','y'],ignore_index=True))
A B C D
0 A0 B0 C0 D0
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
4 A4 B4 C4 D1
5 A5 B5 C5 D2
6 A6 B6 C6 D5
7 A7 B7 C7 D6
concat往往是有意义的。下面的虽然也行但是意义不大。。。
print(pd.concat([a,b],axis=1)) # 在列上拼接会出现大量的NA值
#沿着 axis=0,使用 apppend()方法连接a与b
print(a.append(b))
append重载过很方便,可以一次链接好几个。a.append(b,c,a)
相当于找不同
df = pd.DataFrame(
{
"col1": ["a", "a", "b", "b", "a"],
"col2": [1.0, 2.0, 3.0, np.nan, 5.0],
"col3": [1.0, 2.0, 3.0, 4.0, 5.0],
},
columns=["col1", "col2", "col3"],
)
df2 = df.copy()
df2.loc[0, "col1"] = "c"
df2.loc[2, "col3"] = 4.0
df.compare(df2)
col1 col3
self other self other
0 a c NaN NaN
2 NaN NaN 3.0 4.0
完全一样的行和列是不会显示的。存在差异行列才会显示并且显示前后两个的值。如果是一样的用NaN
不同的用具体的值展现不同
有过SQL经验的人应该知道,键值很可能不唯一是不是?
result = pd.merge(left, right, on="B", how="outer", validate="one_to_one")
pd.merge(left, right, on="B", how="outer", validate="one_to_many")
其实是相当于增加了一层约束。
merge和join其实就是形式上不一样,功能上是一致的。
但是需要注意join默认左链接,很多人喜欢这个书写方式。
merge则默认inner方式,这一点差异很重要!!!
merge的on可是以一个集合或列表含有多个列名作为键值,前提是这些列在两个df里面都存在。
又因为merge是inner,所以这种情况得到的df规模必然大量缩减,可以用来查找特殊元素。
官网合并教程