Pandas操作两个Excel实现数据对应行的合并
zorchp 人气:0写在前面
最近有朋友问我怎么把一个Excel工作表中的数据按照对应的匹配规则放到另外一个表中, 要求是两个对应的列要相同, 具体来看就是sheet1中数据比较多, sheet2中只含有两列, 这两列包含了年份和行业信息, 这两个表的header(pandas中的术语, 表示表头或者列名)都是相同的, 所以关键点就是让表1中的数据与表2中的数据建立对应即可, 然后注意一下选取过的数据就不能选了这个条件.
当然可能会有直接使用Pandas内置高级函数的方法来做, 但是毕竟不是主要研究数据分析了, 能用就行…
为了数据安全, 这里就不放截图了.
主要思路
因为要填充表2, 那么当然要遍历表二的每一行, 针对这每一行给出的列标信息, 然后遍历表1中满足条件的行, 填入表二之后break即可, 因为可能会出现重复遍历, 这里用到了哈希表的方法, 并且哈希表也有两种实现,
一种是给表1新添加一个列, 这个列可以是布尔值或者全0列, 表示没有遍历过(unused), 然后在满足条件的行添加到表二之后, 将对应值设置为1即可, 这样可以在之后的遍历过程中忽略掉已添加的数据.
另一种方法就是使用哈希表存储表一中遍历过的行的索引, 思路跟上面是一样的, 但是不会对原始数据进行增删.
代码
代码部分我给出了两个版本, 一种是我首先想到的, 不借助pandas内置函数, 将数据转换为列表来完成, 这样虽然好想当然之后还要手动处理表头, 比较麻烦, 代码如下:
import pandas as pd df1 = pd.read_excel('data.xlsx', sheet_name='Sheet1', header=0).values.tolist() df2 = pd.read_excel('data.xlsx', sheet_name='Sheet2', header=0).values.tolist() for i in range(len(df1)): df1[i].append(0) for i, item in enumerate(df2): for j in range(len(df1)): if df1[j][-1] == 0 and df1[j][0] == item[0] and df1[j][2] == item[2]: df2[i] = df1[j] df1[j][-1] = 1 break df2 = pd.DataFrame(df2) print(df2) with pd.ExcelWriter("data.xlsx", mode='a', engine='openpyxl') as writer: df2.to_excel(writer, sheet_name="Sheet3")
另一种用到了pandas内置的行遍历方法和索引等方法, 对Dataframe这种pandas内置的原生数据结构支持比较好, 但是不用的话就总忘…
import pandas as pd # pd.set_option('display.max_columns', None) pd.set_option('display.max_rows', None) df1 = pd.read_excel('data.xlsx', sheet_name='Sheet1', header=0) df2 = pd.read_excel('data.xlsx', sheet_name='Sheet2', header=0) # 标记是否匹配过 used = set() for idx2, row2 in df2.iterrows(): tmp = df1[(df1['所属行业'] == row2['所属行业']) & (df1['新年份'] == row2['新年份'])] for idx1, row1 in tmp.iterrows(): if idx1 not in used: df2.iloc[idx2, :] = row1 used.add(idx1) break df2.set_index('所属行业', inplace=True) print(df2) with pd.ExcelWriter("data.xlsx", mode='a', engine='openpyxl') as writer: df2.to_excel(writer, sheet_name="Sheet4")
加载全部内容