BladehelpRunner
@BladehelpRunner
Гений мысли

Как правильно сгенерировать дату в Pandas?

Нужна помощь, мне необходимо сгенерировать таблицу из четырех столбцов: data, artist, track, start (кол-во прослушиваний)
Суть вопроса, нужно сделать интервал в 1 день для КАЖДОГО артиста и КАЖДОЙ его песни, то есть дата 2023-01-01 должна повториться 9 раз (для каждого (3) артиста по три песни)
И ещё, я не понимаю как вставлять каждого артиста по порядку, а не в случайном порядке как сделал я
И если возможно, как выводить каждую песню для артиста отдельно, а не списком?

1) Мне необходимы все варианты записей от 1 января 2023 до 10 мая, то есть каждый отдельный день должен встречаться 9 раз, для артиста (их трое) и для каждой песни артиста (3 песни для каждого артиста) = 3*3 = 9 строк с дублирующейся датой
2) Необходимо вытащить каждую песню из списка и выводить её по отдельности (если это возможно)
В конце образец решения (дата должна повторяться до 10-го мая 2023)
import numpy as np
import pandas as pd

n = 90 #кол-во строк

count_music = np.arange(3000, 100_000_1) # количесвто прослушиваний за день

starts = np.random.choice(count_music, n) # формируем столбец с прослушиваниями в день

start_date = pd.to_datetime('2023-01-01') # дата начала отчета

artists = pd.Series(['ANNA ASTI','Три дня дождя','MACAN']).sample(n,replace=True)

dates = pd.date_range(start_date, periods=n, freq='D')

songs = {
    'ANNA ASTI': ['Девочка танцуй','Грустный дэнс','Гармония'],
    'Три дня дождя': ['Демоны','Где ты','Перезаряжай'],
    'MACAN': ['Кино','Пополам','Бенз'],
}


audio = pd.DataFrame({'date': dates,
                      'artist': artists,
                      'start': starts})

audio['track'] = audio['artist'].apply(lambda x: songs[x])

audio.reset_index(drop= True , inplace= True)

audio.head(5)




df1 = {'date': ['2023-01-01','2023-01-01','2023-01-01','2023-01-01','2023-01-01','2023-01-01','2023-01-01','2023-01-01','2023-01-01'],
      'artist': ['ANNA ASTI','ANNA ASTI','ANNA ASTI','Три дня дождя','Три дня дождя','Три дня дождя','MACAN','MACAN','MACAN'],
       'track': ['Девочка танцуй','Грустный дэнс','Гармония','Демоны','Где ты','Перезаряжай','Кино','Пополам','Бенз'],
        'start': [800_078,679_000,456_876,345_089,345678,56789,6789,234567,90_458]}
df = pd.DataFrame(df1)
df
  • Вопрос задан
  • 110 просмотров
Решения вопроса 1
Maksim_64
@Maksim_64
Data Analyst
Ну смотри, первое ты говоришь количество строк 90, при этом формируешь временную последовательность, на 90 дней при этом у тебя есть желание иметь данные с повторяющемеся днями по количеству артистов их их песен, в примере ты приводишь 3 артиста по 3 песни на каждые то есть 9 ЗАПИСЕЙ на каждый день или 90 * 9 = 810 СТРОК.

Второе ты показываешь желаемый результат для одно дня только надо так делать для временной последовательности. И в нем собственно ты и подтверждаешь, мою мысль выше. Что строчек, будет больше чем 90.

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

import pandas as pd
import numpy as np

songs = {
    'ANNA ASTI': ['Девочка танцуй','Грустный дэнс','Гармония'],
    'Три дня дождя': ['Демоны','Где ты','Перезаряжай'],
    'MACAN': ['Кино','Пополам','Бенз'],
}

NUMBER_OF_DAYS = 3
LENGTH_OF_FINAL_FRAME = sum(len(value) for value in (songs.values())) * NUMBER_OF_DAYS

dates = pd.date_range('2023-01-01', periods=NUMBER_OF_DAYS, freq='1D')

