首页 > 解决方案 > 根据另一列的多个条件修改一列值

问题描述

如果我有以下数据框。我想根据 A 列的多个条件返回 B 列的任意值,规则如下:如果 A 列中的值 >= 0 且 <50,则返回 B 列的原始值;如果 A 列中的值 >= 50 且 < 70,则返回 B 列的值除以 3;如果 A 列中的值 >= 70 且 < 100,则返回 B 列的返回值除以 C 列和 3 列。

import pandas as pd
import numpy as np
np.random.seed(5)
df = pd.DataFrame(np.random.randint(100, size=(100, 3)), columns=list('ABC'))

我在 Python 中的伪代码:

def Standard():
    if (df['A'] >= 0) and (df['A'] < 50):
        return df['B'] 
    if (df['A'] >= 50) and (df['A'] < 70):
        return df['B']/3
    if (df['A'] >= 70) and (df['A'] <= 100):
        return df['B']/df['C']/3

df['B'] = df.apply(Standard, axis = 1)

它返回:TypeError: ('Standard() takes 0 positional arguments but 1 was given', 'occurred at index 0')

我该如何更正我的代码,或者 Python 中是否有其他更好的方法?谢谢你的帮助。

标签: pythonpandas

解决方案


为了获得更好的性能,如果numpy.selectapply匹配任何条件,也可以设置默认值:

masks = [(df['A'] >= 0) & (df['A'] < 50),
         (df['A'] >= 50) & (df['A'] < 70),
         (df['A'] >= 70) & (df['A'] <= 100)]

vals = [df['B'], df['B'] / 3, df['B']/df['C']/3]

df['B'] = np.select(masks, vals, default=0)

性能- 大约快 1000 倍:

np.random.seed(5)
df = pd.DataFrame(np.random.randint(100, size=(10000, 3)), columns=list('ABC'))

#Jeril solution
In [74]: %timeit df['B1'] = df.apply(Standard, axis=1)
__main__:18: RuntimeWarning: divide by zero encountered in double_scalars
424 ms ± 16.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [75]: %timeit df['B'] = np.select(masks, vals, default=0)
468 µs ± 4.09 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

推荐阅读