python - 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}]
而且我知道,如果我在循环中运行它,它将覆盖每次迭代的字典。我只是想确保它适用于多条记录,所以我可以利用它来发挥作用。
解决方案
正如您自己指出的那样,循环遍历 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}
如果您想要的不仅仅是一个列对,您可以将此代码放在一个函数中并在列上循环/映射。
希望这可以帮助。
推荐阅读
- sapui5 - Sapui5 路由器在 Master Detail App 中第二次无法正常工作
- javascript - React/Material 使用 withStyles 将元素悬停在其上时隐藏它的子元素
- javascript - 如何删除 _id 属性?
- javascript - 为不允许的站点启用复制和粘贴
- r - 使用 cumsum 的输出差异
- javascript - 创建一个函数来评估数组中的所有元素是否相同
- web-services - 将 1 个服务拆分为多个服务时,是否需要拆分服务的配置并将每个部分存储在服务中?
- python - 使用数组作为搜索输入的 Elasticsearch 查询
- python - 如何将文本文件转换为 python 列表形式
- react-native - 在 React-Native 中按字母顺序对联系人进行排序