#python #dataframe
Вопрос:
Я хочу создать новый фрейм данных и разделить другие столбцы, в которых есть несколько пользователей, на мостовую сущность, как в SQL. Я могу думать только о повторении каждой строки в DF, а затем каждого элемента в каждом столбце, в котором существуют эти множественные поля.
Примеры данных:
movieid | директора | бросать |
---|---|---|
1 | персона 1, персона 2, персона 3 | персона 4, персона 6, персона 7 |
2 | персона 1, персона 3 | персона 4, персона 5, персона 9, персона 11 |
Мне нужна нижняя таблица, но итерация кажется медленной (9 тысяч строк заняли минуту).
import pandas as pd
import numpy as np
data = pd.read_csv(datafile, sep=str, delimiter=',', encoding='utf-8')
data2 = data[['show_id','director','cast']].copy()
data2[['cast', 'director']] = data2[['cast', 'director']].fillna('none')
df = pd.DataFrame(columns= ['show_id','role','name'])
for row in data2.itertuples():
casts = row.cast.split(',')
directors = row.director.split(',')
for member in casts:
new_row = {'id': row.show_id, 'role':'cast', 'name': member}
df = df.append(new_row, ignore_index=True)
for member in directors:
new_row = {'id': row.show_id, 'role':'director', 'name': member}
df = df.append(new_row, ignore_index=True)
новые ЛИЦА df
movieid | Роль | Имя |
---|---|---|
1 | директор | персона1 |
1 | директор | персона 2 |
1 | бросать | персона4 |
1 | бросать | персона7 |
Комментарии:
1. Я думаю, вы не хотите, чтобы третий столбец новой таблицы данных был «отлит», верно? «персона 1» и «персона 2» не являются участниками приведения, поэтому иметь имя столбца «приведение» не имеет смысла. Разве» приведение» не должно быть «ролью», которая отображается как значение во втором столбце? Разве имя столбца не должно быть чем-то вроде «имя» или «человек»? Итак, вам нужна запись в этой новой таблице для каждого человека в каждом фильме, верно? Так почему бы не повторить, как вы говорите? Что в этом плохого? Это будет хорошим упражнением, если вы начинающий программист. У вас есть вопрос? Не похоже, что ты об этом спрашивал.
2. Приношу свои извинения, когда я что-то исправлял, колонки сдвигались при копировании и вставке. Фиксирующий.
3. является ли актерский состав также ролью?
4. Да, актерский состав-это актер/актриса. Я хочу создать таблицу персон, в которой будет указана роль человека (продюсера, режиссера и т. Д.) Для фильма.
Ответ №1:
Один из способов избежать зацикливания-это использовать DataFrame.melt
и Series.str.split
.
Использование выборочных данных:
import pandas as pd
from io import StringIO
data = '''
movieid;director;cast
1;person 1, person 2, person 3;person 4, person 6, person 7
2;person 1, person 3;person 4, person 5, person 9, person 11
'''
df = pd.read_csv(StringIO(data), sep=';')
# movieid director cast
# 1 person 1, person 2, person 3 person 4, person 6, person 7
# 2 person 1, person 3 person 4, person 5, person 9, person 11
melt
вmovie
/role
/names_csv
:
df = df.melt(id_vars='movieid', var_name='role', value_name='names_csv')
# movieid role names_csv
# 1 director person 1, person 2, person 3
# 2 director person 1, person 3
# 1 cast person 4, person 6, person 7
# 2 cast person 4, person 5, person 9, person 11
split
names_csv
строки в развернутые столбцы:
df = (df.names_csv.str.split(r',s*', expand=True)
.join(df[['movieid', 'role']]))
# 0 1 2 3 movieid role
# person 1 person 2 person 3 None 1 director
# person 1 person 3 None None 2 director
# person 4 person 6 person 7 None 1 cast
# person 4 person 5 person 9 person 11 2 cast
melt
снова, на этот раз вmovie
/role
/name
(при желании с некоторым удалением и сортировкой):
df = (df.melt(id_vars=['movieid', 'role'], value_name='name')
.drop('variable', axis=1).dropna()
.sort_values(['movieid', 'role'], ascending=[True, False], ignore_index=True))
# movieid role name
# 1 director person 1
# 1 director person 2
# 1 director person 3
# 1 cast person 4
# 1 cast person 6
# 1 cast person 7
# 2 director person 1
# 2 director person 3
# 2 cast person 4
# 2 cast person 5
# 2 cast person 9
# 2 cast person 11