【问题标题】:Using Pandas and xlrd together. Ignoring absence/presence of column headers一起使用 Pandas 和 xlrd。忽略列标题的缺失/存在
【发布时间】:2018-09-02 09:07:21
【问题描述】:

我希望你能帮助我 - 我确信它可能是一件小事,只要知道如何解决。

在我的工作室中,我和我的同事都无法通过我们数据库的前端进行“查找并替换所有”更改。老板只是拒绝我们这种级别的访问权限。如果我们需要对数十条甚至数百条记录进行更改,则必须全部通过复制粘贴或类似方式完成。疯狂。

我正在尝试使用 Python 2 来解决这个问题,特别是 Pandas、pyautogui 和 xlrd 等库。

我已经研究了多个 StackOverflow 线程,并且到目前为止已经设法编写了一些在读取给定 XL 文件时运行良好的代码。在生产中,这将是从数据库 GUI 前端中找到的数据集中导出的文件,并且将只是计算机车间中项目的单列“物品编号”。这将始终有一个 Excel 列标题。例如

ANR
51234
34567
12345
...

所有记录编号均为 5 位数字。 我们还可以使用 IR 扫描仪将物品扫描到我们拥有的 iPad 上的“工作流程”应用程序中,并自动从该扫描物品列表中制作一个 XL 文件。

此处的 XL 文件可能与此类似。

56788
12345
89012
...

不同之处在于没有列标题。所有 XL 文件的数据都“锚定”在“Sheet1”上的单元格 A1 中,并且将再次使用单列。这里没有不必要的复杂性!

无论如何,这是脚本。当它完全工作时,系统参数将被提供给它。现在,假设我们需要更改记录以使其“RAM”值从
"2GB" 更改为"2 GB"。

import xlrd
import string
import re
import pandas as pd


field = "RAM"
value = "2 GB"

myFile = "/Users/me/folder/testArticles.xlsx"
df = pd.read_excel(myFile)
myRegex = "^[0-9]{5}$"


# data collection and putting into lists.
workbook = xlrd.open_workbook(myFile)
sheet = workbook.sheet_by_index(0)
data = [[sheet.cell_value(r, c) for c in range(sheet.ncols)] for r in     range(sheet.nrows)]

formatted = []
deDuped = []

# removing any possible XL headers, setting all values to strings
# that look like five-digit ints, apply a regex to be sure.
for i in data:
    cellValue = str(i)
    cellValue = cellValue.translate(None, '\'[u]\'')


    # remove the decimal point
    # Searching for the header will cause a database front-end problem. 
    cellValue = cellValue[:-2]
    cellValue = cellValue.translate(None, string.letters)

    # making sure only valid article numbers get through
    # blank rows etc can take a hike
    if len(cellValue) != 0:
        if re.match(myRegex, cellValue):
            formatted.append(cellValue)

# weeding out any possilbe dupes.
for i in formatted:
    if i not in deDuped:
        deDuped.append(i)


#main code block
for i in deDuped:

    #lots going on here involving pyauotgui
    #making sure of no error running searches, checking for warnings, moving/tabbing around DB front-end etc

    #if all goes to plan
    #removing that record number from the excel file and saving the change
    #so that if we run the script again for the same XL file 
    #we don't needlessly update an already OK record again. 

        df = df[~df['ANR'].astype(str).str.startswith(i)]
        df.to_excel(myFile, index=False)

我真正想知道的是如何运行脚本,以便“不关心”列标题的存在与否。

df = df[~df['ANR'].astype(str).str.startswith(i)]

似乎是这一切都挂起的代码行。我以不同的组合对该行进行了多次更改,但我的脚本总是崩溃。

如果列标题(在我的情况下为“ANR”)对于这种特定的“pandas”方法是必不可少的,是否有一种直接的方法可以将列标题插入到 XL 文件中,如果它首先缺少列标题- 即来自 IR 扫描仪和 iPad 上的“工作流程”应用程序的 XL 文件?

谢谢大家!

更新

我已经按照 Patrick 的建议尝试了一些代码来检查单元格“A1”是否有标题。部分成功。如果单元格 A1 丢失,我可以将“ANR”放入单元格,但我首先会丢失那里的任何内容。

