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

    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(), у тебя будет многоуровневый индекс, посмотри как обращаться к любому из уровней индекса в документации. Ну и посмотри все созданные мною списки, что бы посмотреть идею, как я декомпозировал задачу. Потому что задачу ты задал хорошую, по сути дела словарь это неполная запись за день, из которой нужно формировать данные.
    Ответ написан
    2 комментария
  • Как правильно сгенерировать дату в Pandas?

    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()
    Ответ написан
    2 комментария
  • Как разбить временной столбец на интервалы?

    Maksim_64
    @Maksim_64
    Data Analyst
    Смотрите если уж хочется разбивать на интервалы и создавать столбец с категориями то есть несколько стратегий но в целом для этого используется функция pd.cut, вот для вашей задачи я написал код.
    df= pd.DataFrame({'time':pd.date_range('2023-03-22', periods=48, freq='H')})
    bins = [0,5,11,16,22,24]
    labels = ['Ночь', 'Утро','День','Вечер','Ночь']
    df['session'] = pd.cut(df['time'].dt.hour, bins=bins, labels=labels, include_lowest=True,ordered=False)
    df

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

    Имейте ввиду да для определенных задач это имеет смысл, создавать категориальную переменную для интервала времени, но для многих случаев объекты работающие с временем и датой достаточны умны и вы можете осуществлять группы для временной последовательности это не обязательно GroupBy есть специальный метод resample. Для выборки вы можете установить вашу временную последовательность в индекс и затем использовать удобный метод between_time, и многие, многие другие. И в целом временная последовательность имеет dt атрибут и затем можно к ней обращаться day, hour, year и.т.д.
    Ответ написан
    1 комментарий
  • Как разбить временной столбец на интервалы?

    @dmshar
    Непонятно все-же, в чем вопрос?
    Вы написали свое видение разбивки времени суток на неформальные интервалы так, как вы это видите. У кото-то может быть другое видение (например - только "первая половина дня", "вторая половина дня", "ночь" или любая другая. Единой разбивки нет и быть не может. Значит, это не вопрос.
    Второе, вы написали, что хотите добавить столбец в датафрейм. Как это сделать - причем так, что-бы он заполнялся по вашему условию - показываю ниже. Я НЕ решаю вашу задачу, я показываю принцип решения. А уж подправить его так, что-бы он и на вашем датафрейме и на ваших данных работал, у условие ваше проверял - оставляю вам. Надеюсь, справитесь.

    df=pd.DataFrame({'A':[1,2,3,4,5,6,7,8,9,10]})
    def foo(dt):
        if dt<=3:
            ret='A'
        elif dt<=7:
            ret='B'
        else: 
            ret='C'
        print (ret)
        return ret
    df['B']=df.apply(lambda x: foo(x['A']), axis= 1 )


    P.S.И да, Jupiter файл сюда не загружают, загружают чистый код, составленный так, что-бы каждый мог его себе скопировать, запустить, получить результат и возможно как-то его подправить.
    Ответ написан
    1 комментарий
  • Как найти итоговые поступления каждого маршрута за 7 дней?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день.
    Это тестовое задагние или реальный проект?
    На всякий случай отмечу, что если вы оперируете с валютой, то для высокой точности стоит использовать тип данных BigDecimal вместо примитивов. Тип данных int тем более не подойдет, так как могут быть не только целые значения.

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

    Предположу, что это тестовое задание или домашка и потому вместо ответа дам вам несколько подсказок.
    1) Создайте класс, который хранит в себе информацию по каждому из маршрутов. Приведу простой пример. Можно учесть много аспектов например, дату и т.д., но не будем.
    Например, (псевдокод):
    class Route {
        int busNum;
        Map<DayOfWeek, BigDecimal> incomePerDay;
    }

    далее вы можете создать массив или использовать jcf для хранения данных.
    Не будем морочиться и возьмем массив:
    Route [] routes = new Route [];
    Инициализируем массив маршрутов. В мапу кладем доход. Ключом является день недели, а значением доход на этот день.
    Далее остается при помощи класса Scanner, который вы используете принять выручку на каждый день недели для каждого из маршрутов.
    После того, как вы примете значения остается итерировать по массиву Route. Внутри цикла получить мапу. Проитерировав по мапе получить значения (доходы) по ключу и вывести сумму (недельный доход) в консоль

    Я условился, что за маршрут можно получить от 1000 до 10000.

    За маршрут можно получить и 550 руб. 50 коп. Целых значений может и не быть
    Ответ написан
    2 комментария
  • "обратно симметричный" массив, как мне доделать?

    @zilog81
    static void fill(int []m) {
      int len = m.length;
      for(int i=0; i<len/2+1; i++) {
        m[i]=10+(int)(Math.random()*90);
        m[len-i-1] = m[i];
      }
    }
    Ответ написан
    Комментировать
  • Почему нельзя вычесть переменную внутри while?

    @Akela_wolf
    Extreme Programmer
    Потому что компьютер делает то что вы ему сказали, а не то что вы от него хотите :)

    Пусть account = 100
    тогда, если x=10
    account = 100 + 10 = 110

    затем, если x = -5
    account = 110 - (-5) = ?
    Ответ написан
    Комментировать