Python 在给定列中查找最高行
Python Find highest row in a given column
我是 Whosebug 的新手,最近学习了一些基础知识 Python。这是我第一次使用 openpyxl。在我使用 xlrd 和 xlsxwriter 之前,我确实设法制作了一些有用的程序。但现在我需要一个 .xlsx reader&writer.
有一个文件,我需要读取和编辑已存储在代码中的数据。假设 .xlsx 有五列数据:A、B、C、D、E。在 A 列中,我有超过 1000 行数据。在 D 列上,我有 150 行数据。
基本上,我希望程序在给定列(比如 D)上找到包含数据的最后一行。然后,在 D 列的下一个可用行(最后一行 + 1)中写入存储变量 data
。
问题是我无法使用 ws.get_highest_row()
,因为它 returns A 列的第 1000 行。
基本上,到目前为止,这就是我所拥有的:
data = 'xxx'
from openpyxl import load_workbook
wb = load_workbook('book.xlsx', use_iterators=True)
ws = wb.get_sheet_by_name('Sheet1')
last_row = ws.get_highest_row()
显然这根本行不通。 last_row
returns 1000.
问题是 get_highest_row()
itself uses row dimensions 个实例定义了 sheet 中的最大行。 RowDimension
没有关于列的信息 - 这意味着我们不能用它来解决您的问题,必须以不同的方式处理它。
这是一种 "ugly" openpyxl 特定的选项,但如果 use_iterators=True
:
将不起作用
from openpyxl.utils import coordinate_from_string
def get_maximum_row(ws, column):
return max(coordinate_from_string(cell)[-1]
for cell in ws._cells if cell.startswith(column))
用法:
print get_maximum_row(ws, "A")
print get_maximum_row(ws, "B")
print get_maximum_row(ws, "C")
print get_maximum_row(ws, "D")
除此之外,我会按照@LondonRob 的建议用 pandas
解析内容并让它完成工作。
如果这是 openpyxl
的限制,那么您可以尝试以下方法之一:
- 将 Excel 文件转换为 csv 并使用 Python
csv
模块。
- 使用
zipfile
解压缩 Excel 文件,然后导航到解压缩文件的 "xl/worksheets" 子文件夹,您会在其中找到每个文件的 XML工作表。从那里你可以用 BeautifulSoup
或 lxml
. 解析和更新
xslx Excel 格式是 XML 文件的压缩树文件夹。您可以找到规范 here.
这是使用 Pandas 的方法。
It's easy 使用 last_valid_index
.
获取 Pandas 中的最后一个非空行
可能有更好的方法将生成的 DataFrame
写入您的 xlsx
文件,但是,according to the docs,这种非常愚蠢的方法实际上是在 [=14= 中完成的].
假设您从这个简单的工作表开始:
假设我们要将 xxx
放入列 C
:
import openpyxl as xl
import pandas as pd
wb = xl.load_workbook('deleteme.xlsx')
ws = wb.get_sheet_by_name('Sheet1')
df = pd.read_excel('deleteme.xlsx')
def replace_first_null(df, col_name, value):
"""
Replace the first null value in DataFrame df.`col_name`
with `value`.
"""
return_df = df.copy()
idx = list(df.index)
last_valid = df[col_name].last_valid_index()
last_valid_row_number = idx.index(last_valid)
# This next line has mixed number and string indexing
# but it should be ok, since df is coming from an
# Excel sheet and should have a consecutive index
return_df.loc[last_valid_row_number + 1, col_name] = value
return return_df
def write_df_to_worksheet(ws, df):
"""
Write the values in df to the worksheet ws in place
"""
for i, col in enumerate(replaced):
for j, val in enumerate(replaced[col]):
if not pd.isnull(val):
# Python is zero indexed, so add one
# (plus an extra one to take account
# of the header row!)
ws.cell(row=j + 2, column=i + 1).value = val
# Here's the actual replacing happening
replaced = replace_first_null(df, 'C', 'xxx')
write_df_to_worksheet(ws, df)
wb.save('changed.xlsx')
这导致:
图我将开始回馈 Whosebug 社区。 Alecxe 的解决方案对我不起作用,我不想使用 Pandas 等,所以我改为这样做。它从电子表格的末尾开始检查,并为您提供 D 列中的下一个 available/empty 行。
def unassigned_row_in_column_D():
ws_max_row = int(ws.max_row)
cell_coord = 'D' + str(ws_max_row)
while ws.cell(cell_coord).value == None:
ws_max_row -= 1
cell_coord = 'D' + str(ws_max_row)
ws_max_row += 1
return 'D' + str(ws_max_row)
#then add variable data = 'xxx' to that cell
ws.cell(unassigned_row_in_column_D()).value = data
alexce 的解决方案对我不起作用。这可能是openpyxl版本的问题,我在2.4.1,这是一个小调整后的工作:
def get_max_row_in_col(ws, column):
return max([cell[0] for cell in ws._cells if cell[1] == column])
我是 Whosebug 的新手,最近学习了一些基础知识 Python。这是我第一次使用 openpyxl。在我使用 xlrd 和 xlsxwriter 之前,我确实设法制作了一些有用的程序。但现在我需要一个 .xlsx reader&writer.
有一个文件,我需要读取和编辑已存储在代码中的数据。假设 .xlsx 有五列数据:A、B、C、D、E。在 A 列中,我有超过 1000 行数据。在 D 列上,我有 150 行数据。
基本上,我希望程序在给定列(比如 D)上找到包含数据的最后一行。然后,在 D 列的下一个可用行(最后一行 + 1)中写入存储变量 data
。
问题是我无法使用 ws.get_highest_row()
,因为它 returns A 列的第 1000 行。
基本上,到目前为止,这就是我所拥有的:
data = 'xxx'
from openpyxl import load_workbook
wb = load_workbook('book.xlsx', use_iterators=True)
ws = wb.get_sheet_by_name('Sheet1')
last_row = ws.get_highest_row()
显然这根本行不通。 last_row
returns 1000.
问题是 get_highest_row()
itself uses row dimensions 个实例定义了 sheet 中的最大行。 RowDimension
没有关于列的信息 - 这意味着我们不能用它来解决您的问题,必须以不同的方式处理它。
这是一种 "ugly" openpyxl 特定的选项,但如果 use_iterators=True
:
from openpyxl.utils import coordinate_from_string
def get_maximum_row(ws, column):
return max(coordinate_from_string(cell)[-1]
for cell in ws._cells if cell.startswith(column))
用法:
print get_maximum_row(ws, "A")
print get_maximum_row(ws, "B")
print get_maximum_row(ws, "C")
print get_maximum_row(ws, "D")
除此之外,我会按照@LondonRob 的建议用 pandas
解析内容并让它完成工作。
如果这是 openpyxl
的限制,那么您可以尝试以下方法之一:
- 将 Excel 文件转换为 csv 并使用 Python
csv
模块。 - 使用
zipfile
解压缩 Excel 文件,然后导航到解压缩文件的 "xl/worksheets" 子文件夹,您会在其中找到每个文件的 XML工作表。从那里你可以用BeautifulSoup
或lxml
. 解析和更新
xslx Excel 格式是 XML 文件的压缩树文件夹。您可以找到规范 here.
这是使用 Pandas 的方法。
It's easy 使用 last_valid_index
.
可能有更好的方法将生成的 DataFrame
写入您的 xlsx
文件,但是,according to the docs,这种非常愚蠢的方法实际上是在 [=14= 中完成的].
假设您从这个简单的工作表开始:
假设我们要将 xxx
放入列 C
:
import openpyxl as xl
import pandas as pd
wb = xl.load_workbook('deleteme.xlsx')
ws = wb.get_sheet_by_name('Sheet1')
df = pd.read_excel('deleteme.xlsx')
def replace_first_null(df, col_name, value):
"""
Replace the first null value in DataFrame df.`col_name`
with `value`.
"""
return_df = df.copy()
idx = list(df.index)
last_valid = df[col_name].last_valid_index()
last_valid_row_number = idx.index(last_valid)
# This next line has mixed number and string indexing
# but it should be ok, since df is coming from an
# Excel sheet and should have a consecutive index
return_df.loc[last_valid_row_number + 1, col_name] = value
return return_df
def write_df_to_worksheet(ws, df):
"""
Write the values in df to the worksheet ws in place
"""
for i, col in enumerate(replaced):
for j, val in enumerate(replaced[col]):
if not pd.isnull(val):
# Python is zero indexed, so add one
# (plus an extra one to take account
# of the header row!)
ws.cell(row=j + 2, column=i + 1).value = val
# Here's the actual replacing happening
replaced = replace_first_null(df, 'C', 'xxx')
write_df_to_worksheet(ws, df)
wb.save('changed.xlsx')
这导致:
图我将开始回馈 Whosebug 社区。 Alecxe 的解决方案对我不起作用,我不想使用 Pandas 等,所以我改为这样做。它从电子表格的末尾开始检查,并为您提供 D 列中的下一个 available/empty 行。
def unassigned_row_in_column_D():
ws_max_row = int(ws.max_row)
cell_coord = 'D' + str(ws_max_row)
while ws.cell(cell_coord).value == None:
ws_max_row -= 1
cell_coord = 'D' + str(ws_max_row)
ws_max_row += 1
return 'D' + str(ws_max_row)
#then add variable data = 'xxx' to that cell
ws.cell(unassigned_row_in_column_D()).value = data
alexce 的解决方案对我不起作用。这可能是openpyxl版本的问题,我在2.4.1,这是一个小调整后的工作:
def get_max_row_in_col(ws, column):
return max([cell[0] for cell in ws._cells if cell[1] == column])