#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