Numpy"其中"有多种条件

时间:2016-08-23 19:14:07

标签: python pandas numpy dataframe

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

有什么好主意帮我吗?

提前谢谢

7 个答案:

答案 0 :(得分:22)

您可以使用ternary

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

答案 1 :(得分:12)

我会在这里使用cut()方法,这会产生非常高效且节省内存的category dtype:

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]

答案 2 :(得分:11)

试试这个: 使用@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

答案 3 :(得分:7)

我喜欢保持代码干净。这就是为什么我更喜欢... <property> <name>dfs.nameservices</name> <value>mycluster</value> <final>true</final> </property> .... <property> <name>dfs.client.failover.proxy.provider.mycluster</name> <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value> </property> 来执行此类任务的原因。

<property>
    <name>fs.defaultFS</name>
    <value>hdfs://mycluster</value>
</property>

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

np.vectorize

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

答案 4 :(得分:0)

我第二次使用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()

答案 5 :(得分:0)

警告:请务必小心,如果您的数据缺少值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

或者,您可以使用一个嵌套的np.where来表示媒介,而不是难于使用的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

答案 6 :(得分:-1)

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

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