繁体   English   中英

Pandas 根据其他列的条件添加列

[英]Pandas add column with value based on condition based on other columns

我有以下 pandas dataframe:

df

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'

导致:

df2

但是我不明白首选的方式是什么。 根据您的应用,所有方法是否都一样好?

使用timeits ,卢克!

在此输入图像描述

结论
列表推导在较小数据量上表现最佳,因为即使它们没有矢量化,它们也会产生很少的开销。 OTOH,对于更大的数据, locnumpy.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 :将maskloc进行比较的基准测试结果。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM