顺序处理依赖性中的Python代码

时间:2018-12-18 20:15:56

标签: python pandas numpy dataframe

我是Python的新手,并且在我的代码之一中遇到了性能问题。

我有2个数据帧(例如Df1和Df2)。

Df1 = pd.DataFrame({'A': [1,1,1,2,3,3,4,4,4,5,5],
                   'B':['P1','P2','P3','P1','P4','P2','P1','P6','P3','P2','P8'],
                   'C': [1,2,1,2,1,3,1,1,2,3,2],
                   'D':[100,100,100,200,300,300,400,400,400,500,500],
                   'E':[200,200,200,50,100,100,100,100,100,100,100],
                   'F':[50,50,50,50,150,150,100,100,100,333,333]})

Df2 =pd.DataFrame({'B':['P1','P2','P3','P4','P5','P6','P7','P8','P9','P10'],
                   'L1':[1,4,0,0,2,3,6,56,5,0],
                   'L2':[45,3,0,10,2,4,6,1,6,10],
                   'L3':[0,0,34,10,24,13,19,6,10,10]})

我想做的是一次处理A的1值(即始终在A = 2之前处理A = 1)。这样做的原因是在A = 1时,我正在寻找Df2中的B值(A = 1具有P1,P2和P3,并且我通过加入Df1从Df2中获取了P1,P2和P3的L1,L2和L3和Df2)。基于对L1,L2,L3和C,D,E,F的值的一些计算。我为A = 1中的每一行分配一个决策,即L1,L2或L3。例如,假设对于A = 1,分配看起来像这样:

Df3= pd.DataFrame({'A': [1,1,1],
                   'B': ['P1','P2','P3'],
                   'C': [1,2,1],
                   'D':[100,100,100],
                   'E':[200,200,200],
                   'F':[50,50,50],
                   'L1':[1,4,0],
                   'L2':[45,3,0],
                   'L3':[0,0,34],
                   'Decision':['L1','L1','L3']})

现在,由于A = 1的决定是L1,L1和L3,它将继续进行并从Df2中减去C的值 即它将从Df2(P1,L1)= 1-1 = 0中减去1,从Df2(P2,L1)= 4-2 = 2中减去2,从Df2(P3,L3)= 34-1 = 33中减去1 因此更新后的Df2将如下所示:

Df2 =pd.DataFrame({'B':['P1','P2','P3','P4','P5','P6','P7','P8','P9','P10'],
                   'L1':[0,2,0,0,2,3,6,56,5,0],
                   'L2':[45,3,0,10,2,4,6,1,6,10],
                   'L3':[0,0,33,10,24,13,19,6,10,10]})

对于A = 2重复相同的循环,依此类推。由于A = 1的决定改变了Df2,因此它改变了A = 2的结果,依此类推。到目前为止,我正在为每个A运行循环

我有大约2亿条记录的数据集Df1,其中有2500万个不同的A值。Df2是50万条记录。我将循环运行了2500万次,总运行时间约为12天。我尝试在Df1和Df2上建立索引/ faster联接,根据一些规则对Df1进行子集设置,但这并没有太大帮助(它仅将运行时间缩短了2-3天)

有没有更快的方法来进行此活动?尤其是没有运行循环,但仍会顺序处理A的每个值(因为先前的决策会更改未来的决策)

预先感谢您的建议。

1 个答案:

答案 0 :(得分:0)

我在下面发布了我的代码。尽管它不预先使用任何for循环,但我不知道这是否可以帮助您摆脱时间限制。祝你好运!

df3 = df1.merge(df2, on="B")
# Your decison maker
import random
def f(x=1):
    return random.choice(['L1', 'L2', 'L3'])

df3["Decision"] = df3.apply(lambda x: f(x),axis=1)
df3.sort_values(by='A').reset_index(drop=True, inplace=True)

def ff(x):
    global df2
    df2.loc[df2.B == x.B, x.Decision] -= x.C
    return 

a = df3[["B", "Decision", "C"]].apply(lambda x: ff(x), axis=1)

df2

enter image description here enter image description here enter image description here

请告诉我们这是否会使2亿条记录变得更容易(我会在后面拍一下自己:P)