Pandas:如何通过保留第一个的信息来合并列上的两个数据帧? [英] Pandas: how to merge two dataframes on a column by keeping the information of the first one?

查看:22
本文介绍了Pandas:如何通过保留第一个的信息来合并列上的两个数据帧?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个数据帧 df1df2.df1 包含人的年龄信息,而df2 包含人的性别信息.并非所有人都在 df1df2

df1姓名年龄0 汤姆 341 萨拉 182 伊娃 443 杰克 274 劳拉 30df2姓名性别0 汤姆1 保罗2 伊娃3 杰克米4 米歇尔 F

我想在df1中获取人的性别信息,如果df2中没有此信息,则设置NaN.我试着做 df1 = pd.merge(df1, df2, on = 'Name', how = 'outer') 但我把一些人的信息保存在 df2我不想要的.

df1姓名 年龄 性别0 汤姆 34 米1 萨拉 18 南2 伊娃 44 华氏度3 杰克 27 M4 劳拉 30 南

解决方案

Sample:

df1 = pd.DataFrame({'Name': ['Tom', 'Sara', 'Eva', 'Jack', 'Laura'],'年龄': [34, 18, 44, 27, 30]})#打印(df1)df3 = df1.copy()df2 = pd.DataFrame({'Name': ['Tom', 'Paul', 'Eva', 'Jack', 'Michelle'],'性别': ['M', 'M', 'F', 'M', 'F']})#打印(df2)

使用mapSeries 创建,由 set_index:

df1['Sex'] = df1['Name'].map(df2.set_index('Name')['Sex'])打印 (df1)姓名 年龄 性别0 汤姆 34 米1 萨拉 18 南2 伊娃 44 华氏度3 杰克 27 M4 劳拉 30 南

使用 merge 左连接:

df = df3.merge(df2[['Name','Sex']], on='Name', how='left')打印 (df)姓名 年龄 性别0 汤姆 34 米1 萨拉 18 南2 伊娃 44 华氏度3 杰克 27 M4 劳拉 30 南

<小时>

如果需要按多列映射(例如YearCode)需要merge与左连接:

df1 = pd.DataFrame({'Name': ['Tom', 'Sara', 'Eva', 'Jack', 'Laura'],'年':[2000,2003,2003,2004,2007],'代码':[1,2,3,4,4],'年龄': [34, 18, 44, 27, 30]})打印 (df1)姓名 年份 代码 年龄0 汤姆 2000 1 341 萨拉 2003 2 182 伊娃 2003 3 443 杰克 2004 4 274 劳拉 2007 4 30df2 = pd.DataFrame({'Name': ['Tom', 'Paul', 'Eva', 'Jack', 'Michelle'],'性别': ['M', 'M', 'F', 'M', 'F'],'年':[2001,2003,2003,2004,2007],'代码':[1,2,3,5,3],'瓦尔':[21,34,23,44,67]})打印 (df2)姓名 性别 年份 代码 Val0 汤姆 M 2001 1 211 保罗 M 2003 2 342 伊娃 F 2003 3 233 杰克 M 2004 5 444 米歇尔 F 2007 3 67

#merge 按所有列df = df1.merge(df2, on=['Year','Code'], how='left')打印 (df)Name_x 年份代码 年龄 Name_y 性别 Val0 汤姆 2000 1 34 NaN NaN NaN1 萨拉 2003 2 18 保罗 M 34.02 伊娃 2003 3 44 伊娃 F 23.03 杰克 2004 4 27 NaN NaN NaN4 劳拉 2007 4 30 NaN NaN NaN#specified 列 - 连接列(年份、代码)需要总是 + 附加列(Val)df = df1.merge(df2[['Year','Code','Val']], on=['Year','Code'], how='left')打印 (df)姓名 年份 代码 年龄 Val0 汤姆 2000 1 34 NaN1 萨拉 2003 2 18 34.02 伊娃 2003 3 44 23.03 杰克 2004 4 27 NaN4 劳拉 2007 4 30 NaN

<小时>

如果 map 出现错误,则表示按连接列重复,这里是 Name:

