Openpyxl:识别第一列相同值并合并其他列

0 投票
3 回答
74 浏览
提问于 2025-04-14 17:35

我的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)

希望这对你有帮助。

撰写回答