Python 对一列使用多个条件来指定新列的值

Python 对一列使用多个条件来指定新列的值,python,python-3.x,pandas,any,Python,Python 3.x,Pandas,Any,我试图根据现有列中的字符串为数据分配8个标签中的一个。但是,使用我正在使用的方法,我会出现以下错误: ValueError:序列的真值不明确。使用a.empty、a.bool()、a.item()、a.any()或a.all() 我有144个不同的字符串,我想分配给8个标签 这里有一个简单的例子来说明我的意思。如果A是我的数据帧中的现有列,我想创建B,并根据A的值分配字符串 数据帧: A B 0 1 low 1 1 low 2 2 mid 3 3 mid 4

我试图根据现有列中的字符串为数据分配8个标签中的一个。但是,使用我正在使用的方法,我会出现以下错误:

ValueError:序列的真值不明确。使用a.empty、a.bool()、a.item()、a.any()或a.all()

我有144个不同的字符串,我想分配给8个标签

这里有一个简单的例子来说明我的意思。如果A是我的数据帧中的现有列,我想创建B,并根据A的值分配字符串

数据帧:

   A     B
0  1   low
1  1   low
2  2   mid
3  3   mid
4  5  high
5  4   mid
6  2   mid
7  5  high
我当前使用的代码类似于:

for index, row in df.iterrows():
    if df['A'] == 1:
        df['Label'] = 'low'
    elif any([df['A'] == 2, df['A'] == 3, df['A'] == 4]):
        df['Label'] = 'mid'
    elif df['A'] == 5:
        df['Label'] = 'high'
我认为是使用any()给了我错误。 据我所知,这是因为熊猫是如何工作的,但我并不真正理解它。有没有更简单的方法


任何帮助或指示都将不胜感激:)

使用
.loc
,索引中的条件如下:

将熊猫作为pd导入
从io导入StringIO
df=pd.read\u csv(StringIO(“”)
A.
0  1
1  1
2  2
3  3
4  5
5  4
6  2
7  5
“”,sep=r“\s+”)
df.loc[df[“A”]==1,“B”]=“低”
df.loc[df[“A”].isin((2,3,4)),“B”]=“mid”
df.loc[df[“A”]=“5,”B”]=“高”
打印(df)
输出:

   A     B
0  1   low
1  1   low
2  2   mid
3  3   mid
4  5  high
5  4   mid
6  2   mid
7  5  high

这里不需要
itterrows
,这是一个很慢的问题

方法1
方法2
评论中@anky_91的回答简单地解决了问题:

l=[df.A.eq(1),df.A.isin([2,3,4]),df.A.eq(5)]
df['B']=np.select(l,['low','mid','high'])
这是快得多,工作得很好


谢谢大家的帮助!:)

为什么不简单地创建一个函数并将其应用于列,如此简单,如此通俗

def mapper(x):
     if x == 1:
        return 'low'
     elif x for i in [2, 3, 4]):
        return 'mid'
     elif x == 5:
        return 'high'
     else:
        return 'wtf'

df['B'] = df['A'].apply(mapper)
另一种方法是从映射字典创建一个数据帧并进行连接,这更直观

或者另一种方法是为序列引用映射函数


理想情况下,我更喜欢从下到上按复杂度递增的顺序排列

似乎你永远不会达到“高”的状态,这就是你想要的吗?
l=[df.A.eq(1),df.A.isin([2,3,4]),df.A.eq(5)]
然后
df['B']=np.选择(l,['low','mid','high'])
我会做得更快。不要在这种情况下使用Itrows。我想我已经接触过好几次了。A列中有两个5的例子。但是根据你的情况,它应该评估为“中”,不是吗?啊,抱歉-那是一个打字错误。它应该是一个4。现在更正。
l=[df.A.eq(1),df.A.isin([2,3,4]),df.A.eq(5)]
df['B']=np.select(l,['low','mid','high'])
def mapper(x):
     if x == 1:
        return 'low'
     elif x for i in [2, 3, 4]):
        return 'mid'
     elif x == 5:
        return 'high'
     else:
        return 'wtf'

df['B'] = df['A'].apply(mapper)