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()
对比后两列,一致!?
抽查一些值,根据计算规则手动算一算 ,对比表中代码给出的值,一致!?
完美~~~