从具有列表项的列创建字典的有效方法,其中列表元素是键

2024-05-29 02:07:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试创建列表元素值到索引的映射。例如,给定如下数据帧:

>>> book_df
    name                  genre
0   Harry Potter          ["fantasy", "young adult"]
1   Lord of the Rings     ["fantasy", "adventure", "classics"]
2   I, Robot              ["science fiction", "classics"]
3   Animal Farm           ["classics", "fantasy"]
4   A Monster Calls       ["fantasy", "young adult"]

我想生成一个dict,它将流派映射到该流派下的电影列表。你知道吗

所以,我想要得到的是这样的东西:

>>> genre_to_book_map
{
    "fantasy": ["Harry Potter", "Lord of the Rings", "Animal Farm", "A Monster Calls"],
    "young adult": ["Harry Potter", "A Monster Calls"],
    "classics": ["Lord of the Rings", "I, Robot", "Animal Farm"],
    "science fiction": ["I, Robot"],
    "adventure": ["Lord of the Rings"]
}

我以一种相当冗长的方式完成了这个任务,将列表分解,然后用它创建一个字典(基于Pandas column of lists, create a row for each list elementPandas groupby two columns then get dict for values),如下所示:

exploded_genres = pd.DataFrame({
    "name" :np.repeat(book_df["name"].values, book_df["genres"].str.len())
}).assign(**{"genres":np.concatenate(book_df["genres"].values)})

genre_to_name_map = exploded_genres.groupby("genres")["name"].apply(lambda x: x.tolist())

但我想知道是否有更有效的方法来做这件事,因为这似乎是一件相对简单的事情


Tags: ofthenamedf列表fantasygenresyoung
3条回答

使用旧的良好collections.defaultdict对象:

In [410]: from collections import defaultdict                                                                                                              

In [411]: d = defaultdict(list)                                                                                                                            

In [412]: for idx, row in df.iterrows(): 
     ...:     for g in row['genre']: 
     ...:         d[g].append(row['name']) 
     ...:                                                                                                                                                  

In [413]: dict(d)                                                                                                                                          
Out[413]: 
{'fantasy': ['Harry Potter',
  'Lord of the Rings',
  'Animal Farm',
  'A Monster Calls'],
 'young adult': ['Harry Potter', 'A Monster Calls'],
 'adventure': ['Lord of the Rings'],
 'classics': ['Lord of the Rings', 'I, Robot', 'Animal Farm'],
 'science fiction': ['I, Robot']}

您需要将列表融合到各个流派中,然后按流派分组并输出到字典中。你知道吗

import pandas as pd

df = pd.DataFrame({'name' : [
'Harry Potter',
'Lord of the Rings',
'I, Robot',
'Animal Farm',
'A Monster Calls'
],

'genre': [
 ["fantasy", "young adult"],
 ["fantasy", "adventure", "classics"],
 ["science fiction", "classics"],
 ["classics", "fantasy"],
 ["fantasy", "young adult"]
 ]
})

# create a Series object, give it a name.
s = df.genre.apply(pd.Series).stack().reset_index(level=-1, drop=True)
s.name = 'genres'

# merge and groubpy and output to dict.
d = (
    df.loc[:,['name']]
      .merge(s, left_index=True, right_index=True)
      .groupby('genres')['name']
      .apply(list)
      .to_dict()
)

因为0.25,所以可以使用explode来展开列表。你知道吗

book_df.explode('genre').groupby('genre')['name'].apply(list).to_dict()

相关问题 更多 >

    热门问题