具有多个条件的 Numpy“where”

2025-02-07 14:32:00
admin
原创
62
摘要:问题描述:我尝试在数据框“df_energy”中添加一个新列“energy_class”,如果“consumption_energy”值> 400,则包含字符串“high”,如果“consumption_energy”值在 200 到 400 之间,则包含字符串“medium”,如果“consumpti...

问题描述:

我尝试在数据框“df_energy”中添加一个新列“energy_class”,如果“consumption_energy”值> 400,则包含字符串“high”,如果“consumption_energy”值在 200 到 400 之间,则包含字符串“medium”,如果“consumption_energy”值低于 200,则包含字符串“low”。我尝试 np.where从 numpy 中使用,但我发现numpy.where(condition[, x, y])它只处理两个条件,而不是像我的情况那样处理 3 个。


解决方案 1:

尝试一下:使用@Maxu 的设置

col         = 'consumption_energy'
conditions  = [ df2[col] >= 400, (df2[col] < 400) & (df2[col]> 200), df2[col] <= 200 ]
choices     = [ "high", 'medium', 'low' ]
    
df2["energy_class"] = np.select(conditions, choices, default=np.nan)


  consumption_energy energy_class
0                 459         high
1                 416         high
2                 186          low
3                 250       medium
4                 411         high
5                 210       medium
6                 343       medium
7                 328       medium
8                 208       medium
9                 223       medium

解决方案 2:

您可以使用三元:

np.where(consumption_energy > 400, 'high', 
         (np.where(consumption_energy < 200, 'low', 'medium')))

解决方案 3:

我喜欢保持代码整洁。这就是我更喜欢np.vectorize做这类任务的原因。

def conditions(x):
    if   x > 400:   return "High"
    elif x > 200:   return "Medium"
    else:           return "Low"

func         = np.vectorize(conditions)
energy_class = func(df_energy["consumption_energy"])

然后只需使用以下命令将 numpy 数组添加为数据框中的一列:

df_energy["energy_class"] = energy_class

这种方法的优点是,如果您希望向列添加更复杂的约束,可以轻松完成。希望对您有所帮助。

解决方案 4:

我将在这里使用cut()方法,它将生成非常高效且节省内存的categorydtype:

In [124]: df
Out[124]:
   consumption_energy
0                 459
1                 416
2                 186
3                 250
4                 411
5                 210
6                 343
7                 328
8                 208
9                 223

In [125]: pd.cut(df.consumption_energy,
                 [0, 200, 400, np.inf],
                 labels=['low','medium','high']
          )
Out[125]:
0      high
1      high
2       low
3    medium
4      high
5    medium
6    medium
7    medium
8    medium
9    medium
Name: consumption_energy, dtype: category
Categories (3, object): [low < medium < high]

解决方案 5:

让我们首先创建一个1000000包含 和 之间的随机数的数据框01000用作测试

df_energy = pd.DataFrame({'consumption_energy': np.random.randint(0, 1000, 1000000)})

[Out]:

   consumption_energy
0                 683
1                 893
2                 545
3                  13
4                 768
5                 385
6                 644
7                 551
8                 572
9                 822

对数据框的一些描述

print(df.energy.describe())

[Out]:
       consumption_energy
count      1000000.000000
mean           499.648532
std            288.600140
min              0.000000
25%            250.000000
50%            499.000000
75%            750.000000
max            999.000000

有多种方法可以实现这一点,例如:

  1. 使用numpy.where

df_energy['energy_class'] = np.where(df_energy['consumption_energy'] > 400, 'high', np.where(df_energy['consumption_energy'] > 200, 'medium', 'low'))
  1. 使用numpy.select

df_energy['energy_class'] = np.select([df_energy['consumption_energy'] > 400, df_energy['consumption_energy'] > 200], ['high', 'medium'], default='low')
  1. 使用numpy.vectorize

df_energy['energy_class'] = np.vectorize(lambda x: 'high' if x > 400 else ('medium' if x > 200 else 'low'))(df_energy['consumption_energy'])
  1. 使用pandas.cut

df_energy['energy_class'] = pd.cut(df_energy['consumption_energy'], bins=[0, 200, 400, 1000], labels=['low', 'medium', 'high'])
  1. 使用 Python 的内置模块

def energy_class(x):
  if x > 400:
      return 'high'
  elif x > 200:
      return 'medium'
  else:
      return 'low'

