Python 進行 DataFrame 數據處理的過程中,需要判斷某一列中的值(條件),然後對其他兩列或三列進行求和(均值/最值)等運算,並把運算結果存儲在新的一列中。幹說可能覺得比較暈,我們來看一個例子:
下表 data_base 中,預測區間這一列共有 1/2/3/4 類值,現需要生成新列預測概率,新列的計算規則爲:
- 若預測區間=1,則求分類概率_1與分類概率_2的均值;
- 若預測區間=2/3,則求分類概率_1與分類概率_2與分類概率_3的均值;
- 若預測區間=4,則爲分類概率_1的值;
需求應該說清楚了,下面我們來看看根據上述計算規則,傳統的代碼怎麼寫。
傳統代碼思路:
iterrows() 遍歷 data_base 表,使用 for ... if ... elif ...計算預測概率的值,
import time
start_1 =time.clock()#記錄代碼開始運行時間
data_base[u'預測概率_1'] = 0#賦初始值
for index,row in data_base.iterrows():
if (row['預測區間'] == 1):
data_base.loc[index, '預測概率_1'] = ((data_base.loc[index, '分類概率_1'] + data_base.loc[index, '分類概率_2'])/2).astype(float)
elif (row['預測區間'] == 2) | (row['預測區間'] == 3):
data_base.loc[index, '預測概率_1'] = ((data_base.loc[index, '分類概率_1'] + data_base.loc[index, '分類概率_2']+data_base.loc[index, '分類概率_3'])/3).astype(float)
elif (row['預測區間'] == 4):
data_base.loc[index, '預測概率_1'] = ((data_base.loc[index, '分類概率_1'])).astype(float)
end_1 = time.clock()#記錄代碼結束運行時間
print('Running time: %s Seconds'%(end_1-start_1))#輸出耗時
輸出:Running time: 539.8234579883166 Seconds
一萬四千行數據,運行了將近十分鐘...........
下面來看看比他快 6 萬倍的代碼(思路:lambda...if...else(if...else...) 定義計算規則,然後使用 map() 函數做映射):
start_2 =time.clock()
a = data_base[u'預測區間'].tolist()
x = data_base[u'分類概率_1'].tolist()
y = data_base[u'分類概率_2'].tolist()
z = data_base[u'分類概率_3'].tolist()
b = list(map(lambda a, x, y, z: (x+y+z)/3 if (a==2)|(a==3) else ((x+y)/2 if a==1 else(x if a==4 else 0)),a, x, y, z))
b = pd.DataFrame(b, columns=['預測概率_2'])#轉化成dataframe格式
data_base = pd.concat([data_base, b['預測概率_2']], axis = 1, join='outer', sort=False)
end_2 = time.clock()
print('Running time: %s Seconds'%(end_2-start_2))
輸出:Running time: 0.009003164524415297 Seconds
539.823 / 0.009 ~~ 60000 (這可不就是快了 6 萬倍嘛!哈哈......)
下面我們看看求的結果是否一樣,不管代碼快了多少,如果算錯了那就沒有任何意義:
data_base_out = data_base[['級別', '行業', '年份', '預測區間',
'分類概率_1', '分類概率_2', '分類概率_3',
'預測概率_1','預測概率_2']]
data_base_out.head()
對比後兩列,一致!🆗
抽查一些值,根據計算規則手動算一算 ,對比表中代碼給出的值,一致!🆗
完美~~~