df1 = pd.DataFrame({'Name': ['Tom', 'Sara', 'Eva', 'Jack', 'Laura'],'年龄': [34, 18, 44, 27, 30]})打印 (df1)姓名年龄0 汤姆 341 萨拉 182 伊娃 443 杰克 274 劳拉 30df3, df4 = df1.copy(), df1.copy()df2 = pd.DataFrame({'Name': ['Tom', 'Tom', 'Eva', 'Jack', 'Michelle'],'瓦尔':[1,2,3,4,5]})打印 (df2)名称瓦尔0 Tom 1 <-重复名称 Tom1 Tom 2 <-重复名称 Tom2 伊娃 33 杰克 44 米歇尔 5s = df2.set_index('Name')['Val']df1['New'] = df1['Name'].map(s)打印 (df1)

<块引用>

InvalidIndexError:重新索引仅对唯一值的索引对象有效

解决方案通过 DataFrame 删除重复项.drop_duplicates, 或者使用 map by dict 进行最后一次重复匹配:

#default 保留第一个值s = df2.drop_duplicates('Name').set_index('Name')['Val']印刷)姓名汤姆 1伊娃 3杰克 4米歇尔 5名称:Val,数据类型:int64df1['New'] = df1['Name'].map(s)打印 (df1)姓名 年龄 新0 汤姆 34 1.01 萨拉 18 南2 伊娃 44 3.03 杰克 27 4.04 劳拉 30 南

#add 保留最后一个值的参数s = df2.drop_duplicates('Name', keep='last').set_index('Name')['Val']印刷)姓名汤姆 2伊娃 3杰克 4米歇尔 5名称:Val,数据类型:int64df3['New'] = df3['Name'].map(s)打印 (df3)姓名 年龄 新0 汤姆 34 2.01 萨拉 18 南2 伊娃 44 3.03 杰克 27 4.04 劳拉 30 南

#map by dictionaryd = dict(zip(df2['Name'], df2['Val']))打印 (d){'汤姆':2,'伊娃':3,'杰克':4,'米歇尔':5}df4['New'] = df4['Name'].map(d)打印 (df4)姓名 年龄 新0 汤姆 34 2.01 萨拉 18 南2 伊娃 44 3.03 杰克 27 4.04 劳拉 30 南

I have two dataframes df1 and df2. df1 contains the information of the age of people, while df2 contains the information of the sex of people. Not all the people are in df1 nor in df2

df1
     Name   Age 
0     Tom    34
1     Sara   18
2     Eva    44
3     Jack   27
4     Laura  30

df2
     Name      Sex 
0     Tom       M
1     Paul      M
2     Eva       F
3     Jack      M
4     Michelle  F

I want to have the information of the sex of the people in df1 and setting NaN if I do not have this information in df2. I tried to do df1 = pd.merge(df1, df2, on = 'Name', how = 'outer') but I keep the information of some people in df2 that I don't want.

df1
     Name   Age     Sex
0     Tom    34      M
1     Sara   18     NaN
2     Eva    44      F
3     Jack   27      M
4     Laura  30     NaN

解决方案

Sample:

df1 = pd.DataFrame({'Name': ['Tom', 'Sara', 'Eva', 'Jack', 'Laura'], 
                    'Age': [34, 18, 44, 27, 30]})

#print (df1)
df3 = df1.copy()

df2 = pd.DataFrame({'Name': ['Tom', 'Paul', 'Eva', 'Jack', 'Michelle'], 
                    'Sex': ['M', 'M', 'F', 'M', 'F']})
#print (df2)

Use map by Series created by set_index:

df1['Sex'] = df1['Name'].map(df2.set_index('Name')['Sex'])
print (df1)
    Name  Age  Sex
0    Tom   34    M
1   Sara   18  NaN
2    Eva   44    F
3   Jack   27    M
4  Laura   30  NaN

Alternative solution with merge with left join:

df = df3.merge(df2[['Name','Sex']], on='Name', how='left')
print (df)
    Name  Age  Sex
0    Tom   34    M
1   Sara   18  NaN
2    Eva   44    F
3   Jack   27    M
4  Laura   30  NaN


If need map by multiple columns (e.g. Year and Code) need merge with left join:

df1 = pd.DataFrame({'Name': ['Tom', 'Sara', 'Eva', 'Jack', 'Laura'], 
                    'Year':[2000,2003,2003,2004,2007],
                    'Code':[1,2,3,4,4],
                    'Age': [34, 18, 44, 27, 30]})

