Как мне очистить список и список элементов списка в фрейме данных pandas?

#python #pandas #data-wrangling

#python #pandas #перебор данных

Вопрос:

Отредактировано:

После написания этого:

 m = df.explode('ID1').groupby('ID1')['ID2'].agg(list)
  

У меня есть следующий фрейм данных:

 Ref         
45263     [['3105-BB', '3106-BB', '3201-BB', '3202-BB'],...
45256     [['3105-BB', '3106-BB', '3201-BB', '3202-BB'],...
48565     [['3159-CC', '3217-CC'], ['3159-CC', '3217-CC']]
49365     [['3159-CC', '3217-CC'], ['3159-CC', '3217-CC']]
47548     [['3107-CC', '3108-CC', '3201-CC', '3202-CC'],...
  

В col справа, как мне удалить списки скобок списка и дубликаты для каждой строки. В идеале я хотел бы иметь только один список для каждой строки?

например, для вывода:

 Ref         
45263     ['3105-BB', '3106-BB', '3201-BB', '3202-BB']
45256     ['3105-BB', '3106-BB', '3201-BB', '3202-BB']
48565     ['3159-CC', '3217-CC']
49365     ['3159-CC', '3217-CC']
47548     ['3107-CC', '3108-CC', '3201-CC', '3202-CC']
  

После этого я буду использовать m в следующем:

 df['ID4'] = df['Ref'].map(m)
  

Это вернет конечный фрейм данных, который я ищу.

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

1. было бы полезно, если бы вы предоставили данные, которые могут запускать другие. «выглядит так после завершения некоторой очистки и агрегации», например, что? Чего-то не хватает?

Ответ №1:

Использовать set comprehension с выравниванием значений вложенных списков:

 df['ID'] = df['ID'].apply(lambda x: list(set(z for y in x for z in y)))
  

Если важен порядок, используйте dict с keys трюком:

 df['ID'] = df['ID'].apply(lambda x: list(dict.fromkeys([z for y in x for z in y]).keys()))
  

Если следующая обработка — map, вам нужны разнесенные списки:

 df = df.explode('ID').reset_index(drop=True)
print (df)
      Ref       ID
0   45263  3105-BB
1   45263  3106-BB
2   45263  3202-BB
3   45263  3201-BB
4   45256  3105-BB
5   45256  3106-BB
6   45256  3202-BB
7   45256  3201-BB
8   48565  3217-CC
9   48565  3159-CC
10  49365  3217-CC
11  49365  3159-CC
12  47548  3202-CC
13  47548  3108-CC
14  47548  3201-CC
15  47548  3107-CC
  

Пример:

 df['ID1'] = df['ID'].apply(lambda x: list(set(z for y in x for z in y)))
df['ID2'] = df['ID'].apply(lambda x: list(dict.fromkeys([z for y in x for z in y]).keys()))
print (df)
     Ref                                        ID  
0  45263    [[3105-BB, 3106-BB, 3201-BB, 3202-BB]]   
1  45256    [[3105-BB, 3106-BB, 3201-BB, 3202-BB]]   
2  48565  [[3159-CC, 3217-CC], [3159-CC, 3217-CC]]   
3  49365  [[3159-CC, 3217-CC], [3159-CC, 3217-CC]]   
4  47548    [[3107-CC, 3108-CC, 3201-CC, 3202-CC]]   

                                    ID1                                   ID2  
0  [3105-BB, 3106-BB, 3202-BB, 3201-BB]  [3105-BB, 3106-BB, 3201-BB, 3202-BB]  
1  [3105-BB, 3106-BB, 3202-BB, 3201-BB]  [3105-BB, 3106-BB, 3201-BB, 3202-BB]  
2                    [3217-CC, 3159-CC]                    [3159-CC, 3217-CC]  
3                    [3217-CC, 3159-CC]                    [3159-CC, 3217-CC]  
4  [3202-CC, 3108-CC, 3201-CC, 3107-CC]  [3107-CC, 3108-CC, 3201-CC, 3202-CC]  
  

Редактировать:

 f = lambda x: list(set(z for y in x for z in y)
df.explode('ID1').groupby('ID1')['ID2'].agg(f)
  

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

1. Спасибо за вашу работу. Я внес правку, поскольку считаю, что пропустил некоторые фундаментальные шаги в своем вопросе. Пожалуйста, смотрите выше редактирование @jezrael

2. @Ventoii — Я думаю, что нет, но вы можете использовать мою функцию со своей.

3. было бы здорово, если бы были начальные данные, которые другие могут использовать для запуска этого, иначе довольно сложно следовать.

4. @jezrael Спасибо, я буду запускать его сегодня утром. Я вернусь к вам сегодня.

5. @jezrael Это работает отлично! Спасибо. Этот пост многому научил меня тому, как обращаться с этими структурами данных. Я ценю вашу работу!!