#python #pandas #dataframe #multi-index
Вопрос:
У меня есть фрейм данных (dfA), состоящий из нескольких файлов. dfA содержит три элемента: значение даты, соответствующее другим значениям даты в dfA, имя из списка неизвестного числа имен, которое будет совпадать с другими именами в dfA, и уникальное значение концентрации. Я хочу создать новый фрейм данных (dfB), где строки многоиндексированы по дате, столбцы-это имена, а значения-концентрация из указанного значения имени. Я попытался сделать это, используя приведенный ниже код:
for name in nameList:
dfB[str(name)] = dfA[dfA['Sample Name'] == str(name)]['Calculated Concentration']
Однако я возвращаюсь с фреймом данных, в котором заполнена только первая строка, что, как я полагаю, связано с тем, что значения индекса отличаются от значений других столбцов:
'5/0.5 uM' '10/1 uM' '15/1.5 uM'
083021 14 4.7886 NaN NaN
15 4.5374 NaN NaN
...
090721 14 5.2840 NaN NaN
15 5.3050 NaN NaN
...
083121 57 5.2132 NaN NaN
58 4.8929 NaN NaN
...
В приведенном выше выводе крайний левый столбец является многоиндексированным столбцом значений по дате. Следующий столбец содержит индексы исходного dfA. Тогда «5/0, 5 МКМ» — это значение из «списка имен», которое содержит значения, найденные в исходном dfA с «Именем образца «»5/0, 5 МКМ».
Как я могу создать dfB, где другие столбцы имеют правильные значения, или изменить значения индекса из dfA, где они будут совпадать для каждого столбца?
Комментарии:
1. Что это за колонка красного цвета, которая начинается (14, 15,…)?
2. @butterflyknife Это значения индекса значений, найденных в dfA, которые имеют название «5/0, 5 мкм».
Ответ №1:
Возможно, в дальнейшем вам будет проще переформатировать свои даты в переменные даты и времени, а не в строки. С учетом сказанного, настройте тест:
dfA = pd.DataFrame({
"date":["090721","083021","090721","083021","083121","083021","083121","083021","083121","083121"],
"name":["15/1.5 uM","15/1.5 uM","15/1.5 uM","15/1.5 uM","5/0.5 uM","5/0.5 uM","15/1.5 uM","5/0.5 uM","10/1 uM","10/1 uM"],
"concentration":[0.430896003263987,0.354506173988912,0.679630142573769,0.816498937365697,0.134105578748551,0.364977945903234,0.602557291467607,0.633223692609049,2.59697726598929E-02,0.206455687221982]
})
dfA["index"] = dfA.index # copy index over to a column called index, for reasons that will be clearer soon.
dfA
Обратите внимание, что для каждой комбинации необязательно указывать строку (дата, имя). Чтобы получить то, что вы описали:
pd.pivot_table(dfA, values="concentration", index=["date", "index"], columns=["name"],aggfunc=np.mean)
Выход:
Вы можете видеть, что есть NaN
s. Они соответствуют «пробелам» в начальном кадре данных, как описано ранее. Обратите внимание, что мы использовали функцию агрегирования, np.mean
, но это не имеет никакого значения, потому что мы выбрали нашу переиндексацию таким образом, чтобы в каждой строке было только одно значение концентрации для «агрегирования».
Вы не просили об этом, но вы также можете найти полезным использовать среднее значение строк, у которых одна и та же дата и имя? Просто удалите «индекс» из спецификации с несколькими индексами:
pd.pivot_table(dfA, values="concentration", index=["date"], columns=["name"],aggfunc=np.mean)
Выход: