Объединить кадры данных на основе частичного совпадения строк между столбцами - PullRequest
0 голосов
/ 11 сентября 2018

У меня есть фрейм данных, который я хочу сравнить, если они присутствуют в другом 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

Ответы [ 3 ]

0 голосов
/ 11 сентября 2018

Есть два способа:

  1. получить индексы строк для частичных совпадений (заголовок FILM .startswith ()) или заголовок FILM .contains (). Любой из:

    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 Макс Сталь 2016 3,5

  2. В качестве альтернативы вы можете использовать merge(), если преобразуете столбец составной строки df2 ['FILM'] в его два столбца компонента movie_title (year).

.

# 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

(Признание большой помощи от @ user3483203 здесь и в чате Python)

Код для воссоздания данных:

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')
0 голосов
/ 12 июля 2019
Вариант 1

smci уже близок, у меня сработало следующее:

df1['Votes'] = ''
df1['Votes']=df1['movie'].apply(lambda title: df2[df2['FILM'].str.startswith(title)]['Votes'].any(0))

Пояснение:

Создать столбец Голосов в df1

Применить лямбду к каждой строке фильма в df1

Лямбда ищет df2, выбирая все строки в df2, где фильм начинается с названия фильма

Выберите столбец Голосов в результирующем подмножестве df2

Возьмите первое значение в этом столбце с любым (0)

0 голосов
/ 11 сентября 2018

С учетом входных кадров данных 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
...