【问题标题】:Pandas Multi-index set value based on three different conditionPandas 基于三种不同条件的多指标设定值
【发布时间】:2021-10-11 01:12:21
【问题描述】:

目标是根据列的 3 个条件创建一个新的多索引列 (B)

B 的条件

if B<0
  CONDITION_B='l`
elif B<-1
  CONDITION_B='L`
else
  CONDITION_B='g`

天真地,我想,我们可以简单地创建两个不同的掩码并将值替换为suggested

# Handle CONDITION_B='l` and CONDITION_B='g`

mask_2 = df.loc[:,idx[:,'B']]<0
appenddf_2=mask_2.replace({True:'g',False:'l'}).rename(columns={'A':'iv'},level=1)

然后

# CONDITION_B='L`
mask_33 = df.loc[:,idx[:,'B']]<-0.1
appenddf_2=mask_33.replace({True:'G'}).rename(columns={'A':'iv'},level=1)

正如预期的那样,这会抛出一个错误

TypeError: sequence item 1: expected str instance, bool found

我可以知道如何处理这 3 种不同的情况

预期输出

ONE TWO
B   B
g   L
l   l
l   g
g   l
L   L

产生错误的代码是

import pandas as pd
import numpy as np

np.random.seed(3)
arrays = [np.hstack([['One']*2, ['Two']*2]) , ['A', 'B', 'A', 'B']]
columns = pd.MultiIndex.from_arrays(arrays)
df=  pd.DataFrame(np.random.randn(5, 4), columns=list('ABAB'))

df.columns = columns

idx = pd.IndexSlice



mask_2 = df.loc[:,idx[:,'B']]<0
appenddf_2=mask_2.replace({True:'g',False:'l'}).rename(columns={'A':'iv'},level=1)
mask_33 = df.loc[:,idx[:,'B']]<-0.1
appenddf_2=mask_33.replace({True:'G'}).rename(columns={'A':'iv'},level=1)

【问题讨论】:

  • 为什么不使用附加列而不是用新值屏蔽。正如我所见,掩码值类型是布尔值。然后将 Boolean 更改为 str

标签: python pandas numpy conditional-statements multi-index


【解决方案1】:

我不完全理解您想要做什么,但请尝试以下操作:

df = pd.DataFrame({'B': [ 0, -1, -2, -2, -1,  0,  0, -1, -1, -2]})

df['ONE'] = np.where(df['B'] < 0, 'l', 'g')
df['TWO'] = np.where(df['B'] < -1, 'L', df['ONE'])
df = df.set_index(['ONE', 'TWO'])

输出结果:

>>> df
         B
ONE TWO
g   g    0
l   l   -1
    L   -2
    L   -2
    l   -1
g   g    0
    g    0
l   l   -1
    l   -1
    L   -2

【讨论】:

    【解决方案2】:

    IIUC:

    np.select() 在这种情况下是理想的:

    conditions=[
        df.loc[:,idx[:,'B']].lt(0) & df.loc[:,idx[:,'B']].gt(-1),
        df.loc[:,idx[:,'B']].lt(-1),
        df.loc[:,idx[:,'B']].ge(0)
    ]
    labels=['l','L','g']
    out=pd.DataFrame(np.select(conditions,labels),columns=df.loc[:,idx[:,'B']].columns)
    

    通过np.where():

    s=np.where(df.loc[:,idx[:,'B']].lt(0) & df.loc[:,idx[:,'B']].gt(-1),'l',np.where(df.loc[:,idx[:,'B']].lt(-1),'L','g'))
    out=pd.DataFrame(s,columns=df.loc[:,idx[:,'B']].columns)
    

    out的输出:

       One  Two
        B   B
    0   g   L
    1   l   l
    2   l   g
    3   g   l
    4   L   L
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-09
      • 1970-01-01
      • 2015-08-17
      • 2019-12-15
      相关资源
      最近更新 更多