文件更新后记录变化的处理方式
背景:文件有3列数据,通过一列名为ppid的列可以唯一确定行数据,现在这个文件里的数据发生了变化,有些行数据改变了,有些删除了,也有新增数据行,现在需要将他们行的变化标出,是新建、修改还是删除。
数据如下:
old.csv数据为:
ppid | col1 | col2 |
---|---|---|
LK-001 | A | B |
LK-002 | C | D |
LK-003 | E | F |
new.csv数据为:
ppid | col1 | col2 |
---|---|---|
LK-001 | A | B |
LK-002 | C | G |
LK-99 | N | B |
需要输出的结果为:
ppid | col1 | col2 | change |
---|---|---|---|
LK-001 | A | B | |
LK-002 | C | G | modify |
LK-003 | E | F | deleted |
LK-99 | N | B | new |
使用pandas和numpy库来读取和处理CSV文件
import pandas as pd
import numpy as np
# 读取旧文件和新文件
old_df = pd.read_csv('tmp/old.csv')
new_df = pd.read_csv('tmp/new.csv')
# 创建一个空的结果DataFrame
result_df = pd.DataFrame(columns=['ppid', 'col1', 'col2', 'change'])
# 处理修改和新增的行
for _, row_new in new_df.iterrows():
# 根据ppid查找旧数据
row_old = old_df.loc[old_df['ppid'] == row_new['ppid']]
if len(row_old) == 0:
# 如果旧数据不存在,则添加一行新数据
result_df = result_df.append(
{'ppid': row_new['ppid'], 'col1': row_new['col1'], 'col2': row_new['col2'], 'change': 'new'},
ignore_index=True)
else:
# 如果旧数据存在,则比较新旧数据
if row_new['col1'] != row_old['col1'].values[0] or row_new['col2'] != row_old['col2'].values[0]:
result_df = result_df.append(
{'ppid': row_new['ppid'], 'col1': row_new['col1'], 'col2': row_new['col2'], 'change': 'modify'},
ignore_index=True)
# 数据无变化
else:
result_df = result_df.append(
{'ppid': row_new['ppid'], 'col1': row_new['col1'], 'col2': row_new['col2'], 'change': ''},
ignore_index=True)
# 处理删除的行
for _, row_old in old_df.iterrows():
# 根据ppid查找新数据
row_new = new_df.loc[new_df['ppid'] == row_old['ppid']]
if len(row_new) == 0:
# 如果新数据不存在,则添加一行删除的数据
result_df = result_df.append(
{'ppid': row_old['ppid'], 'col1': row_old['col1'], 'col2': row_old['col2'], 'change': 'deleted'},
ignore_index=True)
# 保存结果到新文件中
result_df.to_csv('tmp/result.csv', index=False)
在pandas库中,
iterrows()
是一个用于迭代DataFrame行的函数。它返回一个迭代器,该迭代器可以依次返回DataFrame中每一行的索引和数据。具体来说,iterrows()
函数会遍历DataFrame中的每一行,对于每一行,它会返回一个元组,其中第一个元素表示该行的索引,第二个元素表示该行的数据。
在pandas库中,
loc
是一个用于选择DataFrame行和列的函数。它可以根据行和列的标签来选择数据,并返回一个新的DataFrame。