1.拼接
有两个DataFrame,都存储了用户的一些信息,现在要拼接起来,组成一个DataFrame,如何实现呢?
import pandas as pd
import numpy as np
data1 = {
"name": ["Tom", "Bob"],
"age": [18, 30],
"city": ["Bei Jing ", "Shang Hai "]
}
df1 = pd.DataFrame(data=data1)
print(df1)
# name age city
# 0 Tom 18 Bei Jing
# 1 Bob 30 Shang Hai
data2 = {
"name": ["Mary", "James"],
"age": [35, 18],
"city": ["Guang Zhou", "Shen Zhen"]
}
df2 = pd.DataFrame(data=data2)
print(df2)
# name age city
# 0 Mary 35 Guang Zhou
# 1 James 18 Shen Zhen
append
append 是最简单的拼接两个DataFrame的方法。
拼接后的索引默认还是原有的索引,如果想要重新生成索引的话,设置参数 ignore_index=True 即可。
df = df1.append(df2)
print(df)
# name age city
# 0 Tom 18 Bei Jing
# 1 Bob 30 Shang Hai
# 0 Mary 35 Guang Zhou
# 1 James 18 Shen Zhen
df = df1.append(df2,ignore_index=True)
print(df)
# name age city
# 0 Tom 18 Bei Jing
# 1 Bob 30 Shang Hai
# 2 Mary 35 Guang Zhou
# 3 James 18 Shen Zhen
concat
除了 append 这种方式之外,还有 concat 这种方式可以实现相同的功能。
concat可以实现多个对象的拼接
df = pd.concat([df1,df2],ignore_index=True)
print(df)
# name age city
# 0 Tom 18 Bei Jing
# 1 Bob 30 Shang Hai
# 2 Mary 35 Guang Zhou
# 3 James 18 Shen Zhen
如果想要区分出不同的DataFrame的数据,可以通过设置参数 keys,当然得设置参数 ignore_index=False。
df = pd.concat([df1,df2], ignore_index=False, keys=["df1", "df2"])
print(df)
# name age city
# df1 0 Tom 18 Bei Jing
# 1 Bob 30 Shang Hai
# df2 0 Mary 35 Guang Zhou
# 1 James 18 Shen Zhen
2.关联
有两个DataFrame,分别存储了用户的部分信息,现在需要将用户的这些信息关联起来,如何实现呢?
import pandas as pd
import numpy as np
data1 = {
"name": ["Tom", "Bob", "Mary", "James"],
"age": [18, 30, 35, 18],
"city": ["Bei Jing ", "Shang Hai ", "Guang Zhou", "Shen Zhen"]
}
df1 = pd.DataFrame(data=data1)
print(df1)
# name age city
# 0 Tom 18 Bei Jing
# 1 Bob 30 Shang Hai
# 2 Mary 35 Guang Zhou
# 3 James 18 Shen Zhen
data2 = {"name": ["Bob", "Mary", "James", "Andy"],
"sex": ["male", "female", "male", np.nan],
"income": [8000, 8000, 4000, 6000]
}
df2 = pd.DataFrame(data=data2)
print(df2)
# name sex income
# 0 Bob male 8000
# 1 Mary female 8000
# 2 James male 4000
# 3 Andy NaN 6000
1.merge
通过 pd.merge 可以关联两个DataFrame,这里我们设置参数 on="name",表示依据 name来作为关联键。
默认使用内连接
c = pd.merge(df1,df2,on='name')
print(c)
# name age city sex income
# 0 Bob 30 Shang Hai male 8000
# 1 Mary 35 Guang Zhou female 8000
# 2 James 18 Shen Zhen male 4000
关联后发现数据变少了,只有 3 行数据,这是因为默认关联的方式是 inner,如果不想丢失任何数据,可以设
置参数 how="outer"。
外连接:
c = pd.merge(df1,df2,on='name',how='outer')
print(c)
# name age city sex income
# 0 Tom 18.0 Bei Jing NaN NaN
# 1 Bob 30.0 Shang Hai male 8000.0
# 2 Mary 35.0 Guang Zhou female 8000.0
# 3 James 18.0 Shen Zhen male 4000.0
# 4 Andy NaN NaN NaN 6000.0
可以看到,设置参数 how="outer" 后,确实不会丢失任何数据,他会在不存在的地方填为缺失值。
如果我们想保留左边所有的数据,可以设置参数 how="left";反之,如果想保留右边的所有数据,可以设置参数 how="right"
c = pd.merge(df1,df2,on='name',how='left')
print(c)
# name age city sex income
# 0 Tom 18 Bei Jing NaN NaN
# 1 Bob 30 Shang Hai male 8000.0
# 2 Mary 35 Guang Zhou female 8000.0
# 3 James 18 Shen Zhen male 4000.0
- 内连接:左右两个数据集中取交集的数据为结果。连接不上的数据全部舍弃。
- 左连接:以左边的数据为主,左边数据的每一项都必须在结果中出现,对于左连接来说,左数据中数据项与右表中连接不上,则设为NaN,右表中连接不上的数据直接舍去。
- 右连接:与左连接相反。
- 全连接:所有数据都要在结果中出现,有数据缺失时,以NaN填充。
主键名
使用pd.merge时,连接时是根据on参数值进行来连接的,那么要保证连接的两个对象中的列名相同,所以有时需要设置左右对象的列名进行连接。
1.首先修改两个对象的name列的列名
df1.rename(columns={'name':'name1'},inplace=True)
print(df1)
# name1 age city
# 0 Tom 18 Bei Jing
# 1 Bob 30 Shang Hai
# 2 Mary 35 Guang Zhou
# 3 James 18 Shen Zhen
df2.rename(columns={'name':'name2'},inplace=True)
print(df2)
# name2 sex income
# 0 Bob male 8000
# 1 Mary female 8000
# 2 James male 4000
# 3 Andy NaN 6000
到这里这两个DataFrame对象的name列的列明就不一样了---nam1和name2
2.连接
在pd.merge()可以通过参数: left_on 和 right_on 来分别设置。
df = pd.merge(df1,df2,left_on='name1',right_on='name2',how='outer')
print(df)
# name1 age city name2 sex income
# 0 Tom 18.0 Bei Jing NaN NaN NaN
# 1 Bob 30.0 Shang Hai Bob male 8000.0
# 2 Mary 35.0 Guang Zhou Mary female 8000.0
# 3 James 18.0 Shen Zhen James male 4000.0
# 4 NaN NaN NaN Andy NaN 6000.0
相同名称字段处理
有时候,两个DataFrame中都包含相同名称的字段,如何处理呢?
例如:
print(df1)
# name age city
# 0 Tom 18 Bei Jing
# 1 Bob 30 Shang Hai
# 2 Mary 35 Guang Zhou
# 3 James 18 Shen Zhen
print(df2)
# name sex income
# 0 Bob male 8000
# 1 Mary female 8000
# 2 James male 4000
# 3 Andy NaN 6000
df1['sex'] = 'male'
print(df1)
# name1 age city sex
# 0 Tom 18 Bei Jing male
# 1 Bob 30 Shang Hai male
# 2 Mary 35 Guang Zhou male
# 3 James 18 Shen Zhen male
这是df1和df2有一个相同的字段名sex,如果关联的话会不会冲突呢?
我们可以设置参数 suffixes,默认 suffixes=('_x', '_y') 表示将相同名称的左边的DataFrame的字段名加上后缀 _x,右边加上后缀 _y。也就是说就算不写该参数,遇到相同字段关联时,也会区分开来。
df = pd.merge(df1, df2, left_on="name1", right_on="name2")
print(df)
# name1 age city sex_x name2 sex_y income
# 0 Bob 30 Shang Hai male Bob male 8000
# 1 Mary 35 Guang Zhou male Mary female 8000
# 2 James 18 Shen Zhen male James male 4000
df = pd.merge(df1, df2, left_on="name1", right_on="name2", suffixes=("_left", "_right"))
print(df)
# name1 age city sex_left name2 sex_right income
# 0 Bob 30 Shang Hai male Bob male 8000
# 1 Mary 35 Guang Zhou male Mary female 8000
# 2 James 18 Shen Zhen male James male 4000
我们还可以重写该参数值,设置为自己可以区分的字符串---suffixes=("_left", "_right")。
2.join
除了 merge 这种方式外,还可以通过 join 这种方式实现关联。
相比 merge,join 这种方式有以下几个不同:
- 默认参数on=None,表示关联时使用左边和右边的索引作为键。
- 设置参数on可以指定的是关联时左边的所用到的键名。
- 左边和右边字段名称重复时,通过设置参数 lsuffix 和 rsuffix 来解决。
实例:
print(df1)
# name1 age city sex
# 0 Tom 18 Bei Jing male
# 1 Bob 30 Shang Hai male
# 2 Mary 35 Guang Zhou male
# 3 James 18 Shen Zhen male
print(df2)
# name2 sex income
# 0 Bob male 8000
# 1 Mary female 8000
# 2 James male 4000
# 3 Andy NaN 6000
df2.set_index('name2',inplace=True)
print(df2)
# sex income
# name2
# Bob male 8000
# Mary female 8000
# James male 4000
# Andy NaN 6000
df = df1.join(df2,on='name1',lsuffix='_left',rsuffix='_right')
print(df)
# name1 age city sex_left sex_right income
# 0 Tom 18 Bei Jing male NaN NaN
# 1 Bob 30 Shang Hai male male 8000.0
# 2 Mary 35 Guang Zhou male female 8000.0
# 3 James 18 Shen Zhen male male 4000.0
- df1.join():默认为df1为主数据集,类似于左连接。
- 参数中df2为右数据集,on参数指定df1中的连接主键,与df2中的索引列进行连接。
- lsuffix='_left',rsuffix='_right':指定遇到相同字段关联后数据列的名称。