快乐学习
前程无忧、中华英才非你莫属!

原创-Pandas心法之数据连接&合并-5

前言

Pandas 下半部分内容,来了。这些示例整合了一下,直接贴上,没怎么分类,因为比较懒

但是内容,肯定是很精华,并配上了中文的注释,并且每行代码,都经过小编的运行和验证。含金量还是非常之高。

示例代码的主要内容有、数据的合并concat、merge 这两个函数,如果你有大量的Excel, 数据库表的复杂链接查询的时候,发现SQL 很慢的时候,可以试试merge函数。

还有分组和汇总,当我们的数据有很多突出的特征,我们就可以进行分类统计和描述。
分类统计和描述,就用到了分组函数 gruopby,结合aggregate和聚合函数max,min等就可以了。

还有更为简洁高级点的分组统计功能,那就是透视表pivot_table

还有字符串处理函数,以及时间字段的处理


import numpy as np
import pandas as pd

# 将Series 和DataFrame与pd.concat函数连接在一起
from datetime import datetime

def make_df(cols, ind):
    """Quickly make a DataFrame"""
    data = {c: [str(c) + str(i) for i in ind]
            for c in cols}

    return pd.DataFrame(data, ind)

# example DataFrame
md = make_df('ABC', range(3))
# print(md)

# numpy数组的串联
x = [1, 2, 3]
y = [4, 5, 6]
z = [7, 8, 9]
xyz = np.concatenate([x, y, z])
# print(xyz)

# 设置轴来设定串联的方向
x = [[1, 2],
     [3, 4]]
xx = np.concatenate([x, x], axis=1)  # 1 是x轴方向
# print(xx)

# pd.concat()可以用于Series或DataFrame对象的简单串联
ser1 = pd.Series(['A', 'B', 'C'], index=[1, 2, 3])
ser2 = pd.Series(['D', 'E', 'F'], index=[4, 5, 6])
ser = pd.concat([ser1, ser2])
# print(ser)

df1 = make_df('AB', [1, 2])
df2 = make_df('AB', [3, 4])

df = pd.concat([df1, df2])
# print('这是concat的df',df)

df3 = make_df('AB', [0, 1])
df4 = make_df('CD', [0, 1])

dfs = pd.concat([df3, df4], axis=1)
# print(dfs)

# 重复索引
x = make_df('AB', [0, 1])
y = make_df('AB', [2, 3])
y.index = x.index  # make duplicate indices!

xys = pd.concat([x, y])
# print(xys)

# 给两个DF数据分别在左侧X轴,添加多层索引
xyk = pd.concat([x, y], keys=['x', 'y'])
# print(xyk)

# 串联部分索引不同,出现NaN
df5 = make_df('ABC', [1, 2])
df6 = make_df('BCD', [3, 4])
# 解决办法,使用join 函数内连接,把索引相同部分进行关联
# 其他不关联的索引A,D舍去。可以理解为sql 的内连接
dfn = pd.concat([df5, df6], join='inner')
# print(dfn)

# 可以理解为sql 的左链接,以df5 为基准。
dfc = pd.concat([df5, df6], join_axes=[df5.columns])
# print(dfc)

# 通过append 函数 来合并数据.效果一样
# print('这是append的df', df1.append(df2))

# 通过append方法不会修改原始对象,
# 而是会使用合并的数据创建一个新对象
# 还是使用concat 比较高效。、

# 1、 高性能合并Merge 合并多个数据源
df_emp = pd.DataFrame({'employee': ['Bob', 'Jake', 'Lisa', 'Sue', 'ztloo'],
                       'group': ['Accounting', 'Engineering', 'Engineering', 'HR', 'code']})
df_date = pd.DataFrame({'employee': ['Lisa', 'Bob', 'Jake', 'Sue', 'pys'],
                        'hire_date': [2004, 2008, 2012, 2014, 2020]})

# print(df_emp)
# print(df_date)

# 按照第一个参数df_emp 的索引顺序排列的
# merge 只合并两个数据源相同的列,不同的列会舍弃
df3 = pd.merge(df_emp, df_date)
# print(df3)

df4 = pd.DataFrame({'group': ['Accounting', 'Engineering', 'HR'],
                    'supervisor': ['Carly', 'Guido', 'Steve']})

# 两个df 在去合并一个df,通过group,新增一个关系列。
df34 = pd.merge(df3, df4)
# print(df34)

# 合并的df 数据中有重复索引
df5 = pd.DataFrame({'group': ['Accounting', 'Accounting',
                              'Engineering', 'Engineering', 'HR', 'HR'],
                    'skills': ['math', 'spreadsheets', 'coding', 'linux',
                               'spreadsheets', 'organization']})
print(df_emp)

# 根据df_emp 中的grop角色进行关联合并。
df15 = pd.merge(df_emp, df5)
print(df15)

# 通过关键字来合并,显示指定两个df 中都有的字段,用来作为关联。
dfe12 = pd.merge(df_emp, df_date, on='employee')
print(dfe12)

