pandas中的4种if-else技术,你应该使用哪一种?

在pandas中进行数据整理通常涉及应用条件逻辑来转换和分类数据。在使用if-elif-else语句时,选择正确的方法对于效率和可读性都至关重要。在本文中,我们将通过pandas进行一次精彩的探索之旅,我们将探索实现if-elif-else逻辑的各种方法,同时根据员工的得分对他们的表现进行分类。

但是,这里有一个转折:我们不仅将探索这些技术,还将在性能对决中对它们进行测试。哪种方法将成为最快的冠军?加入我一起展开这次冒险,探索在pandas中使用if-elif-else的最高效方式。

数据集

为了演示这些技术,我们将使用一个包含有关员工绩效得分信息的虚构数据集。假设我们想根据他们的得分将他们的表现分为三组:“优秀”、“良好”和“需改进”。

import pandas as pd
import random

data = {
    'Employee_ID': range(1, 1_000_001),
    'Performance_Score': [random.randint(0, 100) for _ in range(1_000_000)]
}
df = pd.DataFrame(data)

方法1:使用apply()和自定义函数

将if-elif-else逻辑应用于pandas数据帧的一种常见且符合Python风格的方法是使用apply()方法和自定义函数。

import time

# store starting time 
begin = time.time() 

def categorize_performance(score):
    if score >= 90:
        return 'Excellent'
    elif 70 <= score < 90:
        return 'Good'
    else:
        return 'Needs Improvement'
    
df['Performance_Category'] = df['Performance_Score'].apply(categorize_performance)

end = time.time() 

print(f"Total runtime of the program is {end - begin}") 

#Total runtime of the program is 0.140 seconds 
  • 创建了一个名为categorize_performance的用户定义函数,用于根据“Performance_Score”定义分类逻辑。

  • 使用apply()方法将此函数应用于“Performance_Score”列中的每个元素。

  • 结果是一个新列“Performance_Category”,其中包含基于定义的逻辑的类别。

这种方法提供了一种清晰而灵活的方式来实现自定义的分类逻辑。你可以轻松修改用户定义函数以适应更复杂的条件。

方法2:使用np.where()

由NumPy库提供的np.where()函数是一种用于高效if-else操作的矢量化方法。

begin = time.time() 

df['Performance_Category'] = np.where(df['Performance_Score'] >= 90, 'Excellent',
                                      np.where((df['Performance_Score'] >= 70) & (df['Performance_Score'] < 90), 'Good', 'Needs Improvement'))

end = time.time() 

print(f"Total runtime of the program is {end - begin}") 

# Total runtime of the program is 0.182 sec.
  • 第一个参数np.where()是要检查的条件。

  • 第二个参数是条件为真时要分配的值。

  • 第三个参数是条件为假时要分配的值。

这种方法在一行内创建了一个嵌套的if-else结构,提供了一种简洁而易读的替代方案。

方法3:使用pd.cut()

Pandas中的pd.cut()方法是一种基于指定的区间进行分箱和分类数据的多功能工具。当你想要根据特定的范围定义类别时,该方法特别有用。

begin = time.time() 

bins = [0, 69, 89, 100]
labels = ['Needs Improvement', 'Good', 'Excellent']
df['Performance_Category'] = pd.cut(df['Performance_Score'], bins=bins, labels=labels)
end = time.time() 
print(f"Total runtime of the program is {end - begin}") 
# Total runtime of the program is 0.052858829498291016
  • bins参数指定了分箱边缘,定义了分类的间隔。

  • labels参数将标签分配给相应的分箱。

  • 生成的“Performance_Category”列包含基于指定的分箱的类别标签。

这种方法简洁明了,为定义类别提供了清晰的结构,适用于希望自定义分箱范围的场景。

方法4:使用.loc[] — The Champion进行矢量化的if-else

这种方法利用了pandas的.loc[]访问器的矢量化能力,以高效地执行if-else操作。其思想是使用布尔条件在数据帧中过滤行和列,并相应地分配值。

begin = time.time() 


df.loc[df['Performance_Score'] >= 90, 'Performance_Category'] = 'Excellent'
df.loc[(df['Performance_Score'] >= 70) & (df['Performance_Score'] < 90), 'Performance_Category'] = 'Good'
df['Performance_Category'].fillna('Needs Improvement', inplace=True)

end = time.time() 

print(f"Total runtime of the program is {end - begin}") 


# Total runtime of the program is 0.016 seconds 
  • 对于“Performance_Score”大于或等于90的行,第一行将“Performance_Category”设置为“Excellent”。

  • 第二行将“Performance_Score”介于70和90(不包括)之间的行的“Performance_Category”设置为“Good”。

  • 第三行用“Needs Improvement”填充“Performance_Category”中的其余NaN值。

这种方法利用了pandas有效处理布尔索引的能力,使其成为一种简洁易读的解决方案。

结论

在这篇博客中,我们探索了不同的方法来有效地将if-elif-else逻辑应用于Pandas数据帧。尽管选择的方法可能取决于具体的用例,但性能分析显示df.loc[]或pd.cut()对于较大的数据集通常是最高效的。然而,其他方法更灵活,可能在需要更复杂的条件逻辑或自定义分箱的情况下更受欢迎。

高效的代码不仅节省时间,还使你的数据处理任务更具可扩展性和可管理性。在选择适合你的pandas if-elif-else操作的最适当方法时,请考虑你的具体用例和数据集大小。

原文作者:Anmol Tomar
翻译作者:文杰
美工编辑:过儿
校对审稿:Jason
原文链接:
https://medium.com/codex/4-if-else-techniques-in-pandas-which-one-you-should-be-using-276078019028

Previous
Previous

为什么数据管道无法实现100%自动化?

Next
Next

使用生成式AI编写代码的正确方法