2014-11-03 2 views
0

У меня есть фрейм данных pandas, который содержит для нескольких позиций (определяемых координатой x) значение для разных временных меток. Я хочу создать объект pandas.Series, который содержит значение в заданной позиции x для всех временных меток (так что все индексы-данные для фрейма). Если x не является одной из ярлыков столбцов, я хочу интерполировать между двумя ближайшими значениями x.Выбор серии из базы данных pandas путем интерполяции ярлыков столбцов

Отрывок из объекта dataframe (min(x)=0 и max(x)=0.28):

  0.000000 0.007962 0.018313 0.031770 0.049263 0.072004 
time (s)                
15760800 0.500481 0.500481 0.500481 0.500481 0.500481 0.500481 
15761400 1.396126 0.487198 0.498765 0.501326 0.500234 0.500544 
15762000 1.455313 0.542441 0.489421 0.502851 0.499945 0.500597 
15762600 1.492908 0.592022 0.487835 0.502233 0.500139 0.500527 
15763200 1.521089 0.636743 0.490874 0.500704 0.500485 0.500423 
15763800 1.542632 0.675589 0.496401 0.499065 0.500788 0.500335 

я могу найти способы Нарезать dataframe по имеющимся заголовков столбцов. Но есть ли элегантный способ сделать интерполяцию?

В конце я хочу функцию, которая выглядит примерно так: result = sliceDataframe(dataframe=dfin,x=0.01), с результатом pandas.Series объект, поэтому я могу вызвать его в одной строке (или, возможно, в двух) в другом сценарии постпроцессинга.

ответ

1

Я думаю, вам было бы лучше всего написать простую функцию. Что-то вроде:

def sliceDataframe(df, x): 
    # supposing the column labels are sorted: 
    pos = np.searchsorted(df.columns.values, x) 

    # select the two neighbouring column labels: 
    left = df.columns[pos-1] 
    right = df.columns[pos] 

    # simple interpolation 
    interpolated = df[left] + (df[right] - df[left])/(right - left) * (x - left) 
    interpolated.name = x 
    return interpolated 

Другой вариант заключается в использовании метода interpolate, но таким образом, вы должны добавить колонку с NaNs с меткой вы хотите.
С функцией выше:

In [105]: df = pd.DataFrame(np.random.randn(8,4)) 

In [106]: df.columns = df.columns.astype(float) 

In [107]: df 
Out[107]: 
      0   1   2   3 
0 -0.336453 1.219877 -0.912452 -1.047431 
1 0.842774 -0.361236 -0.245771 0.014917 
2 -0.974621 1.050503 0.367389 0.789570 
3 1.091484 1.352065 1.215290 0.393900 
4 -0.100972 -0.250026 -1.135837 -0.339204 
5 0.503436 -0.764224 -1.099864 0.962370 
6 -0.599090 0.908235 -0.581446 0.662604 
7 -2.234131 0.512995 -0.591829 -0.046959 

In [108]: sliceDataframe(df, 0.5) 
Out[108]: 
0 0.441712 
1 0.240769 
2 0.037941 
3 1.221775 
4 -0.175499 
5 -0.130394 
6 0.154572 
7 -0.860568 
Name: 0.5, dtype: float64 

С помощью метода interpolate:

In [109]: df[0.5] = np.NaN 

In [110]: df.sort(axis=1).interpolate(axis=1) 
Out[110]: 
     0.0  0.5  1.0  2.0  3.0 
0 -0.336453 0.441712 1.219877 -0.912452 -1.047431 
1 0.842774 0.240769 -0.361236 -0.245771 0.014917 
2 -0.974621 0.037941 1.050503 0.367389 0.789570 
3 1.091484 1.221775 1.352065 1.215290 0.393900 
4 -0.100972 -0.175499 -0.250026 -1.135837 -0.339204 
5 0.503436 -0.130394 -0.764224 -1.099864 0.962370 
6 -0.599090 0.154572 0.908235 -0.581446 0.662604 
7 -2.234131 -0.860568 0.512995 -0.591829 -0.046959 

In [111]: df.sort(axis=1).interpolate(axis=1)[0.5] 
Out[111]: 
0 0.441712 
1 0.240769 
2 0.037941 
3 1.221775 
4 -0.175499 
5 -0.130394 
6 0.154572 
7 -0.860568 
Name: 0.5, dtype: float64 
+0

Я не хочу, чтобы настроить dataframe с фиктивной точки. Можно ли использовать опцию интерполяции без добавления столбца? Если нет, то я думаю, что пойду за первым решением. – tvandenbrande

+0

Нет, метод интерполяции pandas всегда заполняет NaN в DataFrame. Но, возможно, это было бы возможно с использованием метода базового метода scipy-интерполяции. Но поскольку сама интерполяция является лишь одной строкой для простой линейной интерполяции после того, как вы выбрали два соседних столбца, я не знаю, что это стоит того. – joris

+0

реализовал первый вариант, который работает отлично и достаточно быстро для последующей обработки. спасибо – tvandenbrande

Смежные вопросы