Как я могу объединить несколько строк данных Excel в одну? - PullRequest
3 голосов
/ 26 марта 2019

В настоящее время я сталкиваюсь с проблемой, когда мне нужно объединить все данные, показанные на изображениях ниже, только в одну строку.

enter image description here

Поэтому, используя Python и Openpyxl, я попытался написать скрипт синтаксического анализа, который читает строку и копирует только тогда, когда значения не равны нулю или не являютсяидентично, в новую рабочую книгу.

Я выхожу из диапазона ошибок, а код не сохраняет только те данные, которые мне нужны.Я потратил на это несколько часов, поэтому я подумал, что могу попросить здесь, чтобы посмотреть, могу ли я открепиться.

Я прочитал некоторую документацию по Openpyxl и о создании списков в Python, попробовал пару видеона YouTube, но ни один из них не сделал именно то, что я пытался достичь.

import openpyxl
from openpyxl import Workbook

path = "sample.xlsx"
wb = openpyxl.load_workbook(path)
ws = wb.active
path2 = "output.xlsx"
wb2 = Workbook()
ws2 = wb2.active

listab = []
rows = ws.max_row
columns = ws.max_column

for i in range (1, rows+1):
   listab.append([])

cellValue = " "    
prevCell = " "

for c in range (1, rows+1):
    for r in range(1, columns+1):
        cellValue = ws.cell(row=r, column=c).value
            if cellValue == prevCell:
                listab[r-1].append(prevCell)
            elif cellValue == "NULL":
                listab[r-1].append(prevCell)
            elif cellValue != prevCell:
                listab[r-1].append(cellValue)
                prevCell = cellValue           

for r in range(1, rows+1):
    for c in range (1, columns+1):
        j = ws2.cell(row = r, column=c)
        j.value = listab[r-1][c-1]

print(listab)

wb2.save("output.xlsx")

Там должна быть одна строка с информацией ниже:

ods_service_id |service_name |service_plan_name |Процессор |RAM |NIC |ПРИВОД |

Ответы [ 3 ]

1 голос
/ 26 марта 2019

Лично я бы пошел с pandas.

import pandas as pd

#Loading into pandas
df_data = pd.read_excel('sample.xlsx')
df_data.fillna("NO DATA",inplace=True)  ## Replaced nan values with "NO DATA"
unique_ids = df_data.ods_service_ids.unique()

#Storing pd into a list
records_list = df_data.to_dict('records') 
keys_to_check = ['service_name', 'service_plan_name', 'CPU','RAM','NIC','DRIVE']
processed = {}

#Go through unique ids
for key in unique_ids:
    processed[key] = {}

    #Get related records
    matching_records = [y for y in records_list if y['ods_service_ids'] == key]
    #Loop through records
    for record in matching_records:
        #For each key to check, save in dict if non null
        processed[key]['ods_service_ids'] = key
        for detail_key in keys_to_check:
            if record[detail_key] != "NO DATA" :
                processed[key][detail_key] = record[detail_key]
        ##Note : doesn't handle duplicate values for different keys so far


#Records are put back in list
output_data = [processed[x] for x in processed.keys()]
# -> to Pandas
df = pd.DataFrame(output_data)[['ods_service_ids','service_name', 'service_plan_name', 'CPU','RAM','NIC','DRIVE']]

#Export to Excel
df.to_excel("output.xlsx",sheet_name='Sheet_name_1', index=False)

. Вышеуказанное должно работать, но я не совсем уверен, как вы хотите сохранить дублированные записи для того же идентификатора.Вы хотите хранить их как DRIVE_0, DRIVE_1, DRIVE_2?

РЕДАКТИРОВАТЬ:

df может быть экспортирован по-другому.Заменено ниже #export to Excel следующим:

df.to_excel("output.xlsx",sheet_name='Sheet_name_1')

РЕДАКТИРОВАТЬ 2:

без входных данных было трудно увидеть какие-либо потоки.Исправлен код выше с поддельными данными

1 голос
/ 26 марта 2019

Если честно, я думаю, что вам удалось запутаться в структурах данных и придумать что-то гораздо более сложное, чем вам нужно.

Один из подходящих подходов - использовать словари Python для каждой службы, обновляя их построчно.

wb = load_workbook("sample.xlsx")
ws = wb.active
objs = {}
headers = next(ws.iter_rows(min_row=1, max_row=1, values_only=True))
for row in ws.iter_rows(min_row=2, values_only=True):
    if row[0] not in objs:
        obj = {key:value for key, value in zip(headers, row)}
        objs[obj['ods_service_id']] = obj
    else:# update dict with non-None values
        extra = {key:value for key, value in zip(headers[3:], row[3:]) if value != "NULL"}
        obj.update(extra)

# write to new workbook
wb2 = Workbook()
ws2 = wb2.active
ws2.append(headers)
for row in objs.values(): # do they need sorting?
    ws2.append([obj[key] for key in headers])

Обратите внимание, как вы можете делать все без использования счетчиков.

0 голосов
/ 26 марта 2019

Я бы предложил использовать для этого библиотеку pandas, и тогда вы легко сможете выполнить любое преобразование.

import pandas as pd

exceldata = pd.read_excel('tmp.xlsx', index_col=0) 

print(exceldata)

Вы можете легко удалить null/na value или заменить его и экспортировать в формат Excel..

Справка для справки:

Чтение Excel

Значение Drop Na

ЗаменитьЗначение NA

...