df3 = pd.DataFrame({'name': ['Bob', 'Jake', 'Lisa', 'Sue', 'dssf'],
                    'salary': [70000, 80000, 120000, 90000, 1009009]})

# 两个df 中,关联两个索引名称不同的方法。
# 通过left_on和right_on 来指定左右关联的索引名称
df13_lr = pd.merge(df_emp, df3, left_on="employee", right_on="name")
print(df13_lr)

# 去掉重复的列,删掉name 列。
print(df13_lr.drop('name', axis=1))

df1a = df_emp.set_index('employee')
df2a = df_date.set_index('employee')
print(df1a)
print(df2a)

dfaa = pd.merge(df1a, df2a, left_index=True, right_index=True)
print(dfaa)

print(df1a.join(df2a))
print(df1a)

# 因为df1a 的索引set_index 被设置成了employee,so 直接关联name.
dfa3 = pd.merge(df1a, df3, left_index=True, right_on='name')
print(dfa3)

# 严重的问题
# 两个df 中有不同的列,使用merge 只会合并都存在的列
df6 = pd.DataFrame({'name': ['Peter', 'Paul', 'Mary'],
                    'food': ['fish', 'beans', 'bread']},
                   columns=['name', 'food'])

df7 = pd.DataFrame({'name': ['Mary', 'Joseph'],
                    'drink': ['wine', 'beer']},
                   columns=['name', 'drink'])

# 为了解决多个df 中不同的列,使用how=outer,
df67 = pd.merge(df6, df7,how='outer')
print(df67)

# 如果只显示第一个df数据中的所有列,left ,也可以使用right.
df67 = pd.merge(df6, df7, how='left')
print(df67)

# 合并两个df ,df 中有相同的列名
df8 = pd.DataFrame({'name': ['Bob', 'Jake', 'Lisa', 'Sue'],
                    'rank': [1, 2, 3, 4]})
df9 = pd.DataFrame({'name': ['Bob', 'Jake', 'Lisa', 'Sue'],
                    'rank': [3, 1, 4, 2]})

'''
由于输出将有两个冲突的列名,
因此合并功能会自动附加后缀_x或_y使输出列唯一。
如果这些默认值不合适,则可以使用suffixes关键字指定自定义后缀:
'''

df89 = pd.merge(df8, df9, on="name")
print(df89)

df89 = pd.merge(df8, df9, on="name", suffixes=["_L", "_R"])
print(df89)

##################################################################

pop = pd.read_csv('state-population.csv')
areas = pd.read_csv('state-areas.csv')
abbrevs = pd.read_csv('state-abbrevs.csv')

print('-----------pop------------')
print(pop.head())
#
print('-----------areas------------')
print(areas.head())

print('-----------abbrevs------------')
print(abbrevs.head())

# 让state/region和 abbreviation 字段相关联
merged = pd.merge(pop, abbrevs, how='outer',
                  left_on='state/region', right_on='abbreviation')

# drop duplicate info

# 删掉abbreviation 列
merged = merged.drop('abbreviation', axis=1)  # drop duplicate info
# print(merged.head())
#

# 检查数据是否有不匹配有空行
print(merged.isnull().any())

# 一些population信息为空;让我们找出:
pop_null = merged[merged['population'].isnull()].head()
# print(pop_null)

state_unique = merged.loc[merged['state'].isnull(), 'state/region'].unique()
# unique.返回Series对象的唯一值。
print(state_unique)

# 把合并好的数据中的state/region
# 等于pr的数据中的state 字段的值修改成Puerto Rico。
merged.loc[merged['state/region'] == 'PR', 'state'] = 'Puerto Rico'

# 把合并好的数据中的state/region 等于USA的数据中的state 字段的值修改成Puerto Rico

merged.loc[merged['state/region'] == 'USA', 'state'] = 'United States'

# any()一个True,则返回True,非空为False
print(merged.isnull().any())
print(merged.head())

# 将结果与面积数据合并。
# 检查我们的结果,我们将希望同时加入state这两个列:
final = pd.merge(merged, areas, on='state', how='left')
print(final.head())

print(final.isnull().any())

# area列中为空;我们可以看一下此处忽略了哪些区域:
fun = final['state'][final['area (sq. mi)'].isnull()].unique()
print(fun)

'''
我们看到,我们areas DataFrame不包括整个美国地区。
我们可以插入适当的值(例如,使用所有州面积的总和),
但是在这种情况下,我们将删除空值,因为整个美国的人口密度与我们当前的讨论无关:
'''
final.dropna(inplace=True)
# print(final.head())

data2010 = final.query("year == 2010 & ages == 'total'")
# print(data2010.head())

data2010.set_index('state', inplace=True)
density = data2010['population'] / data2010['area (sq. mi)']
density.sort_values(ascending=False, inplace=True)
print(density.head())
print(density.tail())
打赏
赞(0) 打赏
未经允许不得转载:同乐学堂 » 原创-Pandas心法之数据连接&合并-5

特别的技术,给特别的你!

联系QQ:1071235258QQ群:710045715

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏

error: Sorry,暂时内容不可复制!