Python 在DataFrame iterrows中更改布尔值没有任何作用

Python 在DataFrame iterrows中更改布尔值没有任何作用,python,python-3.x,pandas,Python,Python 3.x,Pandas,总的想法是: 从Excel中读取数据帧 添加一个新列,在该列中我可以识别有效行和无效行(在本例中,值在None处初始化,但我也尝试在False和0处初始化) 迭代DataFrame并根据一系列测试为新列赋值。(不幸的是,这些测试太复杂,无法使用applymap或类似方法) 预期结果是打印DataFrame并查看正确分配的新列的值 经验的结果是,这些值根本没有改变。它们都保持初始值 下面是一个高度简化的代码示例,其中显示了行为 import pandas as pd df = pd.read_c

总的想法是:

  • 从Excel中读取数据帧
  • 添加一个新列,在该列中我可以识别有效行和无效行(在本例中,值在
    None
    处初始化,但我也尝试在
    False
    0
    处初始化)
  • 迭代DataFrame并根据一系列测试为新列赋值。(不幸的是,这些测试太复杂,无法使用
    applymap
    或类似方法)
  • 预期结果是打印DataFrame并查看正确分配的新列的值

    经验的结果是,这些值根本没有改变。它们都保持初始值

    下面是一个高度简化的代码示例,其中显示了行为

    import pandas as pd
    
    df = pd.read_csv('./some_file.csv', sep='\t')
    
    print(df)   # View outputs below
    
    df['Valid'] = [None for _ in range(len(df))]    # New column
    
    for n in df.iterrows():
        if pd.notnull(n[1].Name):    # Example test
            n[1].Valid = False
        else:    # else clause should ensure all values change
            n[1].Valid = True
    
    print(df)    # Shows all df.Valid values are still None
    
    读取csv()后输出1

    代码末尾的输出2:

        Name  Age Valid
    0   John   20  None
    1  Mandy   25  None
    2   Mike   30  None
    3    NaN   40  None
    4   Alex   35  None
    
    在上面的示例中,当打印
    df
    时,所有值仍然是
    None
    ,即使调试器显示进程进入赋值语句

    是否存在某种我没有看到的范围、引用或可变性问题?有人能解释这种行为吗

    运行python 3.6.0

    对于一个示例数据集,我手动构建了一个
    some_file.csv
    文件,文件之间用制表符分隔(第4行的名称为空字符串,年龄为40岁,第5行被
    read_csv
    跳过,原因很明显):

    返回作为数据副本的序列。它不能用于更新基础数据帧。相反,我建议只构建一个列表,并在完成后将其添加到数据帧中,如:

    测试代码: 结果:
    @StephenRauch我编辑了问题以显示示例输出,还将输入文件更改为示例csv(问题中也有详细内容)。@StephenRauch好的,我将代码和输出分开以便于复制粘贴。但是,我不知道如何使csv更容易。这(循环)绝对不是您应该定义列的方式。只需执行
    df=df.assign(Valid=df['Name'].notnull())
    (为什么空值是“有效的”我将留给OP)@PaulH,OP说这是一个高度最小化的示例,并且工作非常广泛。@PaulH Stephen是正确的。为了清晰起见,发布的代码只是简化了。实际上,它需要执行多个测试,包括系列和多个数据帧之间的交叉依赖关系。使用df.assign()或df.applymap()可能是可能的,但对于一个没有性能要求的一次性任务来说,阅读起来也太难了。@JavoSN我向您保证,这可以在没有循环的情况下完成。
        Name  Age Valid
    0   John   20  None
    1  Mandy   25  None
    2   Mike   30  None
    3    NaN   40  None
    4   Alex   35  None
    
    Name    Age
    John    20
    Mandy   25
    Mike    30
        40
    
    Alex    35
    
    import pandas as pd
    df = pd.read_csv('input.csv', sep='\t')
    
    valid = []
    for n in df.iterrows():
        if pd.notnull(n[1].Name):    # Example test
            valid.append(False)
        else:    # else clause should ensure all values change
            valid.append(True)
    df['Valid'] = valid    # New column
    
    print(df)    # Shows all df.Valid values are still None
    
        Name  Age  Valid
    0   John   20  False
    1  Mandy   25  False
    2   Mike   30  False
    3    NaN   40   True
    4   Alex   35  False