将 Excel 工作表中的数据向左移动以删除空单元格并包含标题名称

问题描述 投票:0回答:1

我有一个像这样的 Excel 工作表,并且想要通过将这些数据块移向 A 列(相对于前一个数据块)来删除数据块之间的空单元格。数据块具有相同的标头,因此在第 1 行中标头“1”下的 A 列和 B 列数据是一个块。

例如,在第 2 行中,列 A - D 为空,列 E 包含标题“3”中的第一个数据块。我想将数据移动到行的开头。然后标题“4”下的下一个块移动到同一行中第一个块的旁边。

但是我也想将数据最初所在的标题名称放在块左侧的列中。
所以再次以第2行为例;
第一个块位于标题 3 下,移动到行的开头。由于原始标题位于左侧的列中,因此将位于 B 列中。在 A 列中,输入 3 作为该块的原始标题。
然后,对于标题“4”下的下一个块,将其移至 E 列,在 D 列中放置“4”作为该块的原始标题。
因此,该行现在从 A 列到最后一个块都没有空单元格,并且每个块前面都有其原始位置的标题名称。

结果应如下所示;

我可以放置标题名称(1,2,3,4..),但我无法放置值


from  openpyxl import *
mybook = load_workbook("newtry.xlsx")
myvalue= []
sheet=mybook.active
for row in sheet.iter_rows(min_row=1, min_col=1, max_row=5, max_col=6):
        for cell in row:
            myvalue.append(cell.value)


x=1
for i in myvalue:
    x=x+1
    if i == 1:
        for row, entry in enumerate('i', start=1):
            sheet.cell(row=x, column=1, value=1)
    book.save("newtry2.xlsx")

python excel openpyxl
1个回答
0
投票

有点复杂,但可以用 Pandas 来完成

使用 Pandas 将带有值的单元格向左移动。
在移位之前将每个组的 Header 转储到 List 中,以便在移位后插入数据。

import pandas as pd


def shift_cols_left(df_row, ncd):
    original_columns = df_row.index.tolist()

    ### Drop NaN cells
    shifted = df_row.dropna()

    cur_row = df_row.name  # Current Row in the DataFrame being compressed
    ### Create a dictionary of the Headers to be added as new columns
    ### This will lists of the original Column Headers for the data. To be inserted into the compressed DataFrame
    for col_count, col in enumerate(shifted):
        section_header = shifted.index[shifted == col].values[0]
        if 'Unnamed' not in str(section_header):  # Use actual Header names only
            cur_col = f"col{col_count}"
            if cur_col in ncd:
                ncd[cur_col] += [section_header]
            else:
                if cur_row > 0:  # Pad the list if needed
                    for x in range(cur_row):
                        if cur_col in ncd:
                            ncd[cur_col] += ['']
                        else:
                            ncd[cur_col] = ['']
                    ncd[cur_col] += [section_header]
                else:
                    ncd[cur_col] = [section_header]

    ### Shift columns with values to the left removing gaps and update column headers
    shifted.index = [original_columns[n] for n in range(shifted.count())]

    return shifted


filepath = 'newtry.xlsx'
sheet = 'Sheet1'

new_col_dict = {}

### Read the original Data from Excel
df = pd.read_excel(filepath, sheet_name=sheet)
print(f"Original DataFrame:\n{df}\n----------------------------------\n")

### Remove empty cells and shift data to the left
df1 = df.apply(shift_cols_left, args=(new_col_dict,), axis=1)
print(f"Left shifted DataFrame\n{df1}\n----------------------------------\n")

### Insert the Header detail into the DataFrame at first row then each 3rd row as necessary
loc = 0
for k, v in new_col_dict.items():
    df1.insert(loc=loc, column=k, value=pd.Series(v))
    loc += 3

### Final DataFrame with shifted data and Header Columns inserted
### Not bothering with renaming Headers as these will be dropped when writing to Excel
print(f"Left shifted DataFrame with header columns included:\n{df1}\n----------------------------------\n")

### Write the resultant DataFrame to Excel
### Drop Index and Header
with pd.ExcelWriter('newtry2.xlsx') as writer: 
    df1.to_excel(writer, sheet_name='Sheet1', index=False, header=False)

输入表
该表是问题中显示的表的副本。我假设第 1 行的标题是合并单元格。
IE。 A1 & B1、C1 & D1、E1 & F1 以及 G1 & H1 单元格单独合并。

输出表

代码示例将创建一个 new 'newtry2.xlsx'(覆盖同一目录中具有该名称的任何现有文件)。
如果需要,可以将写入器更改为写入现有文件而不覆盖。还可以将其写入任意位置的现有工作表或新工作表。

如问题输出图像所示,不包含标题。
标题可以在 DataFrame 中更改/更新,并包含在写入 Excel 中,或者
使用 ExcelWriter 引擎写入 DataFrame 后可以插入标头。

© www.soinside.com 2019 - 2024. All rights reserved.