Python-基于行值的乘法

Python-基于行值的乘法,python,pandas,conditional,Python,Pandas,Conditional,我有一个数据框和三个变量x,y,z x = 10, y = 20, z = 30 df = pd.DataFrame({'A':['a','b','c'], 'B':[6,7,8]}) 以下是我想做的: 创建新列“C”: If df['A'] == 'a', df['C'] = df['B']*x If df['A'] == 'b', df['C'] = df['B']*y If df['A'] == 'c', df['C'] = df['B']*z

我有一个数据框和三个变量x,y,z

x = 10, y = 20, z = 30

df = pd.DataFrame({'A':['a','b','c'],
                   'B':[6,7,8]})
以下是我想做的:

创建新列“C”:

If df['A'] == 'a', df['C'] = df['B']*x
If df['A'] == 'b', df['C'] = df['B']*y
If df['A'] == 'c', df['C'] = df['B']*z
有什么快速的方法吗

您可以使用np.where

df['C'] = np.where(df.A == 'a', df.B*x, np.where(df.A == 'b', df.B*y, df.B*z))
你得到

    A   B   C
0   a   6   60
1   b   7   140
2   c   8   240

创建一个字典,将列a值映射到乘法值,然后在列a上使用,并将其与列B相乘:

mul_map = {'a': 10, 'b': 20, 'c': 30}
df['C'] = df['B'] * df['A'].map(mul_map)
结果输出:

   A  B    C
0  a  6   60
1  b  7  140
2  c  8  240

在我看来,更具可读性(尽管速度较慢):


迄今为止最快的解决方案

#use apply to compare df.A with a,b,c and choose x,y or z.
df.apply(lambda r: r.B*[x,y,z][['a','b','c'].index(r.A)], axis=1)
Out[438]: 
0     60
1    140
2    240
dtype: int64
速度测试

%timeit df.apply(lambda r: r.B*[x,y,z][['a','b','c'].index(r.A)], axis=1)
1000 loops, best of 3: 580 µs per loop

%timeit np.where(df.A == 'a', df.B*x, np.where(df.A == 'b', df.B*y, df.B*z))
1000 loops, best of 3: 932 µs per loop

%timeit df['B'] * df['A'].map(mul_map)
1000 loops, best of 3: 686 µs per loop

我很想看看这两种方法的时间比较。我的直觉是,
.map
很慢,如果它像
的话。apply
@juanpa.arrivillaga:它可能比
np.where
解决方案慢,但是一旦你映射的项目数量增加,可读性就会提高(比如说10倍嵌套
np.where
).@juanpa.arrivillaga,如果不使用自定义函数,则比apply快得多。@ayhan啊,所以使用serial或dict时速度快,而使用callable时速度慢。知道了。有道理。很高兴知道!Gratz on 10000我愿意这是最快的方式@在目前的规模下,这两个项目似乎都具有可比性
%timeit df.apply(lambda r: r.B*[x,y,z][['a','b','c'].index(r.A)], axis=1)
1000 loops, best of 3: 580 µs per loop

%timeit np.where(df.A == 'a', df.B*x, np.where(df.A == 'b', df.B*y, df.B*z))
1000 loops, best of 3: 932 µs per loop

%timeit df['B'] * df['A'].map(mul_map)
1000 loops, best of 3: 686 µs per loop