#pandas
#pandas
Вопрос:
Я пытался использовать pd.melt с фреймом данных, как показано ниже.
MRN Name Dt1 Nam1 Loc1 Dt2 Nam2 Loc2 Dt3 Nam3 Loc3
0 1234 John 2010-01-01 CMV Eye 2010-02-10 RSV Res 2010-03-10 HSV Eye
1 1245 Joe 2011-06-10 Cdiff GI NaT NaN NaN NaT NaN NaN
2 1235 Mary 2012-05-06 Ecoli Bld NaT NaN NaN NaT NaN NaN
3 1254 Matt NaT NaN NaN NaT NaN NaN NaT NaN NaN
чтобы получить результат, как показано ниже
MRN Name Dt Nam Loc
0 1234 John 2010-01-01 CMV Eye
1 1234 John 2010-02-10 RSV Res
2 1234 John 2010-03-10 HSV Eye
3 1245 Joe 2011-06-10 Cdiff GI
4 1235 Mary 2012-05-06 Ecoli Bld
5 1254 Matt NaT NaN NaN
Я не смог этого сделать.
Ответ №1:
Вы можете сделать это без pd.melt
, подготовив каждый набор столбцов, а затем используя pd.concat
для их подключения:
dfs = []
for i in range(1, 4):
tmp_df = df[["MRN", "Name", f"Dt{i}", f"Nam{i}", f"Loc{i}"]]
tmp_df = df.rename(columns={f"Dt{i}": "Dt", f"Name{i}": "Nam", f"Loc{i}": "Loc"})
dfs.append(tmp_df.dropna()) # dropna to remove rows with NaN.
df = pd.concat(dfs)
Или, если вы хотите, чтобы это было очень длинным вкладышем:
df = pd.concat([df[["MRN", "Name", f"Dt{i}", f"Nam{i}", f"Loc{i}"]].rename(columns={f"Dt{i}": "Dt", f"Name{i}": "Nam", f"Loc{i}": "Loc"}).dropna() for i in range(1, 4)])
Ответ №2:
Возможно, вам придется жестко запрограммировать фильтрацию, чтобы она соответствовала ожидаемому результату :
(
pd.wide_to_long(df, stubnames=["Dt", "Nam", "Loc"], i=["MRN", "Name"], j="num")
.reset_index()
.sort_values(["Dt", "num"])
.drop('num', 1)
.loc[:9]
)
MRN Name Dt Nam Loc
0 1234 John 2010-01-01 CMV Eye
1 1234 John 2010-02-10 RSV Res
2 1234 John 2010-03-10 HSV Eye
3 1245 Joe 2011-06-10 Cdiff GI
6 1235 Mary 2012-05-06 Ecoli Bld
9 1254 Matt NaN NaN NaN