本文是DateWhale组队学习Pandas连接部分的学习心得。
方向连接之concat
在concat中,最常用的有三个参数,它们是axis, join, keys,分别表示拼接方向,连接形式,以及在新表中指示来自于哪一张旧表的名字。这里需要特别注意,join和keys与之前提到的join函数和键的概念没有任何关系。
在默认状态下的axis=0,表示纵向拼接多个表,常常用于多个样本的拼接;而axis=1表示横向拼接多个表,常用于多个字段或特征的拼接。
例如,纵向合并各表中人的信息:
df1 = pd.DataFrame({'Name':['San Zhang','Si Li'], 'Age':[20,30]})
df2 = pd.DataFrame({'Name':['Wu Wang'], 'Age':[40]})
pd.concat([df1, df2])
– | Name | Age |
---|---|---|
0 | San Zhang | 20 |
1 | Si Li | 30 |
2 | Wu Wang | 40 |
横向合并各表中的字段:
df2 = pd.DataFrame({'Grade':[80, 90]})
df3 = pd.DataFrame({'Gender':['M', 'F']})
pd.concat([df1, df2, df3], 1)
– | Name | Age | Grade | Gender |
---|---|---|---|---|
0 | San Zhang | 20 | 80 | M |
1 | Si Li | 30 | 90 | F |
虽然说concat是处理关系型合并的函数,但是它仍然是关于索引进行连接的。纵向拼接会根据列索引对其,默认状态下join=outer,表示保留所有的列,并将不存在的值设为缺失;join=inner,表示保留两个表都出现过的列。横向拼接则根据行索引对齐,join参数可以类似设置。
df2 = pd.DataFrame({'Name':['Wu Wang'], 'Gender':['M']})
pd.concat([df1, df2])
– | Name | Age | Gender |
---|---|---|---|
0 | San Zhang | 20 | NaN |
1 | Si Li | 30 | NaN |
2 | Wu Wang | NaN | M |
df2 = pd.DataFrame({'Grade':[80, 90]}, index=[1, 2])
pd.concat([df1, df2], 1)
– | Name | Age | Grade |
---|---|---|---|
0 | San Zhang | 20.0 | NaN |
1 | Si Li | 30.0 | 80.0 |
2 | NaN | NaN | 90.0 |
pd.concat([df1, df2], axis=1, join='inner')
– | Name | Age | Grade |
---|---|---|---|
1 | Si Li | 30.0 | 80.0 |
因此,当确认要使用多表直接的方向合并时,尤其是横向的合并,可以先用reset_index方法恢复默认整数索引再进行合并,防止出现由索引的误对齐和重复索引的笛卡尔积带来的错误结果。
练习
Ex1美国疫情数据集
现有美国4月12日至11月16日的疫情报表,请将New York的Confirmed, Deaths, Recovered, Active合并为一张表,索引为按如下方法生成的日期字符串序列:
date = pd.date_range('20200412', '20201116').to_series()
date = date.dt.month.astype('string').str.zfill(2) +'-'+ date.dt.day.astype('string').str.zfill(2) +'-'+ '2020'
date = date.tolist()
date[:5]
['04-12-2020', '04-13-2020', '04-14-2020', '04-15-2020', '04-16-2020']
首先查看4月12日的报表数据。
df = pd.read_csv(f'../data/us_report/{date[0]}.csv')
df
每一张报表数据都是这种形式。
然后将Province_State(New York包含在其中)设置为索引。
df = df.set_index('Province_State')
df
查看4月12日的New York的Confirmed, Deaths, Recovered, Active
df.loc[['New York'],['Confirmed', 'Deaths', 'Recovered', 'Active']]
我们要做的其实就是将每一张报表数据转化成上述所示的DataFrame,然后在将所有的DataFrame进行合并(纵向拼接)。
采用pd.concat函数实现
def get_df(dt):
data = pd.read_csv(f'../data/us_report/{dt}.csv')
data = data.set_index('Province_State')
return data.loc[['New York'],['Confirmed', 'Deaths', 'Recovered', 'Active']]
df = pd.concat([get_df(dt) for dt in date])
df['Date'] = date
df = df.reset_index()
df = df.set_index(['Province_State','Date'])
df