Pandas Dataframe Groupby и получить диапазон дат - PullRequest
0 голосов
/ 26 октября 2018

Вот мой фрейм данных, над которым я работаю. Определены два периода оплаты: первые 15 дней и последние 15 дней для каждого месяца.

         date  employee_id hours_worked   id job_group  report_id
0  2016-11-14            2         7.50  385         B         43
1  2016-11-15            2         4.00  386         B         43
2  2016-11-30            2         4.00  387         B         43
3  2016-11-01            3        11.50  388         A         43
4  2016-11-15            3         6.00  389         A         43
5  2016-11-16            3         3.00  390         A         43
6  2016-11-30            3         6.00  391         A         43

Мне нужно сгруппировать по идентификатору сотрудника и job_group, но в то же время Я должен достичь диапазона дат для этой сгруппированной строки. Это означает Например, сгруппированные результаты будут такими же, как и для идентификатора сотрудника 1:

Ожидаемый результат:

         date  employee_id hours_worked  job_group  report_id
1  2016-11-15            2         11.50        B         43
2  2016-11-30            2         4.00         B         43
4  2016-11-15            3         17.50        A         43
5  2016-11-16            3         9.00         A         43

Возможно ли это с помощью группы данных pandas groupby? Пожалуйста, помогите спасибо. Дайте мне знать, если вопрос не ясен.

Ответы [ 2 ]

0 голосов
/ 26 октября 2018

а.Сначала (для каждого employee_id) используйте , кратное Grouper с .sum() в столбце hours_worked.Во-вторых, используйте DateOffset, чтобы получить двухнедельный столбец date.После этих 2 шагов я назначил date в сгруппированном DF на основе 2 скобок (диапазонов дат) - если day of month (из столбца date) равно <= 15, то яустановите <code>day в date на 15, иначе я установлю day на 30. Затем этот day используется для сборки нового date.Я рассчитал день окончания месяца на основе 1 , 2 .

b.(Для каждого employee_id) получите запись .last() для столбцов job_group и report_id

c.объединитьи б.на клавише employee_id

# a.
hours = (df.groupby([
            pd.Grouper(key='employee_id'),
            pd.Grouper(key='date', freq='SM')
                    ])['hours_worked']
            .sum()
            .reset_index())
hours['date'] = pd.to_datetime(hours['date'])
hours['date'] = hours['date'] + pd.DateOffset(days=14)

# Assign day based on bracket (date range) 0-15 or bracket (date range) >15
from pandas.tseries.offsets import MonthEnd
hours['bracket'] = hours['date'] + MonthEnd(0)
hours['bracket'] = pd.to_datetime(hours['bracket']).dt.day
hours.loc[hours['date'].dt.day <= 15, 'bracket'] = 15
hours['date'] = pd.to_datetime(dict(year=hours['date'].dt.year,
                                    month=hours['date'].dt.month,
                                    day=hours['bracket']))
hours.drop('bracket', axis=1, inplace=True)

# b.
others = (df.groupby('employee_id')['job_group','report_id']
            .last()
            .reset_index())

# c.
merged = hours.merge(others, how='inner', on='employee_id')

Необработанные данные для employee_id==1 и employeeid==3

df.sort_values(by=['employee_id','date'], inplace=True)
print(df[df.employee_id.isin([1,3])])

    index       date  employee_id  hours_worked   id job_group  report_id
0       0 2016-11-14            1           7.5  481         A         43
10     10 2016-11-21            1           6.0  491         A         43
11     11 2016-11-22            1           5.0  492         A         43
15     15 2016-12-14            1           7.5  496         A         43
25     25 2016-12-21            1           6.0  506         A         43
26     26 2016-12-22            1           5.0  507         A         43
6       6 2016-11-02            3           6.0  487         A         43
4       4 2016-11-08            3           6.0  485         A         43
3       3 2016-11-09            3          11.5  484         A         43
5       5 2016-11-11            3           3.0  486         A         43
20     20 2016-11-12            3           3.0  501         A         43
21     21 2016-12-02            3           6.0  502         A         43
19     19 2016-12-08            3           6.0  500         A         43
18     18 2016-12-09            3          11.5  499         A         43

Вывод

print(merged)

    employee_id       date  hours_worked job_group  report_id
0             1 2016-11-15           7.5         A         43
1             1 2016-11-30          11.0         A         43
2             1 2016-12-15           7.5         A         43
3             1 2016-12-31          11.0         A         43
4             2 2016-11-15          31.0         B         43
5             2 2016-12-15          31.0         B         43
6             3 2016-11-15          29.5         A         43
7             3 2016-12-15          23.5         A         43
8             4 2015-03-15           5.0         B         43
9             4 2016-02-29           5.0         B         43
10            4 2016-11-15           5.0         B         43
11            4 2016-11-30          15.0         B         43
12            4 2016-12-15           5.0         B         43
13            4 2016-12-31          15.0         B         43
0 голосов
/ 26 октября 2018

Используйте SM с Grouper и последним добавлением SemiMonthEnd:

df['date'] = pd.to_datetime(df['date'])

d = {'hours_worked':'sum','report_id':'first'}
df = (df.groupby(['employee_id','job_group',pd.Grouper(freq='SM',key='date', closed='right')])
       .agg(d)
       .reset_index())

df['date'] = df['date'] + pd.offsets.SemiMonthEnd(1)
print (df)
   employee_id job_group       date  hours_worked  report_id
0            2         B 2016-11-15          11.5         43
1            2         B 2016-11-30           4.0         43
2            3         A 2016-11-15          17.5         43
3            3         A 2016-11-30           9.0         43
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...