Как я могу извлечь пары x и y из кадра данных pandas для последующего использования в symfit? - PullRequest
2 голосов
/ 22 мая 2019

Я использую панды для чтения в .csv файлах. Затем я беру пары x и y из кадра данных и использую symfit, чтобы выполнить глобальное сопоставление данных. Я новичок в pandas датафреймах и symfit. Мой текущий проверочный код работает для двух наборов данных, но я хочу написать его так, чтобы он работал для всех наборов данных, импортированных из исходного файла .csv, который всегда будет в одном и том же формате. -колонки всегда будут парами значений x и y в формате x1, y1, x2, y2, и т. д.

Могу ли я перебрать кадр данных и вытащить отдельные массивы для x1, y1, x2, y2, и т. Д.? Означает ли это побеждать цель использования данных?

    # creating the dataframe

        from pandas import read_csv, Series, DataFrame, isnull

        data_file = read_csv(filename, header=None, skiprows=2) # no data in first two rows--these contain information I use later on for plotting

    # important note: data sets contain different numbers of points, so pandas reads in nan for any missing values.

        X1 = Series(data_file[0]).values
        X1 = x_1[~isnull(x_1)] # removes any nan values (up for any suggestions on a better way to do this. Other methods I have tried remove entire rows or columns that contain nan)

        Y1 = Series(data_file[1]).values
        Y1 = y_1[~isnull(y_1)]

        X2 = Series(data_file[2]).values
        X2 = x_2[~isnull(x_2)]

        Y2 = Series(data_file[3]).values
        Y2 = y_2[~isnull(y_2)]

    # sample data 
    # X1 = [12.5, 6.7, 5, 3.1, 128, 47, 5, 3.1, 6.7, 12.5]
    # Y1 = [280, 150, 127, 85, 400, 401, 110, 96, 131, 241]
    # X2 = [75, 39, 10, 7.7, 19, 39, 75]
    # Y2 = [296, 257, 141, 100, 181, 254, 324] 

Отсюда я передаю X и Y классу, который содержит модель и функции подгонки symfit. Я не думаю, что могу объединить X и Y; Мне нужно, чтобы они оставались отдельными, чтобы symfit соответствовал отдельным кривым для каждого набора данных (с четырьмя общими параметрами).

Ниже приведена модель, которую я использую. Я мог бы вырезать синтаксис Symfit. Я все еще изучаю symfit, но пока это было замечательно. Это согласование работает для двух наборов данных, и я могу извлечь параметры соответствия и представить результаты позже.

    # This model assumes two data sets. I need to figure out how to fit as many as 10 data sets.

        from symfit import parameters, variables, Fit, Model

        fi_1 = 0 # These parameters change with each x,y pair. These will also be read from the original data file. I have them hard-coded here for ease. 
        fi_2 = 1

        x_1, x_2, y_1, y_2 = variables('x_1, x_2, y_1, y_2')

        vmax, km, evk, ev = parameters('vmax, km, evk, ev') # these are all shared

        model = Model({
            y_1: vmax * x_1 / (km * (1 + (fi_1 * evk)) + x_1 * (1 + (fi_1 * ev))),
            y_2: vmax * x_2 / (km * (1 + (fi_2 * evk)) + x_2 * (1 + (fi_2 * ev)))})

        fit = Fit(model, x_1=X1, x_2=X2, y_1=Y1, y_2=Y2)
        fit_result = fit.execute()

РЕЗЮМЕ ЗАДАЧИ: Я мог бы иметь до 10 х, у пар, чтобы соответствовать одновременно. Существует ли простой способ перебора элементов данных, чтобы избежать жесткого кодирования массивов x и y, передаваемых в symfit?

1 Ответ

1 голос
/ 22 мая 2019

Оказывается, это было НАМНОГО проще, чем я думал.Я могу реструктурировать входной файл .csv так, чтобы в нем был один столбец для значений x, один для значений y и один для fi - параметра, который изменяется между наборами данных.Таким образом, все пары x, y, которые принадлежат друг другу, имеют соответствующее значение fi.Например, fi = 0 для всех пар x, y в первом наборе данных, и как только начинается второй набор данных, fi = 1. Я могу расширить его для любого числа пар x, y с другим значениемдля Fi.Теперь я могу эффективно использовать фрейм данных:

data_file = read_csv(filename, header=None, skiprows=1) #first row contains column labels now

Вот упрощенная модель:

x, y, fi = variables('x, y, fi') # set variables
vmax, km, evk, ev = parameters('vmax, km, evk, ev') # set shared parameters

model = Model({y: vmax * x / (km * (1 + (fi * evk)) + x *(1 + (fi * ev)))})

fit = Fit(model, x=data_file[0], y=data_file[1], fi=data_file[2])

fit_result = fit.execute()

Это работает и намного чище, чем я думал, что в итоге получится.Перестройка входных файлов для упрощения импорта данных очень помогает!

...