Создание многоиндексированного фрейма данных из других значений фрейма данных с различными показателями

#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)
 

Выход:

введите описание изображения здесь