熊猫DataFrame-迭代

时间:2020-03-31 07:08:00

标签: python pandas iteration python-3.7

首先-我知道在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}]

我知道,如果我在循环中运行它,它将为每次迭代覆盖字典。我只是想确保它可以与多个记录一起使用,所以我可以使它发挥作用。

1 个答案:

答案 0 :(得分:0)

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

假设您有参考表

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}

如果您希望不止一个列对使用此代码,则可以将此代码放在函数中并在列上循环/映射。

希望这会有所帮助。