df_energy['energy_class'] = df_energy['consumption_energy'].apply(energy_class)
  1. 使用 lambda 函数

df_energy['energy_class'] = df_energy['consumption_energy'].apply(lambda x: 'high' if x > 400 else ('medium' if x > 200 else 'low'))

时间比较

从我做过的所有测试来看,通过测量时间time.perf_counter()(有关测量执行时间的其他方法,请参阅此处)pandas.cut是最快的方法。

                        method      time
0                   np.where()  0.124139
1                  np.select()  0.155879
2            numpy.vectorize()  0.452789
3                 pandas.cut()  0.046143
4  Python's built-in functions  0.138021
5              lambda function   0.19081

在此处输入图片描述


笔记:

  • 有关和的区别pandas.cutpandas.qcut请参见:pandas.qcut 和 pandas.cut 有什么区别?

解决方案 6:

警告:小心使用 NaN

请务必小心,如果您的数据有缺失值,np.where则使用起来可能会很棘手,并且可能会无意中给您错误的结果。

考虑以下情况:

df['cons_ener_cat'] = np.where(df.consumption_energy > 400, 'high', 
         (np.where(df.consumption_energy < 200, 'low', 'medium')))

# if we do not use this second line, then
#  if consumption energy is missing it would be shown medium, which is WRONG.
df.loc[df.consumption_energy.isnull(), 'cons_ener_cat'] = np.nan

或者,您可以使用 one-more 嵌套np.where来表示 medium 与 nan,这样会很丑陋。

我认为最好的方法是pd.cut。它处理 NaN 并且易于使用。

例子:

import numpy as np
import pandas as pd
import seaborn as sns

df = sns.load_dataset('titanic')

# pd.cut
df['age_cat'] = pd.cut(df.age, [0, 20, 60, np.inf], labels=['child','medium','old'])


# manually add another line for nans
df['age_cat2'] = np.where(df.age > 60, 'old', (np.where(df.age <20, 'child', 'medium')))
df.loc[df.age.isnull(), 'age_cat'] = np.nan

# multiple nested where
df['age_cat3'] = np.where(df.age > 60, 'old',
                         (np.where(df.age <20, 'child',
                                   np.where(df.age.isnull(), np.nan, 'medium'))))

# outptus
print(df[['age','age_cat','age_cat2','age_cat3']].head(7))
    age age_cat age_cat2 age_cat3
0  22.0  medium   medium   medium
1  38.0  medium   medium   medium
2  26.0  medium   medium   medium
3  35.0  medium   medium   medium
4  35.0  medium   medium   medium
5   NaN     NaN   medium      nan
6  54.0  medium   medium   medium

解决方案 7:

试试这个:即使consumption_energy包含空值也不要担心。

def egy_class(x):
    '''
    This function assigns classes as per the energy consumed.
    ''' 
    return ('high' if x>400 else
             'low' if x<200 else 'medium')
chk = df_energy.consumption_energy.notnull()
df_energy['energy_class'] = df_energy.consumption_energy[chk].apply(egy_class)

解决方案 8:

我支持使用 np.vectorize。它比 np.where 快得多,而且代码也更简洁。使用更大的数据集,你绝对可以发现速度加快了。你可以对条件以及这些条件的输出使用字典格式。

# Vectorizing with numpy 
row_dic = {'Condition1':'high',
          'Condition2':'medium',
          'Condition3':'low',
          'Condition4':'lowest'}

def Conditions(dfSeries_element,dictionary):
    '''
    dfSeries_element is an element from df_series 
    dictionary: is the dictionary of your conditions with their outcome
    '''
    if dfSeries_element in dictionary.keys():
        return dictionary[dfSeries]

def VectorizeConditions():
    func = np.vectorize(Conditions)
    result_vector = func(df['Series'],row_dic)
    df['new_Series'] = result_vector

    # running the below function will apply multi conditional formatting to your df
VectorizeConditions()

解决方案 9:

myassign["assign3"]=np.where(myassign["points"]>90,"genius",(np.where((myassign["points"]>50) & (myassign["points"]<90),"good","bad"))

当您只想使用“where”方法但有多个条件时。我们可以通过像上面一样的方法添加更多(np.where)来添加更多条件。同样,最后两个就是您想要的。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用