import numpy as np
from pandas import DataFrame, Series
import pandas as pd
'''
pandas的拼接分为两种:级联:pd.concat,pd.append;合并:pd.merge,pd.join
'''
'''0回顾numpy的级联
练习:1.生成2个3*3的矩阵,对其分别进行两个维度上的级联
'''
nd = np.random.randint(0, 10, size=(3, 3))
print(nd)
con_np = np.concatenate((nd, nd), axis=0) # 0是第一维的方向
print(con_np)
con_np_col = np.concatenate((nd, nd), axis=1) # 1代表列,传递参数时,用()或者[]效果一样
print(con_np_col)
'''
定义一个生成DataFrame的函数
'''
def make_df(cols, ind):
data = {c: [c + str(i) for i in ind] for c in cols}
return DataFrame(data, index=ind, columns=cols)
result = make_df(["A", "B"], [1, 2])
print(result)
'''1.使用pd.concat()级联
pandas使用pd.concat函数,与np.concatenate函数类似,只是多了一些参数:
pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,
keys=None, levels=None, names=None, verify_integrity=False,
copy=True)
'''
# 1)简单级联 和np.concatenate一样,优先增加行数(默认axis=0)
df1 = make_df(list("AB"), [0, 1])
df2 = make_df(list("AB"), [2, 3])
print(pd.concat([df1, df2]))
# 可以通过设置axis来改变级联的方向
print(pd.concat((df1, df2), axis=1))
# 注意:index在级联时可以重复 列名不建议相同,列名表示属性
df3 = make_df(list("AB"), [0, 1, 2])
df4 = make_df(list("AB"), [1, 2, 3])
df5 = pd.concat((df3, df4))
print(df5)
print(df5.loc[[1, 2]])
# 也可以选择忽略ignore_index,重新索引
print(pd.concat([df3, df4], ignore_index=True))
# 或者使用多层索引keys concat([x,y],keys=["x","y"])
x = make_df(list("XY"), ["a", "b"])
y = make_df(list("XY"), ["A", "B"])
# keys可以使我们合并之后的数据更加的清晰
print(pd.concat([x, y], keys=["x", "y"]))
'''2)不匹配级联 不匹配指的是级联的索引不一致。例如纵向级联时列索引不一致,横向级联时行索引不一致
有三种连接方式:
外连接:补NaN(默认模式)
内连接:只连接匹配的项
连接指定轴join_axes'''
# 外连接:补NaN(默认模式)
df6 = make_df(list("CD"), [1, 3])
df7 = make_df(list("DE"), [2, 4])
print(pd.concat((df6, df7)))
# 内连接:只连接匹配的项
print(pd.concat((df6, df7), join="inner"))
# 连接指定轴join_axes
df8 = make_df(list("ACD"), [0, 1, 2])
df9 = make_df(list("CDF"), [3, 4, 5])
# join_axes以某一个DataFrame列索引为新的列索引值
print(pd.concat([df8, df9], join_axes=[df8.columns]))
'''3)使用append()函数添加
由于在后面级联的使用非常普遍,因此有一个函数append专门用于在后面添加'''
df10 = make_df(["大众", "福克斯"], [0, 1, 2, 3, 4])
df11 = make_df(["大众", "福克斯"], [5, 6, 7, 8, 9])
print(df10.append(df11)) # append方法更加灵活、方便
# concat方法属于pandas append方法就被放到DataFrame中
'''
2.使用pd.merge()合并
merge与concat的区别在于:merge需要依据某一共同的行或列来进行合并
使用pd.merge()合并时,会自动根据两者相同column名称的那一列,作为key来进行合并。
注意:每一列元素的顺序不要求一致
'''
# 1)一对一合并
df12 = DataFrame({"employee": ["张三", "李四", "王五"],
"group": ["sale", "counting", "marketing"]})
df13 = DataFrame({"employee": ["张三", "李四", "王五"],
"work_time": [2, 3, 5]})
print(pd.merge(df12, df13))
# print(pd.concat([df12, df13], axis=1)) 无法达到融合的效果
# 2)多对一合并
df14 = DataFrame({"employee": ["张三", "李四", "王五"],
"group": ["sale", "counting", "marketing"]})
df15 = DataFrame({"employee": ["张三", "张三", "王五"],
"work_time": [2, 3, 5]})
print(pd.merge(df14, df15))
# 3)多对多合并
df16 = DataFrame({"employee": ["张三", "张三", "王五"],
"group": ["sale", "counting", "marketing"]})
df17 = DataFrame({"employee": ["张三", "张三", "王五"],
"work_time": [2, 3, 5]})
# 在进行多对多合并时,每一个数据都没有放过
print(pd.merge(df16, df17))
# 4)key的规范化 使用on=显式指定哪一列为key,当有多个key相同时使用
df18 = DataFrame({"employee": ["小张", "小赵", "小李"], "group": ["sale", "marketing", "search"],
"salary": [12000, 10000, 80000]})
df19 = DataFrame({"employee": ["小张", "小吕", "小李"], "group": ["marketing", "marketing", "search"],
"work_time": [5, 2, 3]})
print(pd.merge(df18, df19))
# 只要employee相同,则进行合并
print(pd.merge(df18, df19, on="employee"))
print(pd.merge(df18, df19, on="group", suffixes=["_A", "_B"]))
# 使用left_on和right_on指定左右两边的列作为key,当左右两边的key都不相等时使用
df20 = DataFrame({"employer": ["小张", "小赵", "小李"], "team": ["sale", "marketing", "search"],
"salary": [12000, 10000, 80000]})
df21 = DataFrame({"employee": ["小张", "小吕", "小李"], "group": ["marketing", "marketing", "search"],
"work_time": [5, 2, 3]})
# 参数一为左,参数二为右
print(pd.merge(df20, df21, left_on="employer", right_on="employee"))
print(pd.merge(df20, df21, left_on="team", right_on="group"))
# 5)内合并与外合并
# 内合并:只保留两者都有的key(默认模式)
df22 = DataFrame({"name": ["小李", "小赵", "小张"], "age": [18, 20, 22]})
df23 = DataFrame({"name": ["小李", "小吕", "小张"], "height": [176, 178, 180]})
print(pd.merge(df22, df23))
# 外合并how='outer':补NaN
print(pd.merge(df22, df23, how="outer"))
# 左合并、右合并:how='left',how='right'
print(pd.merge(df22, df23, how="left"))
print(pd.merge(df22, df23, how="right"))
'''6)列冲突的解决 当列冲突时,即有多个列名称相同时,需要使用on=来指定哪一个列作为key,
配合suffixes指定冲突列名,可以使用suffixes=自己指定后缀
'''
df24 = DataFrame({"employer": ["小张", "小赵", "小李"], "team": ["sale", "marketing", "search"],
"salary": [12000, 10000, 80000]})
df25 = DataFrame({"employee": ["小张", "小吕", "小李"], "group": ["marketing", "marketing", "search"],
"work_time": [5, 2, 3]})
df24.columns = ["employee", "group", "salary"]
print(pd.merge(df24, df25, on="employee", suffixes=["_A", "_B"])) # suffixes指定后缀