Вложенный список для добавления в новый столбец - PullRequest
0 голосов
/ 26 апреля 2020
data = {
    'date': ['2020-04-27', '2020-04-27', '2020-04-27'],
    'user': ['Steeve', 'Pam', 'Olive'],
    'mentions': ["['sport', 'basket']", "['politique']", "[]"],
    'reply_to': [
        "[{'user_id': '123', 'username': 'aaa'}, {'user_id': '234', 'username': 'bbb'}, {'user_id': '456', 'username': 'ccc'}]",
        "[{'user_id': '567', 'username': 'zzz'}, {'user_id': '458', 'username': 'vfd'}]",
        "[{'user_id': '666', 'username': 'ggg'}]"],
    'text': ['textfromSteeve', 'textfromPam', 'textfromOlive']
}

stack = pd.DataFrame(data, columns=['date', 'user','mentions','reply_to','text'])

На этом кадре данных я пытаюсь преобразовать столбцы mentions и reply_to во вложенный список. Цель состоит в том, чтобы применить функцию разнесения pandas, чтобы отобразить одну строку для каждого числа упоминаний. Например, я бы хотел 3 строки пользователя 'Pam' с одним упоминанием для каждой строки (Steeve, Olive и Mar c).

Пока что я сделал следующее:

def nested_list(li):
    temp = []
    for elem in li:
        temp.append([elem]) 
    return temp
stack['mentions_nested= stack.mentions.apply(lambda x: nested_list(x))
stack['replies_nested= stack.reply_to.apply(lambda x: nested_list(x))

Проблема в том, что в столбце есть только одно имя (строка). Он разбивает каждую букву в отдельный список (например: [[P], [a], [m]]).

Относительно столбца reply_to, где длина словаря равна 1, он возвращает что-то например: [[id], [username]].

Ребята, у вас есть идеи, как я могу это сделать?

К вашему сведению: я не собираюсь применять функцию разнесения в обоих случаях упоминается столбец reply_to. Это будет два разных процесса. python

Ответы [ 2 ]

1 голос
/ 26 апреля 2020

Я считаю, что вам нужно заменить не списочные значения в списках на map и isinstance:

for c in ['mentions','reply_to']:
    stack[c] = stack[c].map(lambda x: x if isinstance(x, list) else [x])

print (stack)
     user               mentions  \
0  Steeve                  [Pam]   
1     Pam  [Steeve, Olive, Marc]   
2   Olive            [Paul, Lou]   

                                            reply_to            text  
0               [{'id': '123', 'username': 'alpha'}]  textfromSteeve  
1  [{'id': '231', 'username': 'beta'}, {'id': '45...     textfromPam  
2                 [{'id': '789', 'username': 'olo'}]   textfromOlive  

Тогда возможно создать словари в списочном представлении с назначением ключа из значений индекса, передать DataFrame и последнее использование DataFrame.join для оригинала, последнее использование DataFrame.explode:

L = [dict(**{'idx':k}, **x) for 
     k, v in stack.pop('reply_to').items() 
     for x in v]

df = pd.DataFrame(L).join(stack, on='idx').explode('mentions').reset_index(drop=True)
print (df)
   idx    id username    user mentions            text
0    0   123    alpha  Steeve      Pam  textfromSteeve
1    1   231     beta     Pam   Steeve     textfromPam
2    1   231     beta     Pam    Olive     textfromPam
3    1   231     beta     Pam     Marc     textfromPam
4    1  4580    omega     Pam   Steeve     textfromPam
5    1  4580    omega     Pam    Olive     textfromPam
6    1  4580    omega     Pam     Marc     textfromPam
7    2   789      olo   Olive     Paul   textfromOlive
8    2   789      olo   Olive      Lou   textfromOlive
0 голосов
/ 26 апреля 2020

использовать json нормализовать в ответе на столбец

from pandas import json_normalize

res = pd.concat([json_normalize(ent)
                .assign(index=ind)
                 for ind,ent
                in zip(stack.index,stack['reply_to'])
                ])

res

     id username    index
0   123     alpha   0
0   231     beta    1
1   4580    omega   1
0   789     olo     2

присоединить к исходному фрейму данных с некоторыми очистками

  (stack
   .join(res.set_index('index'))
   .explode('mentions')
   .drop('reply_to',axis=1)
   )

    user    mentions    text         id    username
0   Steeve  Pam     textfromSteeve  123     alpha
1   Pam    Steeve   textfromPam     231     beta
1   Pam     Olive   textfromPam     231     beta
1   Pam     Marc    textfromPam     231     beta
1   Pam     Steeve  textfromPam     4580    omega
1   Pam     Olive   textfromPam     4580    omega
1   Pam     Marc    textfromPam     4580    omega
2   Olive   Paul    textfromOlive   789     olo
2   Olive   Lou     textfromOlive   789     olo
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...