print (df1)
    Name  Year  Code  Age
0    Tom  2000     1   34
1   Sara  2003     2   18
2    Eva  2003     3   44
3   Jack  2004     4   27
4  Laura  2007     4   30

df2 = pd.DataFrame({'Name': ['Tom', 'Paul', 'Eva', 'Jack', 'Michelle'], 
                    'Sex': ['M', 'M', 'F', 'M', 'F'],
                    'Year':[2001,2003,2003,2004,2007],
                    'Code':[1,2,3,5,3],
                    'Val':[21,34,23,44,67]})
print (df2)
       Name Sex  Year  Code  Val
0       Tom   M  2001     1   21
1      Paul   M  2003     2   34
2       Eva   F  2003     3   23
3      Jack   M  2004     5   44
4  Michelle   F  2007     3   67

#merge by all columns
df = df1.merge(df2, on=['Year','Code'], how='left')
print (df)
  Name_x  Year  Code  Age Name_y  Sex   Val
0    Tom  2000     1   34    NaN  NaN   NaN
1   Sara  2003     2   18   Paul    M  34.0
2    Eva  2003     3   44    Eva    F  23.0
3   Jack  2004     4   27    NaN  NaN   NaN
4  Laura  2007     4   30    NaN  NaN   NaN

#specified columns - columns for join (Year, Code) need always + appended columns (Val)
df = df1.merge(df2[['Year','Code', 'Val']], on=['Year','Code'], how='left')
print (df)
    Name  Year  Code  Age   Val
0    Tom  2000     1   34   NaN
1   Sara  2003     2   18  34.0
2    Eva  2003     3   44  23.0
3   Jack  2004     4   27   NaN
4  Laura  2007     4   30   NaN


If get error with map it means duplicates by columns of join, here Name:

df1 = pd.DataFrame({'Name': ['Tom', 'Sara', 'Eva', 'Jack', 'Laura'], 
                    'Age': [34, 18, 44, 27, 30]})

print (df1)
    Name  Age
0    Tom   34
1   Sara   18
2    Eva   44
3   Jack   27
4  Laura   30

df3, df4 = df1.copy(), df1.copy()

df2 = pd.DataFrame({'Name': ['Tom', 'Tom', 'Eva', 'Jack', 'Michelle'], 
                    'Val': [1,2,3,4,5]})
print (df2)
       Name  Val
0       Tom    1 <-duplicated name Tom
1       Tom    2 <-duplicated name Tom
2       Eva    3
3      Jack    4
4  Michelle    5

s = df2.set_index('Name')['Val']
df1['New'] = df1['Name'].map(s)
print (df1)

InvalidIndexError: Reindexing only valid with uniquely valued Index objects

Solutions are removed duplicates by DataFrame.drop_duplicates, or use map by dict for last dupe match:

#default keep first value
s = df2.drop_duplicates('Name').set_index('Name')['Val']
print (s)
Name
Tom         1
Eva         3
Jack        4
Michelle    5
Name: Val, dtype: int64

df1['New'] = df1['Name'].map(s)
print (df1)
    Name  Age  New
0    Tom   34  1.0
1   Sara   18  NaN
2    Eva   44  3.0
3   Jack   27  4.0
4  Laura   30  NaN

#add parameter for keep last value 
s = df2.drop_duplicates('Name', keep='last').set_index('Name')['Val']
print (s)
Name
Tom         2
Eva         3
Jack        4
Michelle    5
Name: Val, dtype: int64

df3['New'] = df3['Name'].map(s)
print (df3)
    Name  Age  New
0    Tom   34  2.0
1   Sara   18  NaN
2    Eva   44  3.0
3   Jack   27  4.0
4  Laura   30  NaN

#map by dictionary
d = dict(zip(df2['Name'], df2['Val']))
print (d)
{'Tom': 2, 'Eva': 3, 'Jack': 4, 'Michelle': 5}

df4['New'] = df4['Name'].map(d)
print (df4)
    Name  Age  New
0    Tom   34  2.0
1   Sara   18  NaN
2    Eva   44  3.0
3   Jack   27  4.0
4  Laura   30  NaN

这篇关于Pandas:如何通过保留第一个的信息来合并列上的两个数据帧?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