import xlwt
from openpyxl import Workbook, load_workbook
from xlutils.copy import copy
import openpyxl

# data collection
workbook = xlrd.open_workbook(myFile)
sheet = workbook.sheet_by_index(0)
data = [[sheet.cell_value(r, c) for c in range(sheet.ncols)] for r in range(sheet.nrows)]



cell_a1 = sheet.cell_value(rowx=0, colx=0)

if cell_a1 == "ANR":
    print "has header"
else:
    wb = openpyxl.load_workbook(filename= myFile)
    ws = wb['Sheet1']
    ws['A1'] = "ANE"
    wb.save(myFile)
    #re-open XL file again etc etc.

我在writing to existing workbook using xlwt 找到了这个新代码块。在这种情况下,贡献者实际上使用了 openpyxl。

【问题讨论】:

  • 为什么不创建一个打开 xlsx 的准备步骤,检查 if not A1 == 'ANR':,如果是这样:插入一个单元格为 A1,内容为 'ANR',将所有其他单元格 1 向下推。现在您获得了相同格式的两个文件,可以轻松完成剩下的工作了吗?
  • 感谢您的提示。你是对的,这也许是解决问题的最直接的方法。

标签: python python-2.7 pandas xlrd


【解决方案1】:

我想我已经为自己解决了。

仍然有点混乱,但似乎正在工作。添加了“if/else”子句来检查单元格 A1 的值并采取相应措施。在how to append data using openpyxl python to excel file from a specified row? 找到了大部分代码 - 使用 openpyxl 的建议

import pyperclip
import xlrd
import pyautogui
import string
import re
import os
import pandas as pd
import xlwt
from openpyxl import Workbook, load_workbook
from xlutils.copy import copy


field = "RAM"
value = "2 GB"
myFile = "/Users/me/testSerials.xlsx"
df = pd.read_excel(myFile)


myRegex = "^[0-9]{5}$"

# data collection
workbook = xlrd.open_workbook(myFile)
sheet = workbook.sheet_by_index(0)
data = [[sheet.cell_value(r, c) for c in range(sheet.ncols)] for r in range(sheet.nrows)]

cell_a1 = sheet.cell_value(rowx=0, colx=0)

if cell_a1 == "ANR":
    print "has header"
else:
    headers = ['ANR']
    workbook_name = 'myFile'
    wb = Workbook()
    page = wb.active
    # page.title = 'companies'
    page.append(headers)  # write the headers to the first line

    workbook = xlrd.open_workbook(workbook_name)
    sheet = workbook.sheet_by_index(0)
    data = [[sheet.cell_value(r, c) for c in range(sheet.ncols)] for r in range(sheet.nrows)]

    for records in data:
        page.append(records)

        wb.save(filename=workbook_name)

        #then load the data all over again, this time with inserted header
        workbook = xlrd.open_workbook(myFile)
        sheet = workbook.sheet_by_index(0)
        data = [[sheet.cell_value(r, c) for c in range(sheet.ncols)] for r in range(sheet.nrows)]


formatted = []
deDuped = []

# removing any possible XL headers, setting all values to strings that look like five-digit ints, apply a regex to be sure.
for i in data:
    cellValue = str(i)
    cellValue = cellValue.translate(None, '\'[u]\'')

    # remove the decimal point
    cellValue = cellValue[:-2]
    # cellValue = cellValue.translate(None, ".0")
    cellValue = cellValue.translate(None, string.letters)

    # making sure any valid ANRs get through
    if len(cellValue) != 0:
        if re.match(myRegex, cellValue):
            formatted.append(cellValue)
# ------------------------------------------

# weeding out any possilbe dupes.
for i in formatted:
    if i not in deDuped:
        deDuped.append(i)


# ref - https://stackoverflow.com/questions/48942743/python-pandas-to-remove-rows-in-excel
df = pd.read_excel(myFile)

print df


for i in deDuped:
    #pyautogui code is run here...

    #if all goes to plan update the XL file
        df = df[~df['ANR'].astype(str).str.startswith(i)]

        df.to_excel(myFile, index=False)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-14
    • 1970-01-01
    • 2020-08-01
    • 2021-01-26
    • 2020-08-11
    • 2018-07-22
    • 2020-03-23
    相关资源
    最近更新 更多