【问题标题】:Comparing pandas Dataframe columns values one by one一一比较熊猫数据框列的值
【发布时间】:2018-01-05 06:35:21
【问题描述】:

df

        Date    Factory I1  D1  I2  D2  I3  D3

   0    1701    West    0   0   0   0   10  0

   1    1701    East    39  0   83  15  3   15

   2    1701    West    0   0   0   10  15  0

我想要这个:

 If D2>I2 Then I3=I2+I3,D3=D2+D3,I2=D2=0

 If D3>I3 Then I2=I2+I3,D2=D2+D3,I3=D3=0

没有变化

所以数据应该是这样的:

df

     Date   Factory I1  D1  I2  D2  I3  D3

     0  1701    West    0   0   0   0   10  0

     1  1701    East    39  0   86  30  0   0

     2  1701    West    0   0   0   0   15  10

我该怎么办?请帮忙~

【问题讨论】:

    标签: python pandas dataframe compare


    【解决方案1】:

    你需要maskassign

    m1 = df.D2 > df.I2
    m2 = df.D3 > df.I3
    df = df.mask(m1, df.assign(I3=df.I2+df.I3, D3=df.D2+df.D3, I2=0, D2=0))
    df = df.mask(m2, df.assign(I2=df.I2+df.I3, D2=df.D2+df.D3, I3=0, D3=0))
    print (df)
       Date Factory  I1  D1  I2  D2  I3  D3
    0  1701    West   0   0   0   0  10   0
    1  1701    East  39   0  86  30   0   0
    2  1701    West   0   0   0   0  15  10
    

    如果有带空格的列:

    m1 = df.D2 > df.I2
    m2 = df.D3 > df.I3
    
    def f1(x):
        df['I3']=df.I2+df.I3 
        df['D3']=df.D2+df.D3 
        df['I2'] = df['D2'] = 0
        return df
    
    def f2(x):
        df['I2']=df.I2+df.I3 
        df['D2']=df.D2+df.D3 
        df['I3'] = df['D3'] = 0
        return df
    
    df = df.mask(m1, f1)
    df = df.mask(m2, f2)
    print (df)
       Date Factory  I1  D1  I2  D2  I3  D3
    0  1701    West   0   0  10   0   0   0
    1  1701    East  39   0  86  30   0   0
    2  1701    West   0   0  15  10   0   0
    

    或者如果想使用assignI3 改为I 3):

    m1 = df['D2'] > df['I2']
    m2 = df['D3'] > df['I 3']
    
    d1 = {'I 3': lambda x: x['I2'] + x['I 3'],'D3':lambda x: x['D2']+x['D3'],'I2':0,'D2':0}
    d2 = {'I2': lambda x: x['I2'] + x['I 3'],'D2':lambda x: x['D2']+x['D3'],'I3':0,'D3':0}
    df = df.mask(m1, df.assign(**d1))
    df = df.mask(m2, df.assign(**d2))
    print (df)
       Date Factory  I1  D1  I2  D2  I 3  D3
    0  1701    West   0   0   0   0   10   0
    1  1701    East  39   0  86  30    3   0
    2  1701    West   0   0   0   0   15  10
    

    【讨论】:

    • 另一个问题:现在列名是I3,D3。当它们成为 Input 第三 , Defect 第三,这怎么行?列名中有一个空格...
    【解决方案2】:

    可以使用易于理解的for 循环并处理每一行:

    newvals = []
    for i in range(len(df.index)):
        ROW = df.iloc[i,:]
        if ROW.D2>ROW.I2:
            ROW.I3=ROW.I2+ROW.I3
            ROW.D3=ROW.D2+ROW.D3
            ROW.I2=ROW.D2=0 
        if ROW.D3>ROW.I3:
            ROW.I2=ROW.I2+ROW.I3
            ROW.D2=ROW.D2+ROW.D3
            ROW.I3=ROW.D3=0
        newvals.append(list(ROW))
    newdf = pd.DataFrame(data=newvals, columns=df.columns)
    print(newdf)
    

    输出:

       Date Factory  I1  D1  I2  D2  I3  D3
    0  1701    West   0   0   0   0  10   0
    1  1701    East  39   0  86  30   0   0
    2  1701    West   0   0   0   0  15  10
    

    【讨论】:

    • 在我看来可能的解决方案,但是 pandas 中最好的方法是避免循环,因为速度很慢。
    • 是的,它更容易理解,但正如 jezrael 所说,它并不快。 TKU都一样!
    • 标题中的“一个接一个”是什么意思?
    猜你喜欢
    • 2017-01-27
    • 1970-01-01
    • 2021-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-28
    • 2021-12-06
    相关资源
    最近更新 更多