python - 比较来自不同 excel 文件的列,并在每个文件的开头添加一列与输出

标签 python excel python-3.x pandas

首先我要声明我不是 Excel 专家,所以我需要一些帮助。

假设我有 3 个 excel 文件:main.xlsx1.xlsx2.xlsx。在所有这些中,我都有一个名为 Serial Numbers 的列。我必须:

  • 1.xlsx2.xlsx 中查找所有序列号,并验证它们是否在 main.xlsx 中。

如果找到序列号:

  • main.xlsx 的最后一列,在与找到的序列号相同的行上写入 OK + name_of_the_file_in which_it_was_found 。否则,写 NOK 。同时在最后一栏写上1.xlsx2.xlsx oknok 是否找到序列号

注意:serial number可以在1.xlsx2.xlsx上的不同列

示例:

ma​​in.xlsx

name date serial number phone status
a      b      abcd        c         <-- ok,2.xlsx
b      c      1234        d         <-- ok,1.xlsx
c      d      3456        e         <-- ok,1.xlsx
d      e      4567        f         <-- NOK
e      f                  g         <-- skip,don't write anything to status column

1.xlsx

name date serial number phone status
a      b      1234        c          <-- OK (because is find in main)
b      c      lala        d          <-- NOK (because not find in main)
c      d      3456        e          <-- OK (because find main)
d      e      jjjj        f          <-- NOK (because not find in main)
e      f                  g          <-- skip,don't write anything to status column

2.xlsx

name date serial number phone status
a      b                  c          <-- skip,don't write anything to status column
b      c      abcd        d          <-- OK (because find main)
c      d      4533        e          <-- NOK (because not find in main)
d      e      jjjj        f          <-- NOK (because not find in main)
e      f                  g          <-- skip,don't write anything to status column

现在,我尝试在 Python 中执行此操作,但显然我不知道如何在找到 dataFrames 的同一行上写入状态列(尝试使用 serial number )。任何帮助将非常感激。 (或至少一些指导)

我的问题不是找到重复项,而是跟踪行(在正确的 serial number 上写入状态)并在指定列( status 列)写入 excel。

我的尝试:

import pandas as pd

get_main = pd.ExcelFile('main.xlsx')
get_1 = pd.ExcelFile('1.xlsx')
get_2 = pd.ExcelFile('2.xlsx')

sheet1_from_main = get_main.parse(0)
sheet1_from_1 = get_1.parse(0)
sheet1_from_2 = get_2.parse(0)


column_from_main = sheet1_from_main.iloc[:, 2].real
column_from_main_py = []
for x in column_from_main:
    column_from_main_py.append(x)


column_from_1 = sheet1_from_1.iloc[:, 2].real
column_from_1_py = []
for y in column_from_1:
    column_from_1_py.append(y)


column_from_2 = sheet1_from_2.iloc[:, 2].real
column_2_py = []
for z in column_from_2:
    column_2_py.append(z)

建议修改:

import pandas as pd

get_main = pd.read_excel('main.xls', sheetname=0)
get_1 = pd.read_excel('1.xls', sheetname=0)
get_2 = pd.read_excel('2.xls', sheetname=0)


column_from_main = get_main.ix[:, 'Serial No.'].real
column_from_main_py = column_from_main.tolist()


column_from_1 = get_1.ix[:, 'SERIAL NUMBER'].real
column_from_1_py = column_from_1.tolist()


column_from_2 = get_2.ix[:, 'S/N'].real
column_from_2_py = column_from_2.tolist()

# Tried to put example data at specific column

df = pd.DataFrame({'Data': [10, 20, 30, 20, 15, 30, 45]})
writer = pd.ExcelWriter('first.xlsx', engine='xlsxwriter')
df.to_excel(writer, sheet_name='Sheet1')
workbook = writer.book
worksheet = writer.sheets['Sheet1']
worksheet.set_column('M:M', None, None)
writer.save()

最佳答案

首先,您可以跳过使用 excelfile 并使用 pd.read_excel(filename, sheetname=0) 进行解析。

就列而言,尝试按名称而不是索引访问列。而不是使用 for 循环来创建列表,而是使用 tolist 方法。因此,您可以说:

而不是 column_from_main = sheet1_from_main.iloc[:, 2].real
column_from_main = get_main.ix[:, 'serial number'].real
column_from_main_py = column_from_main.tolist()

对您的其他文件也执行相同的操作。这将消除序列号列被不同索引的任何问题,并且运行速度会更快。

关于您关于无法正确写入“状态”的评论,您可以展示您尝试过的代码吗?我非常乐意提供帮助,但很高兴看到您到目前为止所做的一切。

为了对照其他两个文件检查主文件中的值,您需要遍历您创建的列表并检查主列表中的每个值是否在其他列表中。在该循环中,您可以根据 main 中的序列号是否存在于一个、无或两者中来分配状态值:

get_main['status'] = ''
get_1['status'] = ''
get_2['status'] = ''
for num in column_from_main_py:
    if num not in column_from_1_py and not in column_from_2_py:
        get_main.loc[get_main['serial number'] == num, 'status'] = 'NOK'
    elif num in column_from_1_py and not in column_from_2_py:
        get_main.loc[get_main['serial number'] == num, 'status'] = 'OK,1.xlsx'
        get_1.loc[get_1['serial number'] == num, 'status'] = 'OK'
    elif num not in column_from_1_py and in column_from_2_py:
        get_main.loc[get_main['serial number'] == num, 'status'] = 'OK,2.xlsx'
        get_2.loc[get_2['serial number'] == num, 'status'] = 'OK'

get_main.loc 行是您为状态列设置 OK 或 NOK 值的地方。本质上,它会找到某些条件为真的索引,然后让您更改该索引处特定列的值。完成主列表后,您可以查看列表 1 和 2 以查找不在主列表中的序列号。同样:

for num in column_from_1_py:
    if num not in column_from_main_py:
        get_1.loc[get_1['serial number'] == num, 'status'] = 'NOK'
for num in column_from_2_py:
    if num not in column_from_main_py:
        get_2.loc[get_2['serial number'] == num, 'status'] = 'NOK'

这将为您设置 NOK 值,您应该继续将数据帧导出到 excel(或 csv、hdf、sql 等...),这样就可以了。

根据您的需要,您可以通过多种方式在 pandas 中索引和选择数据。我建议阅读 Indexing and Selecting Data文档中的页面,因为它对我来说是一个很好的引用。

关于python - 比较来自不同 excel 文件的列,并在每个文件的开头添加一列与输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37194880/

相关文章:

python - 使用 python 2.7 构建 Conda noarch 包

python - Pygame 中的换行符在输入框中使用 Unicode

vba - 在运行时隐藏 Excel 应用程序

VBA:使用类模块/集合和/或动态数组?

python - 使用余弦定律计算向量 (Python)

python - 无法模拟打开,即使使用文档中的示例也是如此

python - 检查用户名可用性 - AJAX 请求的处理 (Google App Engine)

python - 如何在不使用已弃用的 Gdk.Screen.get_width() 的情况下在 Python/GTK 中获取总屏幕大小?

python - 在 Python 中使用 float 切片 ndarray

vba - PowerPoint 文本转语音宏