快速解答
不要尝试循环。
相反,使用默认值(即最常见的)创建新列,然后处理要更改的值并设置它们:
>>> results
TeamID todayorno
0 sw True
1 pr False
2 sw False
3 pr True
>>> results['newnew'] = 'green'
>>> results
TeamID todayorno newnew
0 sw True green
1 pr False green
2 sw False green
3 pr True green
>>> results.loc[(results['TeamID'] == 'sw') & (results['todayorno']), 'newnew'] = 'red'
>>> results
TeamID todayorno newnew
0 sw True red
1 pr False green
2 sw False green
3 pr True green
或者,您可以使用.apply(..., index=1) 来计算整个系列,并使用一个查看每一行的函数,并将整个系列一次性分配为一列:
>>> results
TeamID todayorno
0 sw True
1 pr False
2 sw False
3 pr True
>>> results['newnew'] = results.apply(
... lambda s: 'red' if s['TeamID'] == 'sw' and s['todayorno'] else 'green',
... axis=1,
... )
>>> results
TeamID todayorno newnew
0 sw True red
1 pr False green
2 sw False green
3 pr True green
说明
问题
据我从您的代码中可以看出,您正在尝试向数据框中添加一个名为 newnew 的列。
在TeamID 列包含值"sw" 和列todayorno 包含值True 的数据框行中,您希望列newnew 包含值"red"。
在所有其他行中,您希望newnew 的值为"green"。
规则
要高效地使用 pandas,一条非常重要的规则是:不要尝试循环。尤其是通过行。
而是让 pandas 为您完成这项工作。
因此,第一步是创建新列。由于在大多数情况下您希望值为"green",您可以简单地执行以下操作:
results['newnew'] = 'green'
现在你的数据框看起来像:
TeamID todayorno newnew
0 sw True green
1 pr False green
2 sw False green
3 pr True green
您会注意到 pandas “扩展”了通过所有行提供的单个值。
现在要将sw/True 行变为"red",首先您需要找到所有这些行。为此,我们需要了解 pandas 寻址的工作原理。
(一点点)pandas 寻址的工作原理
当您在 pandas 数据框后使用方括号时,通常是在处理数据框的列。例如:
>>> results['TeamID']
0 sw
1 pr
2 sw
3 pr
Name: TeamID, dtype: object
即通过请求results 数据帧的TeamID 索引,您将返回一个名为TeamID 的Series,其中仅包含该列的值。
另一方面,如果要寻址行,则需要使用.loc 属性。
>>> results.loc[1]
TeamID pr
todayorno False
newnew green
Name: 1, dtype: object
这里我们得到了一个包含行值的Series。
如果我们想查看多行,我们可以通过索引行列表来获得一个子数据框:
>>> results.loc[[1,2]]
TeamID todayorno newnew
1 pr False green
2 sw False green
或者通过使用条件:
>>> results.loc[results['TeamID'] == 'pr']
TeamID todayorno newnew
1 pr False green
3 pr True green
条件可以包含布尔组合,但其语法有特殊要求,例如使用 & 而不是 and 并且由于 & 运算符的优先级而小心地将条件部分用括号括起来:
>>> results.loc[(results['TeamID'] == 'sw') & (results['todayorno'])]
TeamID todayorno newnew
1 sw True green
.loc 属性也可以按行和列寻址。逗号分隔寻址部分,其中行的寻址在前,列在后:
>>> results.loc[results['TeamID'] == 'pr', 'todayorno']
1 False
3 True
Name: todayorno, dtype: bool
最后的润色
.loc 属性也可用于赋值,方法是将您想要的值分配给所需的“坐标”。
所以在你的情况下:
>>> results.loc[
... (results['TeamID'] == 'sw') & (results['todayorno']),
... 'newnew'
... ] = "red"
>>> results
TeamID todayorno newnew
0 sw True red
1 pr False green
2 sw False green
3 pr True green
另一种解决方案
.apply() 数据帧方法允许多次应用单个函数,无论是按列还是按行。要逐行应用,请传递 axis=1 参数。
如果传递给.apply(..., axis=1)的函数的结果返回单个值,那么该函数的每个应用的结果将组合成一个具有相同寻址(相同index,用 pandas 的说法)数据帧的行。
所以:
>>> results.apply(
... lambda s: 'red' if s['TeamID'] == 'sw' and s['todayorno'] else 'green',
... axis=1,
... )
0 red
1 green
2 green
3 green
dtype: object
然后可以将其分配为数据框的列:
>>> results['newnew'] = results.apply(
... lambda s: 'red' if s['TeamID'] == 'sw' and s['todayorno'] else 'green',
... axis=1,
... )
>>> results
TeamID todayorno newnew
0 sw True red
1 pr False green
2 sw False green
3 pr True green