2015-01-10 3 views
1

У меня есть кадр данных, который структурирован аналогично следующему (но в реальном случае с большим количеством строк и столбцов).Анализ парных элементов в DataFrame

In [2]: Ex # The example DataFrame 
Out[2]: 
     NameBef v1B v2B v3B v4B NameAft v1A v2A v3A v4A 
Id                 
422 firstBef 133 145 534 745 FirstAft 212 543 2342 4563 
862 secondBef 234 434 345 3453 SecondAft 643 493 3433 234 
935 thirdBef 232 343 6454 463 thirdAft 423 753 754 743 

Для каждой строки я хочу, чтобы вычислить частное значение каждого VXB и VXA из выше (Xs являются переменными), чтобы в конечном итоге с DataFrame как этот

  v1Q  v2Q  v3Q  v4Q 
Id           
422 1.593985 3.744828 4.385768 6.124832 
862 2.747863 1.135945 9.950725 0.067767 
935 1.823276 2.195335 0.116827 1.604752 

где каждый элемент является фактор соответствующих элементов исходного кадра данных.

Я не смог выяснить, как это сделать удобно.

Для удобства было бы полезно, если бы не требовалось указывать только имена первого и последнего столбцов значений «до» и «после», то есть «v1B», «v4B» и «v1A», , 'v4A' (т.е. не каждый из столбцов).

Следующее - это то, что я придумал.

In [3]: C=Ex.columns 
In [4]: C1B=C.get_loc('v1B') 
In [5]: C2B=C.get_loc('v4B') 
In [6]: C1A=C.get_loc('v1A') 
In [7]: C2A=C.get_loc('v4A') 
In [8]: FB=Ex.ix[:,C1B:C2B+1] 
In [9]: FA=Ex.ix[:,C1A:C2A+1] 

In [10]: FB   # The FB and FA frames have this structure 
Out[10]: 
    v1B v2B v3B v4B 
Id      
422 133 145 534 745 
862 234 434 345 3453 
935 232 343 6454 463 

[3 rows x 4 columns] 

Затем, наконец, создайте требуемый DataFrame. Это делается путем вычисления на массивах numpy, созданных DataFrame.values.

Этот метод я получил от этого question/answer:

In [12]: DataFrame((FA.values*1.0)/FB.values,columns=['v1Q','v2Q','v3Q','v4Q'],index=Ex.index) 
Out[12]: 
      v1Q  v2Q  v3Q  v4Q 
Id           
422 1.593985 3.744828 4.385768 6.124832 
862 2.747863 1.135945 9.950725 0.067767 
935 1.823276 2.195335 0.116827 1.604752 

[3 rows x 4 columns] 

ли я что-то отсутствует? Я надеялся, что смогу добиться этого гораздо более прямым путем, выполнив некоторую операцию над исходным DataFrame.

Не существует ли операции для простого вычисления непосредственно в DataFrames вместо перехода через массивы numpy?

ответ

1

Вы всегда можете использовать df.filter, чтобы выбрать соответствующие имена столбцов. Он может принимать регулярное выражение, так что вы могли бы указать после/до колонки с чем-то вроде этого:

>>> df.filter(regex=r'^v.A$').values/df.filter(regex=r'^v.B$').values 
array([[ 1.59398496, 3.74482759, 4.38576779, 6.12483221], 
     [ 2.74786325, 1.1359447 , 9.95072464, 0.06776716], 
     [ 1.82327586, 2.19533528, 0.11682677, 1.60475162]]) 

Что касается арифметической операции, вы не пропуская ничего. Здесь необходимо использовать массивы Numpy (.values), так как иначе Pandas вычисляет значения из общих меток индексов в обоих DataFrames. Если индекс отсутствует, результаты вычислений составляют NaN. Массивные массивы не имеют индексов с метками, поэтому операция с использованием элементов выполняется успешно.

+0

Ничего себе, что, безусловно, намного компактнее. Избавьтесь от всего этого удаления колонки вручную. Мне просто нужно выбрать имена столбцов, которые легко отфильтровать так, как вы описываете. Также спасибо за подтверждение того, что операция numpy правильная. – Wurdius

+0

Не проблема, рада слышать 'фильтр' может помочь. –

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