WedX - журнал о программировании и компьютерных науках

Расширение фрейма данных pandas с диапазоном дат в столбцах

У меня есть фреймворк pandas с датами и строками, подобными этому:

Start        End           Note    Item
2016-10-22   2016-11-05    Z       A
2017-02-11   2017-02-25    W       B

Мне нужно развернуть / преобразовать его в приведенное ниже, заполняя недели (W-SAT) между столбцами Начало и Конец и вперед, заполняя данные в Примечании и Предметы:

Start        Note    Item
2016-10-22   Z       A
2016-10-29   Z       A
2016-11-05   Z       A
2017-02-11   W       B
2017-02-18   W       B
2017-02-25   W       B

Как лучше всего это сделать с пандами? Какой-то мультииндекс применим?

10.02.2017

Ответы:


1

Вы можете перебирать каждую строку и создавать новый фрейм данных, а затем объединять их вместе

pd.concat([pd.DataFrame({'Start': pd.date_range(row.Start, row.End, freq='W-SAT'),
               'Note': row.Note,
               'Item': row.Item}, columns=['Start', 'Note', 'Item']) 
           for i, row in df.iterrows()], ignore_index=True)

       Start Note Item
0 2016-10-22    Z    A
1 2016-10-29    Z    A
2 2016-11-05    Z    A
3 2017-02-11    W    B
4 2017-02-18    W    B
5 2017-02-25    W    B
10.02.2017
  • Спасибо! Это очень полезно. Я определенно слишком много думал об этом. 10.02.2017
  • Есть ли другой способ добиться этого без итерации строка за строкой? 21.02.2018
  • Я хотел бы знать и без iterrows ... iterrows медленный для набора данных с примерно 300 000 строками для обработки. 25.04.2018
  • @ihightower См. мой ответ ниже 15.11.2018
  • @ihightower, пожалуйста, посмотри мой ответ. Мой ответ не требует повторения. 25.05.2019
  • Есть ли способ сделать это, но без ручного указания столбцов, которые будут включены в новый фрейм данных? Если у вас есть фрейм данных с большим количеством столбцов, становится утомительно вручную выбирать все столбцы для включения ... 10.07.2020

  • 2

    Вам вообще не нужна итерация.

    df_start_end = df.melt(id_vars=['Note','Item'],value_name='date')
    
    df = df_start_end.groupby('Note').apply(lambda x: x.set_index('date').resample('W').pad()).drop(columns=['Note','variable']).reset_index()
    
    20.05.2019
  • Groupby с применением и настраиваемой функцией - это итерация, которая часто в несколько раз медленнее, чем просто использование цикла for. 10.07.2020

  • 3

    Если количество уникальных значений df['End'] - df['Start'] не слишком велико, но количество строк в вашем наборе данных велико, тогда следующая функция будет намного быстрее, чем цикл по вашему набору данных:

    def date_expander(dataframe: pd.DataFrame,
                      start_dt_colname: str,
                      end_dt_colname: str,
                      time_unit: str,
                      new_colname: str,
                      end_inclusive: bool) -> pd.DataFrame:
        td = pd.Timedelta(1, time_unit)
    
        # add a timediff column:
        dataframe['_dt_diff'] = dataframe[end_dt_colname] - dataframe[start_dt_colname]
    
        # get the maximum timediff:
        max_diff = int((dataframe['_dt_diff'] / td).max())
    
        # for each possible timediff, get the intermediate time-differences:
        df_diffs = pd.concat([pd.DataFrame({'_to_add': np.arange(0, dt_diff + end_inclusive) * td}).assign(_dt_diff=dt_diff * td)
                              for dt_diff in range(max_diff + 1)])
    
        # join to the original dataframe
        data_expanded = dataframe.merge(df_diffs, on='_dt_diff')
    
        # the new dt column is just start plus the intermediate diffs:
        data_expanded[new_colname] = data_expanded[start_dt_colname] + data_expanded['_to_add']
    
        # remove start-end cols, as well as temp cols used for calculations:
        to_drop = [start_dt_colname, end_dt_colname, '_to_add', '_dt_diff']
        if new_colname in to_drop:
            to_drop.remove(new_colname)
        data_expanded = data_expanded.drop(columns=to_drop)
    
        # don't modify dataframe in place:
        del dataframe['_dt_diff']
    
        return data_expanded
    
    14.11.2018
    Новые материалы

    Как создать диаграмму градиентной кисти с помощью D3.js
    Резюме: Из этого туториала Вы узнаете, как добавить градиентную кисть к диаграмме с областями в D3.js. Мы добавим градиент к значениям SVG и применим градиент в качестве заливки к диаграмме с..

    Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
    Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

    Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
    В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..


    Для любых предложений по сайту: [email protected]