Оптимизация скрипта Python, который читает файл CSV в dataframe - PullRequest
2 голосов
/ 29 сентября 2019

Я написал скрипт на python для чтения файла csv в фрейме данных, сортировки в зависимости от двух строк (дата и инцидент), а затем генерирования двух столбцов X | Y из данных.Данные включают различные инциденты, которые должны обрабатываться независимо.
Для каждого идентификатора инцидента;Столбец X представляет собой список инцидентов, так что он увеличивается от index = 0 до index = len (listOfIncidents), а Y - это просто ListOfIncident (index + 1).
Предположим, что это данные (бесполезные столбцы опущены дляясность) заказан и готов для разделения на X и Y
Образец изображения изображения
На рисунке ниже показан результат X и Y
Образец изображения результата здесь

Файл CSV близок к строке размером 500 Кб, поэтому сначала;Я преобразовал столбец даты в Unix (для легкой сортировки);затем отсортировал данные.Я создал функцию create_input_output для обработки создания X и Y и добавления к maindfObj

import csv
import pandas as pd
import time
import datetime


# Function takes the computed IncidentActivity_Type and IncidentID as arguments
# Function Writes the IncidentActivity_Type into X and Y and create a CSV file using the IncidentID as file name
# Define the column Names
_ncols = ('X', 'Y')
# Define empty dataframe
maindfObj = pd.DataFrame([], columns=_ncols)
def create_input_output(xy, incident_id):
    global maindfObj
    # Define Empty List
    values = []
    xList = [];
    i = 0
    while i < len(xy):
        try:
            # Insert into X and Y so that X gets Index i and Y gets index i+1 etc
            xList = xy[0:i+1]
            values.append((xList, xy[i + 1]))
        except:
            xList = xy[0:i+1]
            # We have reached the end of list. Complete with NULL
            values.append((xList, "NULL"))
        i = i + 1
    # Write to dataframe
    subdfObj = pd.DataFrame(values, columns=_ncols)
    maindfObj = maindfObj.append(subdfObj)
    print("Appended "+ incident_id + ". New size: ") #print the size
    print(maindfObj.shape)
    # Create a filename
    #filename = incident_id + ".csv"
    # Write dataframe to file
    #subdfObj.to_csv(filename, sep=',')
    #print("Appended " + incident_id)

# Point to CSV file to be read. If file is in the same folder as python source just write filename
from google.colab import drive
drive.mount('/content/drive')
with open('/content/drive/My Drive/public/Incident_Activity.csv') as csv_file:
    # Read file. Possible delimiters are , ; and white space
    csv_reader = csv.reader(csv_file, delimiter=';')
    line_count = 0
    # Create a new list to hold the read data rows
    _newarr = []
    # Create Column
    _columns = []
    for row in csv_reader:
        # First Row is the header
        if line_count == 0:
            print(f'Column names are {", ".join(row)}')
            line_count += 1
            _columns = row[0].split(',')
            _columns = list(_columns)
            # Appending new column UnixEquiv to hold computed date
            _columns.append('UnixEquiv')
        # Other Rows are the data
        else:
            # Split
            rowstr = row[0].split(',')
            # Convert to list
            rowstr = list(rowstr)
            # Convert dateTime to Unix Timestamp and append to last column
            rowstr.append(time.mktime(datetime.datetime.strptime(rowstr[1], "%d/%m/%Y %H:%M").timetuple()))
            # Append new row to _newarr
            _newarr.append(tuple(rowstr))
            line_count += 1
    # Convert List to dataframe
    dfObj = pd.DataFrame(_newarr, columns=_columns)
    # Sort dataframe by the IncidentID and Unix Timestamp calculated earlier
    dfObj = dfObj.sort_values(by=['Incident ID', 'UnixEquiv'])

    # Create temporary XY List
    _tempxy = []
    # Initialize active Incident ID to empty
    _activeIncident = ""
    # Routine separates the big data based on Incident ID
    for index, row in dfObj.iterrows():
        if row['Incident ID'] == _activeIncident or _activeIncident == "":
            # Incident ID has not changed
            _tempxy.append(row['IncidentActivity_Type'])
            _activeIncident = row['Incident ID']
        else:
            # Incident ID has changed.
            _activeIncident = row['Incident ID']
            # Let's write that to file before we start the next batch
            create_input_output(_tempxy, _activeIncident)
            # Clear old Incident ID
            _tempxy.clear()
            # Start new batch
            _tempxy.append(row['IncidentActivity_Type'])
    #Dataframe is ready here. Use
    print(maindfObj.shape) #print the size

Код работает, но его завершение занимает слишком много времени.Я знаю, что люди здесь, которые знают лучше, могут помочь мне оптимизировать сценарий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...