#python #pandas #melt
Вопрос:
У меня есть фрейм данных, к которому нужно поворачиваться дольше:
import pandas as pd import io _1 = pd.read_csv(io.StringIO( """date; origin; val_one; val_two; aaa; bbb; ccc; ddd; eee; fff 10/11/2009; aaa; 1; 0; 0; 0; 0; 0; 1; 0 10/11/2009; bbb; 0; 1; 1; 0; 0; 0; 0; 1 10/11/2009; ccc; 0; 1; 0; 0; 0; 0; 0; 0 10/11/2009; ddd; 0; 2; 0; 1; 1; 1; 0; 0"""), sep=";").set_axis(['date', 'origin', 'val_one', 'val_two', 'aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff'], axis=1)
Теперь я хочу создать исходно-целевые (строки aaa
: fff
) диады. Строки , в которых нет цели (т. е. ни один из целевых столбцов не является 1
, например, третьей строкой, индекс 2), должны быть удалены; строки, в которых существует более одной цели (например, вторая строка, индекс 1, где aaa
находится 1
и fff
является одним из целевых столбцов 1
), должны быть превращены в две строки. Ожидаемый результат составляет:
_2_targ = pd.read_csv(io.StringIO( """date; origin; val_one; val_two; target 10/11/2009; aaa; 1; 0; eee 10/11/2009; bbb; 0; 1; aaa 10/11/2009; bbb; 0; 1; fff 10/11/2009; ddd; 0; 2; bbb 10/11/2009; ddd; 0; 2; ccc 10/11/2009; ddd; 0; 2; ddd"""), sep=';').set_axis(['date', 'origin', 'val_one', 'val_two', 'target'])
Я пытался использовать pd.melt
безрезультатно (см. Ниже) — это создает все диады, даже те, которые я не хочу сохранять (потому что целевого столбца нет 1
).
_2 = pd.melt(_1, id_vars=['date', 'origin', 'val_one', 'val_two'], value_vars=['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff'], var_name='target', value_name='tmp')
Что я упускаю?
Комментарии:
1.
output = _2[_2["tmp"].gt(0]].drop("tmp",1)
Ответ №1:
Я верю, что вы можете расплавиться точно так же, как вы это делаете, а затем удалить строки из вашего long_df, которые имеют значение 0 для tmp
import pandas as pd import io #nice reproducible input! df1 = pd.read_csv(io.StringIO( """date; origin; val_one; val_two; aaa; bbb; ccc; ddd; eee; fff 10/11/2009; aaa; 1; 0; 0; 0; 0; 0; 1; 0 10/11/2009; bbb; 0; 1; 1; 0; 0; 0; 0; 1 10/11/2009; ccc; 0; 1; 0; 0; 0; 0; 0; 0 10/11/2009; ddd; 0; 2; 0; 1; 1; 1; 0; 0"""), sep=";").set_axis(['date', 'origin', 'val_one', 'val_two', 'aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff'], axis=1) #Melt exactly the same as you did long_df = pd.melt( df1, id_vars=['date', 'origin', 'val_one', 'val_two'], value_vars=['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff'], var_name='target', value_name='tmp' ) #Filter out rows where tmp is 0, sort to match your output, and drop the tmp column long_df = long_df[long_df['tmp'].gt(0)].sort_values('origin').drop(columns='tmp').reset_index(drop=True) long_df
Результат почти такой, как вы показываете выше, но я думаю, что вы забыли bbb:fff
строку
date origin val_one val_two target 0 10/11/2009 aaa 1 0 eee 1 10/11/2009 bbb 0 1 aaa 2 10/11/2009 bbb 0 1 fff 3 10/11/2009 ddd 0 2 bbb 4 10/11/2009 ddd 0 2 ccc 5 10/11/2009 ddd 0 2 ddd
Я также переименовал ваши переменные, но это, очевидно, не важно
Комментарии:
1. Спасибо. Также вы были правы насчет вывода: вывод, данный вашим ответом, верен, я обновил ошибку в вопросе.