Присвоение результатов группирования по нескольким индексам, применение пользовательской функции, возврат к родительскому фрейму данных. - PullRequest
0 голосов
/ 25 октября 2019

У меня есть фрейм данных, в котором я хочу сгруппировать по 2 столбцам, вычесть четные из нечетных строк 3-го столбца в каждой группе и назначить результаты столбцу в исходном фрейме данных. Ничто из того, что я пробую из других ответов, похоже, не работает для меня.

Пример dataframe:

    ID Day OtherInfo log_timestamp
    A  17   foo       t1
    A  17   bar       t2
    A  18   footoo    t3
    A  18   bar_bar   t4

где log_timestamp - объект datetime.

Нужный результат долженвыглядело примерно так:

    ID Day OtherInfo log_timestamp duration
    A  17   foo       t1           (t2-t1)
    A  17   bar       t2 
    A  18   footoo    t3            (t4-t3)
    A  18   bar_bar   t4

Я пробовал комбинации определения моей собственной функции, использования лямбда-функции и использования "apply", "agg", "map" и "transform", но я не совсемполучить его.

>>>my_df['duration'] = my_df.groupby(['ID', 'day'])['log_timestamp'].agg({'duration': lambda series: (series - series.shift())[1::2].reset_index(drop=True)})
TypeError: incompatible index of inserted column with frame index

>>>my_df['duration'] = my_df['day'].map(my_df.groupby(['ID', 'day'])['log_timestamp'].apply({'duration': lambda series: (series - series.shift())[1::2].reset_index(drop=True)}))
TypeError: unhashable type: 'dict'

>>>my_df['duration'] = my_df.groupby(['ID', 'day'])['log_timestamp'].transform(lambda series: (series - series.shift())[1::2].reset_index(drop=True))
ValueError: Length of passed values is 1, index implies 2

1 Ответ

1 голос
/ 25 октября 2019

Я использовал следующий тест DataFrame (с «истинными» временными метками):

  ID  Day OtherInfo       log_timestamp
0  A   17       foo 2019-09-01 10:20:00
1  A   17       bar 2019-09-01 11:30:00
2  A   18    footoo 2019-09-01 15:10:00
3  A   18   bar_bar 2019-09-01 15:55:00

Начнем с определения функции, вычисляющей 2 значения результата из 2 исходных значений (временных меток):

def fn(grp):
    return [grp.iloc[1] - grp.iloc[0], np.nan]

Первое возвращаемое значение является разницей, а второе - NaN .

Используйте его следующим образом:

df['duration'] = df.groupby(np.arange(len(df.index)) // 2)\
    .log_timestamp.transform(fn)

Результат:

  ID  Day OtherInfo       log_timestamp duration
0  A   17       foo 2019-09-01 10:20:00 01:10:00
1  A   17       bar 2019-09-01 11:30:00      NaT
2  A   18    footoo 2019-09-01 15:10:00 00:45:00
3  A   18   bar_bar 2019-09-01 15:55:00      NaT

groupby (np.arange (len (df.index)) // 2) - это пандазонская «идиома» для группировки DataFrame (или * 1021)* Series ) на группы по 2 строки (или элементы).

Затем transform (fn) генерирует последовательность значений, что-то вроде «копии» исходной последовательности (пара отметок времени).

Таким образом, первое возвращаемое значение - разница между обеими отметками времени - это новое значение для первого элемента и NaN - для второго.

Поскольку столбец назначения имеет тип Отметка времени , NaN преобразуется в NaT .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...