Openpyxl:识别第一列相同值并合并其他列
我的Excel表格中,A列有一些ID号码,但有时候这些号码是相同的。在这种情况下,我希望程序能把I列中的文本合并起来。I列可以有1到多个与相同ID对应的行。
举个例子:
从这里开始
列A | 列I |
---|---|
197 | 这是示例1 |
198 | 这是 |
198 | 示例2 |
199 | 这是示例3 |
到这里为止
列A | 列I |
---|---|
197 | 这是示例1 |
198 | 这是示例2 |
199 | 这是示例3 |
列A是否保持两行或合并成一行并不重要,关键是列I需要合并。
我尝试过逐行检查,看看前后行是否相同。但我遇到的问题是如何把新合并的列表放到另一列里。目前,我得到的Excel列表看起来和源数据没有什么不同。
mylist = []
for cell in sheet['A']:
mylist.append(cell.value)
textlist = []
for cell in sheet['I']:
textlist.append(str(cell.value))
mergecount=0
startcell=1
sheet.insert_cols(10)
for row in range(1, len(mylist)):
print(row, mylist[row-1], mylist[row])
if mylist[row-1] == mylist[row]:
mergecount += 1
else:
print(row, mylist[row-1], mylist[row], startcell, mergecount)
if mergecount > 0:
for text in textlist:
newcells = ' '.join(text)
cell.value = newcells
mergecount = 0
startcell = row+1
if mergecount > 0:
for text in textlist:
newcells = ' '.join(text)
cell.value = newcells
workbook.save(file)
3 个回答
1
你只需要对A列进行循环,把I列的文本放进一个字典里,A列的ID作为字典的键。
然后清空并把这个字典写入到同一个表格或者另一个表格里。
在这个例子中,我是把数据写入了一个叫做“Combined”的新表格。
这里假设B到H列没有需要保留的数据。
import openpyxl
wb = openpyxl.load_workbook('Book1.xlsx')
ws = wb.active
dict1 = {}
### loop Column A, set the ID in column A as the key and append all data with same ID to the same key in dict1
for cell in ws['A']:
valA = cell.value # Column A value
valB = cell.offset(column=8).value # Column I value
if valA in dict1:
dict1[valA] += f" {valB}"
else:
dict1[valA] = valB
### Create new Sheet called Combined
ws_new = wb.create_sheet("Combined")
### Append data to the Sheet 'key' into Column A and 'val' into Column B
for key, val in dict1.items():
ws_new.append([f"{str(key)}", f"{val}"])
ws_new.insert_cols(2, 7) # Insert columns so text is Column I
wb.save('Book1.xlsx')
1
这是对@moken版本的一个优化版。
from collections import defaultdict
from openpyxl import load_workbook
values = defaultdict(list) # collect key, value pairs, extending as required
wb = load_workbook("Book1.xlsx")
ws1 = wb.active
for row in ws1.iter_rows(max_col=9, values_only=True):
key = row[0]
value = row[-1]
if key and value: # skip rows with neither key nor value
values[key].append(value)
ws2 = wb.create_sheet("consolidated")
for key, value in values.items():
ws2.append([key, " ".join(value)])
0
我稍微改写了一下代码,试着模仿你的风格和变量名称,这样更容易理解。
首先,我们可以使用你之前做的那种方式,把数据捕获到列表里:
import openpyxl
from openpyxl import load_workbook
file = "Book1.xlsx"
workbook = load_workbook(file)
sheet = workbook.active
mylist = []
for cell in sheet['A']:
mylist.append(cell.value)
textlist = []
for cell in sheet['I']:
textlist.append(str(cell.value))
接下来,我们可以创建两个新列表,用来保存新的ID和新文本。作为一个好的习惯,我建议从0开始循环,而不是从“1”开始:
mylist_new = []
textlist_new = []
for row in range(0, len(mylist)):
if row == 0:
newtext = textlist[row]
else:
if mylist[row-1] == mylist[row]:
# The operator '+' is going to work to concatenate strings:
newtext = newtext + ' ' + textlist[row]
else:
mylist_new.append(mylist[row-1])
textlist_new.append(newtext)
newtext = textlist[row]
# I need these last 2 lines to save the last values of both: IDs and text:
mylist_new.append(mylist[-1])
textlist_new.append(newtext)
最后,你可以把新列表中的数据保存到两个不同的列里(在这个例子中,我会使用同一个工作表的J列(第10列)和K列(第11列)):
for row in range(0, len(mylist_new)):
sheet.cell(row=row+1, column=10).value = mylist_new[row]
for row in range(0, len(textlist_new)):
sheet.cell(row=row+1, column=11).value = textlist_new[row]
workbook.save(file)
希望这对你有帮助。