#python #python-3.x
#python #python-3.x
Вопрос:
Для веб-сервера я пытаюсь сгенерировать отчет с указанием количества запросов с различными кодами ответов в течение некоторой фиксированной продолжительности, скажем, часа.
Из необработанных данных журналов http-доступа я сначала сгенерировал массив array, где каждая строка содержит 3 ячейки: час, код ответа и количество запросов. Из этого я затем генерирую конечный результат. Логика довольно проста, для каждой строки во входных данных,
У меня это работает, см. Небольшой пример, но он не кажется «питоническим», мне интересно, есть ли лучший способ сделать это. У меня есть начальные навыки в Python, и я не знаком с различными библиотеками обработки данных.
Есть ли лучший способ сделать это? Существуют ли какие-либо библиотеки, которые можно использовать для непосредственного получения конечного результата из исходных необработанных данных?
Кроме того, я почти уверен, что transpose — неправильное название для этого преобразования, буду признателен, если кто-нибудь сможет меня поправить и в этом.
#! /usr/bin/python3
'''
data is an array of array n*3:
h resp count
1 200 15
1 201 23
2 200 9
2 201 75
2 404 5
result is an array of n*m:
200 202 404
1 15 23 0
2 9 75 5
'''
def process(data):
result = [[None]]
for inrow in data:
r,c,v = inrow[0], inrow[1], inrow[2]
row = find_row(result, r)
idx = find_column_index(result, c)
row[idx] = v
return result
def find_row(result, r):
row = next((row for row in result[1:] if row[0] == r), None)
if not row:
row = [r]
result.append(row)
for x in result[0][1:]:
row.append(0)
return row
def find_column_index(result, c):
columns = result[0]
idx = next((idx for idx in range(len(columns)) if columns[idx] == c), None)
if not idx:
columns.append(c)
for row in result[1:]:
row.append(0)
idx = len(columns) - 1
return idx
def test():
#import pdb; pdb.set_trace()
arr = [
[1, "200", 15],
[1, "202", 23],
[2, "200", 9],
[2, "202", 75],
[2, "404", 5]
]
result = process(arr)
print(result)
if __name__ == "__main__":
test()
Комментарии:
1. Здравствуйте, меня смущает ваше описание ваших входных данных и выходных данных: я предполагаю, что ваш пример ввода и вывода данных написан неправильно в ваших комментариях. Вы хотели, чтобы ваш результат составлял часы в зависимости от типа запроса? т.е. (hr 1 соответствует 202 «200» ответам, 23 «201» ответам и 0 «404» ответам; hr 2 соответствует 9 «200» ответам, 75 «201» ответам и так далее?
2. @pooh17yes в первой строке последний столбец неверен в комментариях, он верен в тестовых данных внизу. Сейчас я отредактирую свой пост. И вы правы в отношении выходных данных — количество запросов в каждый час для различных кодов ответов
Ответ №1:
Pandas может решить это легко для вас, просто перенесите фрейм данных в сводную таблицу:
import pandas as pd
df = pd.DataFrame(arr = [
[1, "200", 15],
[1, "202", 23],
[2, "200", 9],
[2, "202", 75],
[2, "404", 5]
],columns = ['h', 'resp', 'count'])
pivot = df.pivot(values='count',index='h',columns='resp')
print(pivot)
Комментарии:
1. Это потрясающе. Возможно ли также сгенерировать конечный результат из необработанных данных, которые представляют собой массив
(timestamp, response-code)
? Мне нужно было бы извлечь час (или вычислить какой-то другой период) и получить их количество2. Наконец-то удалось приступить
pandas
к работеcygwin
. Кажется, что должна быть небольшая ошибка вышеdf.pivot(values='count',index='h',columns='count')
df.pivot(values='count',index='h',columns='resp')
. Я подожду день или два, прежде чем редактировать ваш ответ. Также отображаются отсутствующие значения,NaN
которыми я хотел бы быть0
. Я добавлю еще один комментарий и отредактирую, как только выясню, как это сделать