基于列之间的部分字符串匹配加入数据帧
Join dataframes based on partial string-match between columns
我有一个数据框,我想比较它们是否存在于另一个 df 中。
after_h.sample(10, random_state=1)
movie year ratings
108 Mechanic: Resurrection 2016 4.0
206 Warcraft 2016 4.0
106 Max Steel 2016 3.5
107 Me Before You 2016 4.5
我想比较以上电影是否出现在另一个df中。
FILM Votes
0 Avengers: Age of Ultron (2015) 4170
1 Cinderella (2015) 950
2 Ant-Man (2015) 3000
3 Do You Believe? (2015) 350
4 Max Steel (2016) 560
我想要这样的东西作为我的最终输出:
FILM votes
0 Max Steel 560
给定输入数据帧 df1
和 df2
,您可以通过 pd.Series.isin
使用布尔索引。要对齐电影字符串的格式,您需要首先将电影和年份从 df1
:
连接起来
s = df1['movie'] + ' (' + df1['year'].astype(str) + ')'
res = df2[df2['FILM'].isin(s)]
print(res)
FILM VOTES
4 Max Steel (2016) 560
有两种方法:
获取部分匹配的行索引:FILM.startswith(title)
或 FILM.contains(title)
。以下之一:
df1[ df1.movie.apply( lambda title: df2.FILM.str.startswith(title) ).any(1) ]
df1[ df1['movie'].apply(lambda title: df2['FILM'].str.contains(title)).any(1) ]
movie year ratings
106 Max Steel 2016 3.5
- 或者,如果将复合字符串列 df2['FILM'] 转换为它的两个组成列
movie_title (year)
,则可以使用 merge()
.
.
# see code at bottom to recreate your dataframes
df2[['movie','year']] = df2.FILM.str.extract('([^\(]*) \(([0-9]*)\)')
# reorder columns and drop 'FILM' now we have its subfields 'movie','year'
df2 = df2[['movie','year','Votes']]
df2['year'] = df2['year'].astype(int)
df2.merge(df1)
movie year Votes ratings
0 Max Steel 2016 560 3.5
(在这里和 Python 聊天室感谢@user3483203 的帮助)
重新创建数据帧的代码:
import pandas as pd
from pandas.compat import StringIO
dat1 = """movie year ratings
108 Mechanic: Resurrection 2016 4.0
206 Warcraft 2016 4.0
106 Max Steel 2016 3.5
107 Me Before You 2016 4.5"""
dat2 = """FILM Votes
0 Avengers: Age of Ultron (2015) 4170
1 Cinderella (2015) 950
2 Ant-Man (2015) 3000
3 Do You Believe? (2015) 350
4 Max Steel (2016) 560"""
df1 = pd.read_csv(StringIO(dat1), sep='\s{2,}', engine='python', index_col=0)
df2 = pd.read_csv(StringIO(dat2), sep='\s{2,}', engine='python')
smci 的选项 1 已经差不多了,以下对我有用:
df1['Votes'] = ''
df1['Votes']=df1['movie'].apply(lambda title: df2[df2['FILM'].str.startswith(title)]['Votes'].any(0))
解释:
在 df1 中创建投票列
将 lambda 应用于 df1 中的每个电影字符串
lambda 查找 df2,选择 df2 中 Film 以电影标题开头的所有行
Select df2 的结果子集的 Votes 列
取此列中的第一个值与 any(0)
我有一个数据框,我想比较它们是否存在于另一个 df 中。
after_h.sample(10, random_state=1)
movie year ratings
108 Mechanic: Resurrection 2016 4.0
206 Warcraft 2016 4.0
106 Max Steel 2016 3.5
107 Me Before You 2016 4.5
我想比较以上电影是否出现在另一个df中。
FILM Votes
0 Avengers: Age of Ultron (2015) 4170
1 Cinderella (2015) 950
2 Ant-Man (2015) 3000
3 Do You Believe? (2015) 350
4 Max Steel (2016) 560
我想要这样的东西作为我的最终输出:
FILM votes
0 Max Steel 560
给定输入数据帧 df1
和 df2
,您可以通过 pd.Series.isin
使用布尔索引。要对齐电影字符串的格式,您需要首先将电影和年份从 df1
:
s = df1['movie'] + ' (' + df1['year'].astype(str) + ')'
res = df2[df2['FILM'].isin(s)]
print(res)
FILM VOTES
4 Max Steel (2016) 560
有两种方法:
获取部分匹配的行索引:
FILM.startswith(title)
或FILM.contains(title)
。以下之一:df1[ df1.movie.apply( lambda title: df2.FILM.str.startswith(title) ).any(1) ]
df1[ df1['movie'].apply(lambda title: df2['FILM'].str.contains(title)).any(1) ]
movie year ratings
106 Max Steel 2016 3.5
- 或者,如果将复合字符串列 df2['FILM'] 转换为它的两个组成列
movie_title (year)
,则可以使用merge()
.
.
# see code at bottom to recreate your dataframes
df2[['movie','year']] = df2.FILM.str.extract('([^\(]*) \(([0-9]*)\)')
# reorder columns and drop 'FILM' now we have its subfields 'movie','year'
df2 = df2[['movie','year','Votes']]
df2['year'] = df2['year'].astype(int)
df2.merge(df1)
movie year Votes ratings
0 Max Steel 2016 560 3.5
(在这里和 Python 聊天室感谢@user3483203 的帮助)
重新创建数据帧的代码:
import pandas as pd
from pandas.compat import StringIO
dat1 = """movie year ratings
108 Mechanic: Resurrection 2016 4.0
206 Warcraft 2016 4.0
106 Max Steel 2016 3.5
107 Me Before You 2016 4.5"""
dat2 = """FILM Votes
0 Avengers: Age of Ultron (2015) 4170
1 Cinderella (2015) 950
2 Ant-Man (2015) 3000
3 Do You Believe? (2015) 350
4 Max Steel (2016) 560"""
df1 = pd.read_csv(StringIO(dat1), sep='\s{2,}', engine='python', index_col=0)
df2 = pd.read_csv(StringIO(dat2), sep='\s{2,}', engine='python')
smci 的选项 1 已经差不多了,以下对我有用:
df1['Votes'] = ''
df1['Votes']=df1['movie'].apply(lambda title: df2[df2['FILM'].str.startswith(title)]['Votes'].any(0))
解释:
在 df1 中创建投票列
将 lambda 应用于 df1 中的每个电影字符串
lambda 查找 df2,选择 df2 中 Film 以电影标题开头的所有行
Select df2 的结果子集的 Votes 列
取此列中的第一个值与 any(0)