python - Openpyxl - 将两个表的匹配行组合成一个长行
问题描述
在 Excel 文件中,我有两个大表。表 A(“解剖”,409 行 x 25 列)包含唯一条目,每个条目由唯一 ID 分隔。表 B(“解剖”,234 行 x 39 列)在第一个单元格中使用表 A 的 ID 并对其进行扩展。要在 Minitab 中分析数据,所有数据必须位于一个长行中,这意味着“Damage”的值必须遵循“Dissection”。整个事情看起来像这样:
Table A - i.e. Dissection
- ID1 [valueTabA] [valueTabA]
- ID2 [valueTabA] [valueTabA]
- ID3 [valueTabA] [valueTabA]
- ID4 [valueTabA] [valueTabA]
Table B - i.e. Damage
- ID1 [valueTabB1] [valueTabB1]
- ID1 [valueTabB2] [valueTabB2]
- ID4 [valueTabB] [valueTabB]
他们应该结合这样的东西:
Table A
- ID1 [valueTabA] [valueTabA] [valueTabB1] [valueTabB1] [valueTabB2] [valueTabB2]
- ID2 [valueTabA] [valueTabA]
- ID3 [valueTabA] [valueTabA]
- ID4 [valueTabA] [valueTabA] [valueTabB] [valueTabB]
最好的方法是什么?
下面介绍我的两种方法。两者都在相同的表中使用相同的数据,但在两个不同的文件中,以便能够测试两种方案。
第一种方法使用一个文件,两个表都在同一个工作表中,第二种方法使用一个文件,两个表都在不同的工作表中。
- 场景:两个表都在同一个工作表中,我试图将行作为一个范围移动
current_row = 415 # start without headers of table A
current_line = 2 # start without headers of table B
for row in ws.iter_rows(min_row=415, max_row=647):
# loop through damage
id_A = ws.cell(row=current_row, column=1).value
max_col = 25
for line in ws.iter_rows(min_row=2, max_row=409):
# loop through dissection
id_B = ws.cell(row=current_line, column=1).value
if id_A == id_B:
copy_range = ((ws.cell(row=current_line, column=2)).column_letter + str(current_line) + ":" +
(ws.cell(row=current_line, column=39)).column_letter + str(current_line))
ws.move_range(copy_range, rows=current_row, cols=max_col+1)
print("copied range: " + copy_range +" to: " + str(current_row) + ":"+str(max_col+1))
count += 1
break
if current_line > 409:
current_line = 2
else:
current_line += 1
current_row += 1
-> 在这里,我正在努力将范围附加到表 A 的右行,而不覆盖前一行(参见上面的示例 ID1)
- 场景:两个表都位于单独的工作表中
dissection = wb["Dissection"]
damage = wb["Damage"]
recovery = wb["Recovery"]
current_row, current_line = 2, 2
for row in damage.iter_rows():
# loop through first table
id_A = damage.cell(row=current_row, column=1).value
for line in dissection.iter_rows():
# loop through second table
id_B = dissection.cell(row=current_line, column=1).value
copyData = []
if id_A == id_B:
for col in range(2, 39):
# add data to the list, skipping the ID
copyData.append(damage.cell(row=current_line, column=col).value)
# print(copyData) for debugging purposes
for item in copyData:
column_count = dissection.max_column
dissection.cell(row=current_row, column=column_count).value = item
column_count += 1
current_row += 1
break
if not current_line > 409:
# prevent looping out of range
current_line += 1
else:
current_line = 2
-> 与 1. 中的问题相同,在某些时候它不再添加损坏值,copyData
而是None
,最后它只是不粘贴项目(单元格保持空白)
我已经尝试了所有我能找到的与excel相关的东西,但不幸的是没有任何效果。熊猫在这里会更有用还是我只是没有看到什么?
感谢您抽时间阅读 :)
解决方案
我强烈建议pandas
在这种情况下使用。仍然有点不清楚您的数据在excel
文件中的格式,但考虑到您的第二个选项,我假设这些表都位于excel
文件的不同工作表上。我还假设第一行包含表格标题(例如Table A - i.e. Dissection
)。如果不是这种情况,只需删除skiprows=1
:
import pandas as pd
df = pd.concat(pd.read_excel("filename.xlsx", sheet_name=None, skiprows=1, header=None), axis=1, ignore_index=True)
df.to_excel('combined_data.xlsx) #save to excel
read_excel
将excel
文件加载到pandas
数据框中。sheet_name=None
表示所有工作表都应加载到OrderedDict
数据框中。pd.concat
将这些数据帧连接成一个数据帧(axis=1
表示轴)。您可以使用 探索数据df.head()
,或使用 将数据框保存excel
到df.to_excel
。
推荐阅读
- python - 发送带有数据框的电子邮件作为附件
- javascript - Material UI Select 组件使 React 应用程序崩溃
- android - 从微调器获取所选项目 - MVVM - 数据绑定
- php - 从 Android Studio 上传图片到 MySQL 服务器
- javascript - 用java脚本抓取网页并用python登录
- javascript - Datatable jquery将复选框选择的可选行数限制为最多5个
- html - 在我的情况下,如何静态定位 div?
- windows - 在 azure 管道中使用 cmake 中的 bash 尝试调用 WSL,但从管道代码调用不会
- r - 绘制多列 R 的散点图和/或回归线
- php - 希腊字母被替换为??? 一旦我使用 PHPWord 将 docx 转换为 pdf?