Как эффективно получить строку значений, хранящихся во фрейме данных, из строки идентификаторов?

#python #pandas #dataframe #numpy

Вопрос:

Я работаю с двумя кадрами данных:

 1. name_basics:

 nconst      primaryName
0  nm0000001     Fred Astaire
1  nm0000002    Lauren Bacall
2  nm0000003  Brigitte Bardot
3  nm0000004     John Belushi
4  nm0000005   Ingmar Bergman

2. title_directors:

 tconst            directors
0  tt0000574            nm0846879
1  tt0000591            nm0141150
2  tt0000679  nm0091767,nm0877783
3  tt0001184  nm0063413,nm0550220
4  tt0001258            nm0088881
 

То, что я ищу, — это что-то вроде этого:

 tconst            directors
0  tt0000574      name1
1  tt0000591      name2
2  tt0000679      name3,name4
3  tt0001184      name5,name6
4  tt0001258      name7
 

Я попытался сделать это, определив имена функций, а затем выполнив

 title_directors['directors'] = title_directors['directors'].apply(getNames)
 
 def getNames(nconsts):
    nconstList = nconsts.split(',')
    retString = ''
    for nconst in nconstList:
        df = name_basics[name_basics['nconst'] == nconst]['primaryName']
        if not df.empty:
            retString  = df.iloc[0]   ', '
    return retString[:-2]

getNames('nm0063413,nm0550220')
'Ricardo de Baños, Alberto Marro'
 

Но это слишком медленно (на моем компьютере это заняло бы около 80 часов). Мне было интересно, как правильно это сделать.

Большое спасибо

Комментарии:

1.Если бы они у вас были по одному, pandas join инструмент мог бы сделать именно это. pandas.pydata.org/docs/reference/api/pandas.DataFrame.join.html Вы, безусловно, могли бы ускорить процесс, сделав nconst ключ для name_basics .

Ответ №1:

Один подход:

 import pprint

import pandas as pd

name_basics = pd.read_csv("input.csv")
title_directors = pd.read_csv("filer.csv", delim_whitespace=True)

print(name_basics)
print(title_directors)

# split by comma
title_directors["directors"] = title_directors["directors"].str.split(",")

# explode the DataFrame
td = title_directors.explode("directors")

# map the name_basics DataFrame onto the directors column
td["directors"] = td["directors"].map(name_basics.set_index("nconst").squeeze()).fillna("")

# un-explode
res = td.groupby("tconst").agg(",".join).reset_index()

# remove unwanted commnas from the new column
res["directors"] = res["directors"].str.strip(",")
print(res)
 

name_basics Для фрейма данных следующим образом:

       nconst      primaryName
0  nm0000001     Fred Astaire
1  nm0000002    Lauren Bacall
2  nm0000003  Brigitte Bardot
3  nm0000004     John Belushi
4  nm0000005   Ingmar Bergman
 

и а title_directors следующим образом:

       tconst            directors
0  tt0000574            nm0000001
1  tt0000591            nm0141150
2  tt0000679  nm0091767,nm0000004
3  tt0001184  nm0063413,nm0550220
4  tt0001258            nm0088881
 

это дает следующий результат:

       tconst     directors
0  tt0000574  Fred Astaire
1  tt0000591              
2  tt0000679  John Belushi
3  tt0001184              
4  tt0001258          
 

Комментарии:

1. Большое вам спасибо, это было очень полезно :). Мне пришлось добавить [‘PrimaryName’] после .squeeze (), но все остальное работало отлично!

2. @alanacevedo Рад, что смог помочь!