Как сжать pandas DataFrame в словарь с уникальными ключами и перечисленными значениями? - PullRequest
2 голосов
/ 07 ноября 2019

У меня есть следующий пример pandas DataFrame, в котором есть два столбца: Name и Age:

import pandas as pd

data = [['Alex',10],['Bob',12],['Barbara',25], ['Bob',72], 
    ['Clarke',13], ['Clarke',13], ['Destiny', 45]]

df = pd.DataFrame(data,columns=['Name','Age'], dtype=float)

print(df)
      Name   Age
0     Alex  10.0
1      Bob  12.0
2  Barbara  25.0
3      Bob  72.0
4   Clarke  13.0
5   Clarke  13.0
6  Destiny  45.0

Моя конечная цель - создать словарь, в котором каждый ключ является именем икаждое значение представляет собой список Ages, связанный с этим Name.

Таким образом, конечный словарь будет

final_result = {"Alex":[10], "Bob":[12, 72], "Barbara":[25], "Clarke":[13], "Destiny":[45]} 

Мой подход:

Я мог бы попробоватьперебирая кадр данных для создания списков и переименовывая столбец:

for name in df.Name.unique():
    list_attributes = []
    for i in df.loc[df.Age == name].Age.unique()
        list_attributes.append(i)
    df['List_Column'] = list_attributes

Но это очень запутанно. Какой самый эффективный способ сделать это?

Ответы [ 2 ]

3 голосов
/ 07 ноября 2019

Опция 1 : groupby().apply(list):

df.groupby('Name')['Age'].apply(list).to_dict()
# 4.06 ms ± 966 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Опция 2 : понимание списка / слова

{a:list(x) for a,x in df.groupby('Name')['Age']}
# 2.68 ms ± 177 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Вывод:

{'Alex': [10.0],
 'Barbara': [25.0],
 'Bob': [12.0, 72.0],
 'Clarke': [13.0, 13.0],
 'Destiny': [45.0]}
1 голос
/ 07 ноября 2019

A defaultdict может работать здесь. drop_duplicates сначала, чтобы обеспечить добавление в список только уникальных значений.

from collections import defaultdict

df = df.drop_duplicates()

d = defaultdict(list)
for k,v in zip(df.Name, df.Age):
    d[k].append(v)
#defaultdict(list,
#            {'Alex': [10.0],
#             'Barbara': [25.0],
#             'Bob': [12.0, 72.0],
#             'Clarke': [13.0],
#             'Destiny': [45.0]})

Это также довольно быстро. Он будет работать намного лучше, чем groupby в тех случаях, когда имеется много групп с несколькими уникальными значениями на группу.

import numpy as np
import pandas as pd

N=10000
df = pd.DataFrame({'Name': np.arange(0,N,1)//10,
                   'Age': np.arange(0,N,1)%100})
df = df.drop_duplicates()

def Alollz(df):
    d = defaultdict(list)
    for k,v in zip(df.Name, df.Age):
        d[k].append(v)
    return d

%timeit Alollz(df)
#3.34 ms ± 7.63 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit {a:list(x) for a,x in df.groupby('Name')['Age']}
#113 ms ± 1.25 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...