Stack Overflow на русском Asked on November 20, 2021
Может кто подсказать как реализовать следующее:
Имеется 500 таблиц Excel в формате XLS, которые содержат различные данные, однако одинаковые по структуре.
Можно ли как-то найти ячейку содержащую определенное значение, и получить данные ячейки находящейся справа от нее? И в идеале записать это значение в отдельный файл.
Пытался использовать бибилиотеку xlrd для поиска ячейки, однако никак не получается сделать поиск по содержимому листа.
import numpy as np
import pandas as pd # pip install pandas
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
def find_cell_next_to_val(df, val):
# df = pd.read_excel(filename, header=None, **kwargs)
# df = df.apply(lambda col: col.str.strip())
df.loc[:, df.dtypes.eq("object")] =
df.loc[:, df.dtypes.eq("object")].apply(lambda col: col.str.strip())
rows, cols = np.where(df == str(val).strip())
if len(rows) == 0:
return None
row, col = rows[0], cols[0]
# print(f"row: {row}, col: {col}")
if col + 1 > df.shape[1]:
return None
col_idx = df.iloc[row, col+1:].first_valid_index()
# print(f"col_idx: {col_idx}")
try:
return df.iat[row, col_idx], row, col_idx
except KeyError:
return None
def wrap(df, search_val):
val, row, col = find_cell_next_to_val(df, search_val)
print(f"Найдено значение [{search_val}: {val}] в ячейке [{row}, {col}]")
df = pd.read_excel(filename, header=None, dtype=str)
wrap(df, "№")
wrap(df, "Гос. №")
wrap(df, "Дата приема заказа")
wrap(df, "Общая стоимость ремонта с НДС, руб.")
Вывод:
Найдено значение [№: И-3] в ячейке [1, 19]
Найдено значение [Гос. №: О 327 КК] в ячейке [8, 25]
Найдено значение [Дата приема заказа: 09.01.2019 г.] в ячейке [1, 30]
Найдено значение [Общая стоимость ремонта с НДС, руб.: 41316.03864] в ячейке [50, 13]
Answered by MaxU on November 20, 2021
Вот вариант решения для приведенного примера данных:
import numpy as np
import pandas as pd # pip install pandas
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
def find_cell_next_to_val(filename, val, **kwargs):
df = pd.read_excel(filename, header=None, dtype=str, **kwargs)
df = df.apply(lambda col: col.str.strip())
rows, cols = np.where(df == str(val).strip())
if len(rows) == 0:
return None
row, col = rows[0], cols[0]
if col + 1 > df.shape[1]:
return None
col_idx = df.iloc[row, col+1:].first_valid_index()
try:
return df.iat[row, col_idx]
except KeyError:
return None
Тесты:
In [67]: filename = r"D:downloadпример2020722.xls"
In [68]: find_cell_next_to_val(filename, "№", sheet_name="наряд-заказ")
Out[68]: 'И-3'
In [69]: find_cell_next_to_val(filename, "Гос. №", sheet_name="наряд-заказ")
Out[69]: 'О 327 КК'
In [70]: find_cell_next_to_val(filename, "Дата приема заказа", sheet_name="наряд-заказ")
Out[70]: '09.01.2019 г.'
In [71]: find_cell_next_to_val(filename, "Общая стоимость ремонта с НДС, руб.", sheet_name="наряд-заказ")
Out[71]: '41316.03864'
Answered by MaxU on November 20, 2021
Воспользуйтесь Pandas:
import numpy as np
import pandas as pd # pip install pandas
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
def find_cell_next_to_val(filename, val, **kwargs):
df = pd.read_excel(filename, **kwargs)
rows, cols = np.where(df == val)
if len(rows) == 0:
return None
row, col = rows[0], cols[0]
if col + 1 > df.shape[1]:
return None
return df.iat[row, col+1]
Тестовый файл:
Тесты:
In [18]: find_cell_next_to_val(filename, "bbb")
Out[18]: 222
In [19]: find_cell_next_to_val(filename, 3)
Out[19]: 'ccc'
In [20]: find_cell_next_to_val(filename, "3")
Pandas автоматически парсит числа как числа, а не как строки, поэтому строка "3"
не была найдена. При использовании read_excel()
можно явно указать читать все ячейки как строки:
In [21]: find_cell_next_to_val(filename, "3", dtype=str)
Out[21]: 'ccc'
In [22]: find_cell_next_to_val(filename, "3", dtype=str, sheet_name="Sheet1")
Out[22]: 'ccc'
Answered by MaxU on November 20, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP