Pandas从入门到精通(6)- 连接

2020-12-29  本文已影响0人  木头里有虫911

1. 课程内容

SQL中最常见的操作莫过于将好几张表连接(JOIN)起来查看某些字段,与之类似,Pandas具有功能全面且性能强大连接操作。而且因为我们的DataFrame中有列-columns和索引-index。在Pandas中的连接操作感觉比SQL中要丰富的多。
本期我们就来串一串这些连接方法,主要有:

1.1 merge

merge()函数 基本语法:
pd.merge(df1, df2, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=True)
其中:

image.png

使用merge时,如果没有指定 on = 哪一列,则默认以重叠列名当做链接键, 当然也可以按照多键连接,只需要'on'参数后传入多键列表即可。

1.2 join索引连接

在上面的Merge中,主要是针对columns进行连接,如果在merge中指定on = index, 即按照索引来连接,是否可以呢?答案是可以的。但是这种情况最好直接用join来做。pandas 中利用 join 函数来处理索引连接,它的参数选择要少于 merge ,除了必须的 on 和 how 之外,可以对重复的列指定左右后缀 lsuffix 和 rsuffix 。其中, on 参数指索引名,单层索引时省略参数表示按照当前索引连接。

1.3 方向连接concat

前面介绍了关系型连接,其中最重要的参数是 on 和 how ,但有时候用户并不关心以哪一列为键来合并,只是希望把两个表或者多个表按照纵向或者横向拼接,为这种需求, pandas 中提供了 concat 函数来实现。
在 concat 中,最常用的有三个参数,它们是 axis, join, keys ,分别表示拼接方向,连接形式,以及在新表中指示来自于哪一张旧表的名字。这里需要特别注意, join 和 keys 与之前提到的 join 函数和键的概念没有任何关系。

在默认状态下的 axis=0 ,表示纵向拼接多个表,常常用于多个样本的拼接;而 axis=1 表示横向拼接多个表,常用于多个字段或特征的拼接。

1.4 其他连接操作

其他类似的连接操作还有append,combine等,比较简单,这里不在介绍

2. 作业练习题

1:美国疫情数据集

现有美国4月12日至11月16日的疫情报表,请将 New YorkConfirmed, Deaths, Recovered, Active 合并为一张表,索引为按如下方法生成的日期字符串序列:

date = pd.date_range('20200412', '20201116').to_series()

In [62]: date = date.dt.month.astype('string').str.zfill(2
   ....:        ) +'-'+ date.dt.day.astype('string'
   ....:        ).str.zfill(2) +'-'+ '2020'
   ....: 

In [63]: date = date.tolist()

In [64]: date[:5]
Out[64]: ['04-12-2020', '04-13-2020', '04-14-2020', '04-15-2020', '04-16-2020']

解答:
第一步查看原始数据。原始数据存在一个文件夹中,每个文件是用日期进行命名的csv文件,选择其中一份查看


image.png
import pandas as pd
path = './us_report/'
file_name = '04-12-2020.csv'
df = pd.read_csv(path + file_name)
df.head()
image.png

第二步:需求分析
现在需要做两件事:
1) 将每份csv文件中的New York州的'Confirmed','Deaths','Recovered','Active'数据提取出来
2)将提取出来的数据合并成一个大的DataFrame, 并且以文件名中的日期作为Index

第三步:解决思路

  1. 从每份文档中提取信息是一个重复的操作,适合使用一个函数来完成
  2. 这个函数干两件事:提取文件名中的日期和New York州的数据。这个都很简单:
state = 'New York'
need_col = ['Confirmed','Deaths','Recovered','Active']

def file_process(f):
    f_index = [f.split('.')[0]] # 注意index必须要是一个列表的形式
    f_path = path + f
    f_df = pd.read_csv(f_path)
    new_df = f_df[f_df['Province_State'] == state][need_col]
    new_df.index = f_index
    
    return new_df

# 使用一个文件调试,看看是否能够正确的提取信息
file_process('05-01-2020.csv')
image.png

OK,程序可以跑

  1. 遍历整个文件夹,对每份文件调用相同的函数之后在合并信息,搞定!
# 读取所有样本
df1 = file_process('04-12-2020.csv')
for file in os.listdir(path)[1:]:
    df1 = pd.concat([df1, file_process(file)])
df1

结果如下:


image.png

在这里,使用函数的好处是如果需求有变,例如将New York换成其他州,或者需要其他信息的时候,只要在函数外面定义相应的值即可。由于函数的主体和其他部分是解耦的,当有需求改动的时候,只需要做较小的改动即可完成!

参考:开源内容Joyful Pandas, 作者 DataWhale耿远昊
另外,更多精彩内容也可以微信搜索,并关注公众号:‘Python数据科学家之路“ ,期待您的到来和我交流

上一篇下一篇

猜你喜欢

热点阅读