如果在多列上有条件,pandas 数据框中的新列无法获得预期值基础

lov*_*veR 3 python if-statement python-3.x pandas

我有一个 Pandas 数据框,其数据如下表所示:

Negative  Positive  Neutral
True      False     False
True      False     False
False     False     True
False     True      False
True      False     False
False     True      False
True      False     False
True      False     False
Run Code Online (Sandbox Code Playgroud)

我正在做的是创建一个新列(“总体”),并根据条件,如果列“正”的行值为真,总体列获得值“正”,如果列“负”为真,则总体将采用“负”或“中性”值:

def flag_df(df):
    if (df["Negative"] == "True") and (df["Positive"] == "False") and (df["Neutral"] == "False"):
        return "Negative"
    elif (df["Negative"] == "False") and (df["Positive"] == "True") and (df["Neutral"] == "False"):
        return "Positive"
    else :
        return "Neutral"

fdf['Overall'] = fdf.apply(flag_df, axis = 1)
Run Code Online (Sandbox Code Playgroud)

但不幸的是,我不知道我做错了什么,“总体”列中的所有观察结果都是“中立”的:

Negative    Positive    Neutral     Overall
True           False     False      Neutral
True           False     False      Neutral
False          False     True       Neutral
False          True      False      Neutral
True           False     False      Neutral
False          True      False      Neutral
True           False     False      Neutral
True           False     False      Neutral
Run Code Online (Sandbox Code Playgroud)

有人可以让我知道我做错了什么吗?

jez*_*ael 6

如果所有列都是布尔值并且True每行始终只有一个是可能的,请使用DataFrame.dot

print (df.dtypes)
Negative    bool
Positive    bool
Neutral     bool
dtype: object

df['Overall'] = df.dot(df.columns)
print (df)
   Negative  Positive  Neutral   Overall
0      True     False    False  Negative
1      True     False    False  Negative
2     False     False     True   Neutral
3     False      True    False  Positive
4      True     False    False  Negative
5     False      True    False  Positive
6      True     False    False  Negative
7      True     False    False  Negative
Run Code Online (Sandbox Code Playgroud)

如果多个列名称使用:

cols = ['Negative', 'Positive', 'Neutral']
df['Overall'] = df[cols].dot(pd.Index(cols))
Run Code Online (Sandbox Code Playgroud)

或者:

df1 = df[cols]
df['Overall'] = df1.dot(df1.columns)
Run Code Online (Sandbox Code Playgroud)

您的解决方案应通过以下方式更改numpy.select

m1 = df["Negative"] & ~df["Positive"] & ~df["Neutral"]
m2 = ~df["Negative"] & df["Positive"] & ~df["Neutral"]

df['Overall'] = np.select([m1, m2], ['Negative','Positive'], default='Neutral')
print (df)
   Negative  Positive  Neutral   Overall
0      True     False    False  Negative
1      True     False    False  Negative
2     False     False     True   Neutral
3     False      True    False  Positive
4      True     False    False  Negative
5     False      True    False  Positive
6      True     False    False  Negative
7      True     False    False  Negative
Run Code Online (Sandbox Code Playgroud)

如果可能,True每行有多个匹配 - s 可以向列 anmes 添加分隔符,然后删除最后一个,

print (df)
   Negative  Positive  Neutral
0      True     False     True
1      True     False    False
2     False     False     True
3     False      True    False
4      True     False    False
5     False      True    False
6      True     False    False
7      True     False    False


df['Overall'] = df.dot(df.columns + ',').str.rstrip(',')
print (df)
   Negative  Positive  Neutral           Overall
0      True     False     True  Negative,Neutral
1      True     False    False          Negative
2     False     False     True           Neutral
3     False      True    False          Positive
4      True     False    False          Negative
5     False      True    False          Positive
6      True     False    False          Negative
7      True     False    False          Negative
Run Code Online (Sandbox Code Playgroud)

  • 我尝试并收到错误:“ValueError:点积形状不匹配,(48, 3) vs (10,)”知道为什么会这样吗? (2认同)
  • @loveR - 使用 `df['总体'] = df[['消极', '积极', '中性']].dot(pd.Index(['消极', '积极', '中性'])) ` (2认同)
  • 或者 `df1 = df[['Negative', 'Positive', 'Neutral']]` 然后 `df['Overall'] = df1.dot(df1.columns)` (2认同)
  • 最后一个建议,您最好将其包含在上面的解决方案中 `df['Overall'] = df[['Negative', 'Positive', 'Neutral']].dot(pd.Index(['Negative', “积极”、“中立”])) `一切都完成了! (2认同)