2020-08-09--Pandas-10--转换拼接

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':指定遇到相同字段关联后数据列的名称。

你可能感兴趣的:(2020-08-09--Pandas-10--转换拼接)