artists = []
for key, value in songs.items():
    artists += [key] * len(value)

dates_and_artists = []
for date in dates:
    for artist in artists:
        dates_and_artists.append((date,artist))

songs_arr = np.array(list(songs.values()) * NUMBER_OF_DAYS).reshape(-1,1)




data = np.concatenate([np.array(dates_and_artists), 
                       songs_arr, 
                       np.random.randint(3000,1_000_000,LENGTH_OF_FINAL_FRAME).reshape(-1,1)], axis=1)

df = pd.DataFrame(data=data, columns=['Date','Artist','Track','Start'])
df


Ну в целом там все понятно, сначала собираем артистов, по количеству песен, затем добавляем дату к каждой такой записи, затем все это дело в массив, плюс выбираем случайно, количество прослушиваний (обрати внимание это для каждой песни выбирается, а не для каждого дня), если надо подправь, я ориентиероваля на твой фрейм который представил как результат.

Код для любого количества артистов и песен у них ну и количество дней тоже сколько надо задашь. NUMBER_OF_DAYS. Поменяй да и все.

ДОПОЛНЕНИЕ К ОТВЕТУ
Как и обещал, подработал я свое решение, так как оно должно быть, меньше кода, быстрее и больше функциональности.

from itertools import chain
import pandas as pd
import numpy as np


songs = {
    'ANNA ASTI': ['Девочка танцуй','Грустный дэнс','Гармония'],
    'Три дня дождя': ['Демоны','Где ты','Перезаряжай'],
    'MACAN': ['Кино','Пополам','Бенз'],
}

NUMBER_OF_DAYS = 3
NUMBER_OF_SONGS_PER_DAY = sum(len(value) for value in (songs.values()))
STARTING_DATE = '2023-01-01'

dates = pd.date_range(STARTING_DATE, periods=NUMBER_OF_DAYS, freq='1D')
artists = list(chain(*[[key] * len(value) for key, value in songs.items()]))
songs_per_day = list(chain(*songs.values()))

index = pd.MultiIndex.from_product([dates,artists],names=['Date','Artist'])

df = pd.DataFrame({
    'Songs':songs_per_day * NUMBER_OF_DAYS,
    'Start':np.random.randint(3000,1000000,NUMBER_OF_DAYS * NUMBER_OF_SONGS_PER_DAY),
    
}, index=index).reset_index()

df


Вот это хороший читабельный pandas код, теперь я спокоен, а то вопрос то решил, но просто в лоб, а не так как следует.

кстати обрати внимание, если запустишь код без reset_index(), у тебя будет многоуровневый индекс, посмотри как обращаться к любому из уровней индекса в документации. Ну и посмотри все созданные мною списки, что бы посмотреть идею, как я декомпозировал задачу. Потому что задачу ты задал хорошую, по сути дела словарь это неполная запись за день, из которой нужно формировать данные.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
i229194964
@i229194964
Веб разработчик
import itertools

start_date = pd.to_datetime('2023-01-01') # дата начала отчета
artists = ['ANNA ASTI', 'Три дня дождя', 'MACAN']
songs = {
    'ANNA ASTI': ['Девочка танцуй','Грустный дэнс','Гармония'],
    'Три дня дождя': ['Демоны','Где ты','Перезаряжай'],
    'MACAN': ['Кино','Пополам','Бенз'],
}

# создаем комбинации артистов и песен
artist_song_combinations = list(itertools.product(artists, songs.keys()))

# создаем список дат для каждого артиста и каждой его песни
date_list = [start_date + pd.DateOffset(days=i) for i in range(len(artists) * len(songs))]

# создаем датафрейм с датами, артистами и песнями
audio = pd.DataFrame({'date': date_list})
audio[['artist', 'track']] = pd.DataFrame(artist_song_combinations)
audio['track'] = audio['track'].apply(lambda x: songs[x])

# создаем столбец с количеством прослушиваний
audio['start'] = np.random.choice(count_music, len(audio))

audio.head()
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы