python - 减去单独列等于特定值的列

标签 python pandas

我希望减去单独列等于特定值的列。例如,当 Val == A 时,我想减去 A - B。但是,当 Val == B 时,我想减去 B - A

df = pd.DataFrame({ 
    'Val' : ['A','B','A','B','A','B'],                  
    'A_1' : [1, 2, 3, 4, 5, 6], 
    'A_2' : [2, 3, 4, 5, 6, 1],              
    'B_1' : [6, 5, 4, 3, 2, 1],
    'B_2' : [6, 5, 4, 3, 2, 1],                        
        })

for x in df['Val']:
    
    if x == 'A':
        
        df['1_Sum'] = df.iloc[:,-4] - df.iloc[:,-2]
        df['2_Sum'] = df.iloc[:,-4] - df.iloc[:,-2]
        
    elif x == 'B':
        
        df['1_Sum'] = df.iloc[:,-2] - df.iloc[:,-4]
        df['2_Sum'] = df.iloc[:,-2] - df.iloc[:,-4]

预期输出:

  Val  A_1  A_2  B_1  B_2  1_Sum  2_Sum
0   A    1    2    6    6     -5     -4
1   B    2    3    5    5      3      2 
2   A    3    4    4    4     -1      0
3   B    4    5    3    3     -1     -2
4   A    5    6    2    2      3      4
5   B    6    1    1    1     -5      0

最佳答案

使用numpy.select通过 DataFrame.filter 减去过滤列,对于 AB 组,每列的顺序和数量只需相同:

df1 = df.filter(like='A').sub(df.filter(like='B').to_numpy())
df2 = df.filter(like='B').sub(df.filter(like='A').to_numpy())
m1 = df['Val'].eq('A').to_numpy()[:, None]
m2 = df['Val'].eq('B').to_numpy()[:, None]

df3 = (pd.DataFrame(np.select([m1, m2], [df1, df2]), index=df.index)
         .rename(columns=lambda x: f'{x+1}_Sum'))
df = df.join(df3)
print (df)
  Val  A_1  A_2  B_1  B_2  1_Sum  2_Sum
0   A    1    2    6    6     -5     -4
1   B    2    3    5    5      3      2
2   A    3    4    4    4     -1      0
3   B    4    5    3    3     -1     -2
4   A    5    6    2    2      3      4
5   B    6    1    1    1     -5      0

如果想分别减去每个系列:

mask = df.Val=='A'

df["1_Sum"] = np.where(mask, df.A_1 - df.B_1,  df.B_1 - df.A_1)
df["2_Sum"] = np.where(mask, df.A_2 - df.B_2,  df.B_2 - df.A_2)

print (df)
  Val  A_1  A_2  B_1  B_2  1_Sum  2_Sum
0   A    1    2    6    6     -5     -4
1   B    2    3    5    5      3      2
2   A    3    4    4    4     -1      0
3   B    4    5    3    3     -1     -2
4   A    5    6    2    2      3      4
5   B    6    1    1    1     -5      0

编辑:

永远不要使用 apply 来减去值,因为在引擎盖下循环,所以非常慢,这里测试具有 6k 行的 DataFrame:

df = pd.DataFrame({ 
    'Val' : ['A','B','A','B','A','B'],                  
    'A_1' : [1, 2, 3, 4, 5, 6], 
    'A_2' : [2, 3, 4, 5, 6, 1],              
    'B_1' : [6, 5, 4, 3, 2, 1],
    'B_2' : [6, 5, 4, 3, 2, 1],                        
        })

df = pd.concat([df] * 1000, ignore_index=True)

df["1_Sum1"] = df.apply(lambda x: x.A_1 - x.B_1 if x.Val=='A' else x.B_1 - x.A_1, axis=1 )
df["1_Sum2"] = np.where(df.Val=='A', df.A_1 - df.B_1,  df.B_1 - df.A_1)


In [77]: %timeit df["1_Sum1"] = df.apply(lambda x: x.A_1 - x.B_1 if x.Val=='A' else x.B_1 - x.A_1, axis=1 )
271 ms ± 7.85 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [78]: %timeit df["1_Sum2"] = np.where(df.Val=='A', df.A_1 - df.B_1,  df.B_1 - df.A_1)
1.04 ms ± 4.22 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
    

关于python - 减去单独列等于特定值的列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62809219/

相关文章:

python - 从宽到长,但我想使用前缀而不是后缀

Python 在相同值上加入 Pandas 数据框的行并聚合字符串值

python - 使用 odbc_connect 从 SQLAlchemy 连接到 SQL 服务器

python - 如何创建多个空数据框?

php - 将 PHP 应用程序的一部分移植到 Python 会有助于扩展吗?

python - Scrapy:重复请求 440 状态代码

python - 将整个对象传递给它的参数是否可以?

Python for 循环语法

python - 获取 Python 中 if 语句中满足哪个或条件

python - 从python中的单元格获取数字