Как создать столбец, полный списков в pandas

#python #pandas

#python #pandas

Вопрос:

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

 fruit_name | color
----------- -------
apple      | red
banana     | yellow
orange     | orange
 

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

 name  |  fruit
------ -------
Ben   |  ['apple', 'banana', 'orange']
Alex  |  ['apple', 'banana', 'orange']
Jude  |  ['apple', 'banana', 'orange']
May   |  ['apple', 'banana', 'orange']
...
 

Для этого я попробовал следующее

 new_df = pd.DataFrame(columns=['name', 'fruit']
new_df['name'] = students['name']
new_df['fruit'] = fruits['fruits_name'].to_list()
 

Я получаю следующее сообщение об ошибке

 ValueError: Length of values (3) does not match length of index (10)
 

Я хочу, чтобы мой конечный результат выглядел следующим образом

 name  |  fruit
------ -------
Ben   |  apple
Ben   |  banana
Ben   |  orange
Alex  |  apple
Alex  |  banana
Alex  |  orange
...
 

Я думал, что буду использовать функцию explode, как только у меня будет столбец списков. Но я застрял, получая фрейм данных со столбцом списков.

Ответ №1:

То, что вы ищете, на самом деле называется перекрестным слиянием, доступно в Pandas 1.2.0 :

 new_df = students[['name']].merge(fruits[['fruit_name']], how='cross')
 

Вывод:

     name fruit_name
0    Ben      apple
1    Ben     banana
2    Ben     orange
3   Alex      apple
4   Alex     banana
5   Alex     orange
6   Jude      apple
7   Jude     banana
8   Jude     orange
9    May      apple
10   May     banana
11   May     orange
 

Примечание. если вы застряли с более ранней версией, используйте тот же ключ для объединения:

 new_df = (students[['name']].assign(key=1)
   .merge(fruits[['fruit_name']].assign(key=1), on='key')
   .drop('key', axis=1)
)
 

Ответ №2:

Причина, по которой вы получаете ошибку ValueError: Length of values (3) does not match length of index (10) , заключается в том, что вы пытаетесь вставить список фруктов в виде столбца. Чтобы сделать его вложенным списком, вы можете использовать np.repeat или как показано ниже:

 fruit_list = ['apple', 'banana', 'orange']
names = ['Ben', 'Alex', 'Jude', 'May']

fruit_df = pd.DataFrame(columns=['name', 'fruit'])
fruit_df['name'] = names
fruit_df['fruit'] = [fruit_list for _ in range(len(names))] # make a nested fruit list for every name
 

это дает:

 >>> fruit_df.head(2)
  name                    fruit
0   Ben  [apple, banana, orange]
1  Alex  [apple, banana, orange] 
 

как вы спрашиваете. и тогда вы можете

 >>> fruit_df.explode('fruit') 
   name   fruit
0   Ben   apple
0   Ben  banana
0   Ben  orange
1  Alex   apple
1  Alex  banana
1  Alex  orange
2  Jude   apple
2  Jude  banana
2  Jude  orange
3   May   apple
3   May  banana
3   May  orange