同时计算行和列

时间:2019-07-29 18:17:32

标签: python-3.x pandas numpy-ndarray

我正在尝试对python中的行和列进行一些计算。对于大型数据集,执行该过程将花费更长的时间。

我正在尝试进行如下计算:

Df =pd.DataFrame({'A': [1,1,1,2,2,2,2],
                   'unit': [1,2,1,1,1,1,2],
                   'D1':[100,100,100,200,300,400,3509],
                   'D2':[200,200,200,300,300,400,2500],
                   'D3':[50,50,50,60,50,67,98],
                   'Level1':[1,4,0,4,4,4,5],
                   'Level2':[45,3,0,6,7,8,9],
                   'Level3':[0,0,34,8,7,0,5]
                 })

对于A的每个值(在上面的示例中A = 1和2),我依次运行一个函数(即,由于A的结果,我无法同时对A = 1和A = 2运行相同的函数= 1会更改A = 2的其他一些值)。我计算的得分为:

def score(data):
    data['score_Level1']=np.where(data['Level1']>=data['unit'], data['unit'], 0)*(((np.where(data['Level1']>=data['unit'], data['unit'], 0)).sum()*100) +(10/data['D1']))
    data['score_Level2']=np.where(data['Level2']>=data['unit'], data['unit'], 0)*(((np.where(data['Level2']>=data['unit'], data['unit'], 0)).sum()*100) +(10/data['D2']))
    data['score_Level3']=np.where(data['Level3']>=data['unit'], data['unit'], 0)*(((np.where(data['Level3']>=data['unit'], data['unit'], 0)).sum()*100) +(10/data['D3']))

    return(data)

上面的代码所做的是,它逐行给出Leveli(i = 1,2,3)的得分,如下所示:

Step1:
compare Value of "Leveli' with corresponding "unit" column, if Leveli >=unit then unit else 0. 

Step2:
Then it (sums up result for above operation across all rows for Leveli)*100+ (1/Di) = Lets say "S"

Step3:
It goes row by row again and assign a score for Leveli as:

Step1*Step2 (for each row)

Above code should yield results for A=1 as:

score(Df[Df['A']==1])

I am listing only scoring for Level1, same thing happends for Level2 and Level3
Step1:
Compare 1>=1 = True Yields 1, 4>=2 = true Yields 2, 0>=1 =False Yields 0

Step2:
(1+2+0)*100+1/100=300.1

Step3:
Compare 1>=1 = True Yields 1 *300.1=300.1
Compare 4>=2 = True Yields 2 *300.1=600.2
Compare 0>=1 = False Yields 0 *300.1=0

我正在为2亿个A值进行此活动。由于必须按顺序进行(A = n取决于A = n-1的结果),因此计算需要很长时间。

任何使它更快的建议都受到赞赏。

1 个答案:

答案 0 :(得分:0)

我认为,您可以避免运行速度更快的位置。 您可以尝试以下代码吗?

def score2(data, score_field, level_field, d_field):
    indexer= data[level_field]>=data['unit']
    data[score_field]= 0.0
    data.loc[indexer, score_field]= data['unit'] * data.loc[indexer, 'unit'].sum()*100 + 10/data[d_field]
    return(data)

score2(Df, 'score_Level1', 'Level1', 'D1')
score2(Df, 'score_Level2', 'Level2', 'D2')
score2(Df, 'score_Level3', 'Level3', 'D3')

.loc与索引器一起替换了where。在分配的左侧,它将仅为“级别字段”大于unit的行设置值。所有其他人保持原样。如果没有行data[score_field]= 0.0,它们将包含NaN。 顺便说一句。熊猫有自己的.where方法,该方法适用于系列。它与numpy实现略有不同。