[英]Pandas add column with value based on condition based on other columns
我有以下 pandas dataframe:
import pandas as pd
import numpy as np
d = {'age' : [21, 45, 45, 5],
'salary' : [20, 40, 10, 100]}
df = pd.DataFrame(d)
并想添加一个名为“is_rich”的额外列,根据他/她的薪水记录一个人是否富有。 我找到了多种方法来实现这一点:
# method 1
df['is_rich_method1'] = np.where(df['salary']>=50, 'yes', 'no')
# method 2
df['is_rich_method2'] = ['yes' if x >= 50 else 'no' for x in df['salary']]
# method 3
df['is_rich_method3'] = 'no'
df.loc[df['salary'] > 50,'is_rich_method3'] = 'yes'
导致:
但是我不明白首选的方式是什么。 根据您的应用,所有方法是否都一样好?
使用timeits
,卢克!
结论
列表推导在较小数据量上表现最佳,因为即使它们没有矢量化,它们也会产生很少的开销。 OTOH,对于更大的数据, loc
和numpy.where
表现更好 - 矢量化赢得了一天。
请记住,方法的适用性取决于您的数据,条件数量和列的数据类型。 我的建议是在确定选项之前测试数据的各种方法。
然而,可以肯定的是,列表理解非常具有竞争力 - 它们在C中实现并且针对性能进行了高度优化。
基准代码,供参考 。 以下是定时功能:
def numpy_where(df):
return df.assign(is_rich=np.where(df['salary'] >= 50, 'yes', 'no'))
def list_comp(df):
return df.assign(is_rich=['yes' if x >= 50 else 'no' for x in df['salary']])
def loc(df):
df = df.assign(is_rich='no')
df.loc[df['salary'] > 50, 'is_rich'] = 'yes'
return df
另一种方法是使用 pandas mask
(取决于用例where
)方法。 首先使用默认值(选择为"no"
)初始化一个 Series 并根据条件替换其中的一些(有点像loc[]
和numpy.where()
之间的混合)。
df['is_rich'] = pd.Series('no', index=df.index).mask(df['salary']>50, 'yes')
这可能是最快的选择。 例如,对于具有 10 mil 行的帧, mask()
选项比loc
选项快 40%。 1
我还在cs95的答案中更新了perfplot
基准,以比较mask
方法与其他方法的性能:
1 :将mask
与loc
进行比较的基准测试结果。
def mask(df):
return df.assign(is_rich=pd.Series('no', index=df.index).mask(df['salary']>50, 'yes'))
df = pd.DataFrame({'salary': np.random.rand(10_000_000)*100})
%timeit mask(df)
# 391 ms ± 3.87 ms per loop (mean ± std. dev. of 10 runs, 100 loops each)
%timeit loc(df)
# 558 ms ± 75.6 ms per loop (mean ± std. dev. of 10 runs, 100 loops each)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.