управление списком на основе пользовательской логики

#python #list

#python #Список

Вопрос:

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

Например, ниже приведен список. Список содержит кортеж и элемент. Кортеж представляет час и день, а другой элемент представляет количество кликов. Здесь, [(0,1),3] —> в (0,1) 0 представляет час, а 1 представляет день. 3 представляет количество кликов. Вот так у меня за все 24 часа диапазон от 0 до 23 в течение 31 дня.

 [[(0, 1), 1],
 [(0, 2), 3],
 [(0, 3), 19],
 [(0, 4), 1],
 [(0, 5), 3],
 [(0, 6), 1],
 [(0, 8), 6],
 [(0, 11), 1],
 [(0, 12), 36],
 [(0, 15), 1],
 [(0, 16), 1],
 [(0, 20), 56],
 [(0, 21), 4],
 [(0, 22), 1],
 [(0, 24), 4],
 [(0, 25), 2],
 [(0, 26), 3],
 [(0, 27), 18],
 [(0, 28), 25],
 [(0, 30), 4],
 [(1, 1), 12],
 [(1, 2), 2],
 [(1, 3), 9],
 [(1, 4), 1],
 [(1, 5), 15],
 [(1, 6), 4],
 [(1, 7), 6],
 [(1, 8), 13],
 [(1, 10), 3],
 [(1, 11), 14],
 [(1, 12), 2],
 [(1, 13), 9],
 [(1, 14), 3],
 [(1, 15), 10],
 [(1, 16), 6],
 [(1, 18), 2],
 [(1, 19), 7],
 [(1, 20), 3],
 [(1, 21), 2],
 [(1, 22), 1],
 [(1, 23), 1],
 [(1, 24), 1],
 [(1, 25), 3],
 [(1, 26), 1],
 [(1, 27), 2],
 [(1, 28), 13],
 [(1, 29), 10]]
 

Мне нужно создавать фрейм данных в день в час. Если в этот конкретный день нет часа, ему должно быть присвоено 0 для total_clicks.

 day hour total_clicks
1   0      3
1   1      5
1   2      8
2   0      10
2   1      7
2   2      6
 

Кто-нибудь может мне помочь в решении этой проблемы?

Комментарии:

1. вы хотите, чтобы это было наиболее эффективным способом, или вас не волнует сложность

2. не нужно усложнять

Ответ №1:

Я пишу это для вас. Это позволит получить полный дневной и часовой фрейм и заполнить недостающее значение равным 0.

 import pandas as pd
import numpy as np
 

Это тестовые данные.

 test_data = [
    [(0, 1), 1],
    [(0, 2), 3],
    [(0, 3), 19],
    [(0, 4), 1],
    [(0, 5), 3],
    [(0, 6), 1],
    [(0, 8), 6],
    [(0, 11), 1],
    [(0, 12), 36],
    [(0, 15), 1],
    [(0, 16), 1],
    [(0, 20), 56],
    [(0, 21), 4],
    [(0, 22), 1],
    [(0, 24), 4],
    [(0, 25), 2],
    [(0, 26), 3],
    [(0, 27), 18],
    [(0, 28), 25],
    [(0, 30), 4],
    [(1, 1), 12],
    [(1, 2), 2],
    [(1, 3), 9],
    [(1, 4), 1],
    [(1, 5), 15],
    [(1, 6), 4],
    [(1, 7), 6],
    [(1, 8), 13],
    [(1, 10), 3],
    [(1, 11), 14],
    [(1, 12), 2],
    [(1, 13), 9],
    [(1, 14), 3],
    [(1, 15), 10],
    [(1, 16), 6],
    [(1, 18), 2],
    [(1, 19), 7],
    [(1, 20), 3],
    [(1, 21), 2],
    [(1, 22), 1],
    [(1, 23), 1],
    [(1, 24), 1],
    [(1, 25), 3],
    [(1, 26), 1],
    [(1, 27), 2],
    [(1, 28), 13],
    [(1, 29), 10],
]
 

Это код:

 formatted_test_data = [[row[0][0], row[0][1], row[1]] for row in test_data]
df = pd.DataFrame(formatted_test_data, columns=["hour", "day", "total_clicks"])
min_day = df["day"].min()
max_day = df["day"].max()
frame_df = pd.DataFrame(
    {
        "day": np.repeat(np.arange(min_day, max_day   1), 24),
        "hour": np.repeat(
            np.arange(24).reshape(1, -1), max_day - min_day   1, axis=0
        ).flatten(),
    }
)
result = frame_df.merge(
    df.groupby(["day", "hour"]).sum().reset_index(), on=["day", "hour"], how="left"
).fillna(0)
 

Комментарии:

1. Большое спасибо за предоставление оптимизированного кода. Потрясающая работа

Ответ №2:

Вы можете сделать это несколькими способами.

Я выделил 2.

 df = pd.DataFrame(your_list,columns=['day_hour','clicks'])

#1 
df[['day', 'hour']] = pd.DataFrame(df['day_hour'].tolist(),index=df.index)
#2 
df['day'], df['hour'] = df['day_hour'].str
 

Комментарии:

1. все еще отсутствует часть, где, если час не существует, он дает 0 кликов