Pandas DataFrame - 迭代
Pandas DataFrame - iterating
首先 - 我知道遍历 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)
它 returns 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}]
而且我知道如果我在循环中 运行 它会在每次迭代时覆盖字典。我只是想确保它适用于多个记录,这样我就可以利用它发挥作用。
正如您自己指出的那样,遍历 pandas 数据帧并不是一个好方法。相反,您应该使用联接,这里有一些想法:
假设您有参考 table
template
template1 template2
index
var 1 1 5
var 2 2 4
var 3 3 3
var 4 4 2
和您的数据 table
datafile
record1 record2
index
var 3 1 3
var 1 2 3
var 4 4 2
- 索引上的左连接会自动匹配变量,顺序不起作用:
joined = template.join(datafile, how='left')
.
- 然后您可以轻松创建新列,告诉您模板中的值和数据 table 是否匹配:
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}
如果您不仅需要一对列,还可以将此代码放入一个函数中,然后在列上循环/映射。
希望对您有所帮助。
首先 - 我知道遍历 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)
它 returns 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}]
而且我知道如果我在循环中 运行 它会在每次迭代时覆盖字典。我只是想确保它适用于多个记录,这样我就可以利用它发挥作用。
正如您自己指出的那样,遍历 pandas 数据帧并不是一个好方法。相反,您应该使用联接,这里有一些想法:
假设您有参考 table
template
template1 template2
index
var 1 1 5
var 2 2 4
var 3 3 3
var 4 4 2
和您的数据 table
datafile
record1 record2
index
var 3 1 3
var 1 2 3
var 4 4 2
- 索引上的左连接会自动匹配变量,顺序不起作用:
joined = template.join(datafile, how='left')
. - 然后您可以轻松创建新列,告诉您模板中的值和数据 table 是否匹配:
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}
如果您不仅需要一对列,还可以将此代码放入一个函数中,然后在列上循环/映射。
希望对您有所帮助。