2015-01-23 2 views
0

У меня есть dataframe, который имеет следующую основную структуру:Применяя функцию к каждой строке панд кадра данных - со скоростью

import numpy as np 
import pandas as pd 
tempDF = pd.DataFrame({'condition':[0,0,0,0,0,1,1,1,1,1],'x1':[1.2,-2.3,-2.1,2.4,-4.3,2.1,-3.4,-4.1,3.2,-3.3],'y1':[6.5,-7.6,-3.4,-5.3,7.6,5.2,-4.1,-3.3,-5.7,5.3],'decision':[np.nan]*10}) 
print tempDF 
    condition decision x1 y1 
0   0  NaN 1.2 6.5 
1   0  NaN -2.3 -7.6 
2   0  NaN -2.1 -3.4 
3   0  NaN 2.4 -5.3 
4   0  NaN -4.3 7.6 
5   1  NaN 2.1 5.2 
6   1  NaN -3.4 -4.1 
7   1  NaN -4.1 -3.3 
8   1  NaN 3.2 -5.7 
9   1  NaN -3.3 5.3 

В каждой строке, я хочу, чтобы изменить значение столбца «решения», чтобы ноль, если столбец «условие» равен нулю и если «x1» и «y1» являются одинаковыми знаками (положительными или отрицательными) - для целей этого сценария нуль считается положительным. Если знаки «x1» и «y1» различны или столбец «условие» равен 1 (независимо от знаков «x1» и «y1»), столбец «решение» должен равняться 1. Надеюсь, я так ясно объяснил это.

я могу перебирать каждую строку dataframe следующим образом:

for i in range(len(tempDF)): 
    if (tempDF.ix[i,'condition'] == 0 and ((tempDF.ix[i,'x1'] >= 0) and (tempDF.ix[i,'y1'] >=0)) or ((tempDF.ix[i,'x1'] < 0) and (tempDF.ix[i,'y1'] < 0))): 
     tempDF.ix[i,'decision'] = 0 
    else: 
     tempDF.ix[i,'decision'] = 1 

print tempDF 
      condition decision x1 y1 
     0   0   0 1.2 6.5 
     1   0   0 -2.3 -7.6 
     2   0   0 -2.1 -3.4 
     3   0   1 2.4 -5.3 
     4   0   1 -4.3 7.6 
     5   1   1 2.1 5.2 
     6   1   1 -3.4 -4.1 
     7   1   1 -4.1 -3.3 
     8   1   1 3.2 -5.7 
     9   1   1 -3.3 5.3 

Это дает правильный вывод, но это немного медленно. Реальный фрейм данных, который у меня есть, очень велик, и эти сравнения нужно будет делать много раз. Есть ли более эффективный способ достижения желаемого результата?

ответ

1

Во-первых, использовать np.sign и операторы сравнения, чтобы создать булево массив, который True, где решение должно быть 1:

decision = df["condition"] | (np.sign(df["x1"]) != np.sign(df["y1"])) 

Здесь я использовал законы де Моргана.

Тогда приведение к int и положить его в dataframe:

df["decision"] = decision.astype(int) 

Давать:

>>> df 
    condition decision x1 y1 
0   0   0 1.2 6.5 
1   0   0 -2.3 -7.6 
2   0   0 -2.1 -3.4 
3   0   1 2.4 -5.3 
4   0   1 -4.3 7.6 
5   1   1 2.1 5.2 
6   1   1 -3.4 -4.1 
7   1   1 -4.1 -3.3 
8   1   1 3.2 -5.7 
9   1   1 -3.3 5.3 
+0

Круто! Спасибо. – user1718097

+0

Очень незначительная точка. Вместо этого я мог бы использовать np.signbit(), чтобы нулевые значения включались в положительные значения. – user1718097

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