如何使用python2.7使用嵌套for循环遍历数据帧并附加到新的数据帧列?

如何使用python2.7使用嵌套for循环遍历数据帧并附加到新的数据帧列?,python,python-2.7,pandas,dataframe,Python,Python 2.7,Pandas,Dataframe,我尝试遍历两个python dataframe列以确定特定值,然后将结果添加到一个新列中。下面的代码引发以下错误: raise ValueError('Length of values does not match length of ' 'index')" 我不知道为什么 数据帧: TeamID todayorno 1 sw True 2 pr False 3 sw False 4 pr True 代码

我尝试遍历两个python dataframe列以确定特定值,然后将结果添加到一个新列中。下面的代码引发以下错误:

raise ValueError('Length of values does not match length of ' 'index')" 
我不知道为什么

数据帧:

    TeamID    todayorno
1   sw        True
2   pr        False
3   sw        False
4   pr        True
代码:


您正在迭代数据帧两次,这表明您有2个
for
循环。最终得到的结果是10项,而不是所需的4项

不需要显式迭代。您可以使用
numpy。选择
为指定条件应用值

import numpy as np

mask = results['TeamID'] == 'sw'
conditions = [~mask, mask & results['todayorno'], mask & ~results['todayorno']]
values = ['green', 'red', 'green']

results['newnew'] = np.select(conditions, values, 'green')

print(results)

  TeamID  todayorno newnew
1     sw       True    red
2     pr      False  green
3     sw      False  green
4     pr       True  green
快速回答 不要试图循环

相反,使用默认值(即最常见值)创建新列,然后处理要更改的值并进行设置:

>>> 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”

在所有其他行中,您希望
newnewnew
的值为
“绿色”

规矩 为了有效地与熊猫合作,一条非常重要的规则是:不要试图循环。尤其是穿过一排排

相反,让熊猫为你做这项工作

因此,第一步是创建新列。由于在大多数情况下,您希望值为
“绿色”
,因此只需执行以下操作:

results['newnew'] = 'green'
现在,您的数据帧看起来像:

  TeamID  todayorno newnew
0     sw       True  green
1     pr      False  green
2     sw      False  green
3     pr       True  green
您会注意到熊猫“扩展”了所有行中提供的单个值

现在要将
sw/True
行设置为
“红色”
,首先需要找到所有行。为此,我们需要了解熊猫是如何工作的

(一点点)熊猫如何工作 当在数据帧后使用方括号时,通常是在对数据帧的列进行寻址。例:

>>> results['TeamID']
0    sw
1    pr
2    sw
3    pr
Name: TeamID, dtype: object
也就是说,通过请求
TeamID
数据帧的
results
索引,您得到了一个名为
TeamID
系列,其中只包含该列的值

另一方面,如果要寻址行,则需要使用
.loc
属性

>>> results.loc[1]
TeamID          pr
todayorno    False
newnew       green
Name: 1, dtype: object
这里我们得到了一个
系列
,其中包含该行的值

如果我们想看到多行,我们可以通过索引行列表来获得子数据帧:

>>> 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
条件可以包含布尔组合,但其语法有特殊要求,例如使用
&
而不是
,并由于
&
运算符的优先级,小心地用括号括起条件的各个部分:

>>> 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
另一种解决方案 dataframes的
.apply()
方法允许多次应用单个函数,可以按列或按行。要按行应用,请传递
轴=1
参数

如果传递给
.apply(…,axis=1)
的函数的结果返回一个值,则该函数的每个应用程序的结果将以数据帧行的相同寻址(通俗地说是相同索引)组合成一系列

因此:

然后可以将其指定为数据帧的一列:

>>> 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

您给出了一个示例,说明了在代码运行之前数据帧的外观。你能举一个例子说明你希望dataframe如何处理你的代码运行吗?注意
pd.Series.apply
+
lambda
应该作为最后的手段使用,因为矢量化解决方案是不可能的。使用布尔级数进行索引比使用行三元语句更有效。谢谢jpp!这完全符合预期。我要读《努比》了你能解释一下这条线是怎么工作的吗?条件=[~mask,mask&results['todayorno'],mask&~results['todayorno']]——让我试一试:您是否选择了所有掩码的反转、使用todayorno的掩码和使用todayorno的反转选择的掩码?然后指定与绿色、红色、绿色相同的顺序?
~
表示否定,
&
表示“和”或“交叉点”。
条件的每一项都与
值中的一项匹配。例如,
~mask
'green'
(每个列表中的第一个元素)匹配。
>>> 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