首页 > 解决方案 > Pandas DataFrame - 迭代

问题描述

首先 - 我知道迭代 Pandas DataFrame 不是一个好主意,因此欢迎对其他可能的解决方案提出任何建议。

我正在尝试编写一小段代码来比较两个数据帧 - 其中一个是要比较的模板。

数据框看起来像这样(当然是缩短版):

模板:

            Template1 | Template2 | Template3 
----------------------+-----------+------------
Variable 1 |  value   |   value   |   value     
Variable 2 |  value   |   value   |   value     
Variable 3 |  value   |   value   |   value     
Variable 4 |  value   |   value   |   value   

以及要比较的文件(数据文件):

            Record 1 | Record 2 | Record 3 | Record 4
---------------------+----------+----------+----------
Variable 3 |  value  |  value   |  value   |  value  
Variable 1 |  value  |  value   |  value   |  value  
Variable 4 |  value  |  value   |  value   |  value

现在,脚本应该做什么:

我设法编写了一小段代码,它甚至可以用于一条记录:

template = templatefile['Template2']
record_to_check = datafile[0]

errors_found = []
for a in template.index:
    if a in record_to_check.index:
        variable = {}
        if template[a] == record_to_check[a]:
            # equal
            pass
        else:
            # unequal
            variable['name'] = a
            variable['value'] = template[a]
            errors_found.append(variable)
    else:
        # not found
        variable = {}
        variable['name'] = a
        variable['value'] = template[a]
        errors_found.append(variable)

它返回 errors_found 字典,包含一对 {variable:value}。当我试图把它放在另一个循环中时问题就开始了(迭代数据文件中的记录:

template = templatefile['Template2']

for record_to_check in datafile.iteritems():
    errors_found = []
    for a in template.index:
        if a in record_to_check.index:
            variable = {}
            if template[a] == record_to_check[a]:
                # equal
                pass
            else:
                # unequal
                variable['name'] = a
                variable['value'] = template[a]
                errors_found.append(variable)
        else:
            # not found
            variable = {}
            variable['name'] = a
            variable['value'] = template[a]
            errors_found.append(variable)

结果:

Traceback (most recent call last):
  File "attributes.py", line 24, in <module>
    if a in record_to_check.index:
TypeError: argument of type 'builtin_function_or_method' is not iterable

我究竟做错了什么?

编辑:预期输出应该是这样的字典:

[{'name': 'variable2', 'value': value_from_template}, {'name': 'variable3', 'value': value_from_template}]

而且我知道,如果我在循环中运行它,它将覆盖每次迭代的字典。我只是想确保它适用于多条记录,所以我可以利用它来发挥作用。

标签: pythonpandasiterationpython-3.7

解决方案


正如您自己指出的那样,循环遍历 pandas 数据框并不是一个好方法。相反,您应该使用连接,这里有一些想法:

假设您有参考表

template
        template1   template2
index                        
var 1           1           5
var 2           2           4
var 3           3           3
var 4           4           2

和你的数据表

datafile
        record1   record2
index                    
var 3         1         3
var 1         2         3
var 4         4         2
  • 索引上的左连接将自动匹配变量,排序不起作用:joined = template.join(datafile, how='left').
  • 然后,您可以轻松创建新列,告诉您模板和数据表中的值是否匹配:joined['temp1=rec1'] = joined["template1"] == joined["record1"].
  • 此列可用于仅显示值不匹配的那些行:errors_found = joined[~joined['temp1=rec1']]
errors_found
        template1   template2   record1   record2  temp1=rec1
index                                                        
var 1           1           5       2.0       3.0       False
var 2           2           4       NaN       NaN       False
var 3           3           3       1.0       3.0       False
  • 您现在可以获得包含模板值的字典:errors_found = joined[~joined['temp1=rec1']]['template 1'].to_dict()
{'var 1': 1, 'var 2': 2, 'var 3': 3}

如果您想要的不仅仅是一个列对,您可以将此代码放在一个函数中并在列上循环/映射。

希望这可以帮助。


推荐阅读