Подсчитать рабочий день между использованием колонн панд - PullRequest
0 голосов
/ 18 сентября 2018

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

    MonthBegin  MonthEnd
0   2014-06-09  2014-06-30
1   2014-07-01  2014-07-31
2   2014-08-01  2014-08-31
3   2014-09-01  2014-09-30
4   2014-10-01  2014-10-31

Я попытался применить numpy.busday_count, но получаю следующую ошибку:

Iterator operand 0 dtype could not be cast from dtype('<M8[ns]') to dtype('<M8[D]') according to the rule 'safe'

Я пытался изменить тип на метку времени следующим образом:

Timestamp('2014-08-31 00:00:00')

или datetime:

datetime.date(2014, 8, 31)

или numpy.datetime64:

numpy.datetime64('2014-06-30T00:00:00.000000000')

Кто-нибудь знает, как это исправить?

Примечание 1. Я прошел попытку np.busday_count двумя способами: 1. Передача столбцов данных, t['Days']=np.busday_count(t.MonthBegin,t.MonthEnd)

Передача массивов np.busday_count(dt1,dt2)

Примечание 2: Мой фрейм данных содержит более 150 тыс. Строк, поэтому мне нужно использовать эффективный алгоритм

Ответы [ 4 ]

0 голосов
/ 18 сентября 2018

Вы можете изменить свой код, чтобы получить желаемый результат, как показано ниже:

df = pd.DataFrame({'MonthBegin': ['2014-06-09', '2014-08-01', '2014-09-01', '2014-10-01', '2014-11-01'],
                   'MonthEnd': ['2014-06-30', '2014-08-31', '2014-09-30', '2014-10-31', '2014-11-30']})
df['MonthBegin'] = df['MonthBegin'].astype('datetime64[ns]')
df['MonthEnd'] = df['MonthEnd'].astype('datetime64[ns]')
df['BDays'] = np.busday_count(df['MonthBegin'].tolist(), df['MonthEnd'].tolist())
print(df)

  MonthBegin   MonthEnd  BDays
0 2014-06-09 2014-06-30     15
1 2014-08-01 2014-08-31     21
2 2014-09-01 2014-09-30     21
3 2014-10-01 2014-10-31     22
4 2014-11-01 2014-11-30     20

Кроме того, numpy.busday_count имеет несколько других необязательных аргументов, таких как Weekmask, праздничные дни ..., которые вы можете использовать в соответствии с вашими потребностями.Надеюсь, это поможет.

0 голосов
/ 18 сентября 2018

Вам необходимо предоставить шаблон, в котором написаны ваши даты.

 a = datetime.strptime('2014-06-9', '%Y-%m-%d')

Рассчитайте это для ваших

b = datetime.strptime('2014-06-30', '%Y-%m-%d')

Теперь их разница

c = b-a
c.days 

что дает вам разницу в 21 день. Теперь вы можете использовать понимание списка, чтобы получить разницу между двумя датами в виде дней.даст вам datetime.timedelta (21), чтобы преобразовать его в дни, просто используйте

0 голосов
/ 18 сентября 2018

Я думаю, что лучший способ сделать это

df.apply(lambda row : np.busday_count(row['MBegin'],row['MEnd']),axis=1)

Для моего кадра данных df, как показано ниже:

      MBegin          MEnd
0   2011-01-01  2011-02-01
1   2011-01-10  2011-02-10
2   2011-01-02  2011-02-02

делать:

df['MBegin'] = df['MBegin'].values.astype('datetime64[D]')
df['MEnd'] = df['MEnd'].values.astype('datetime64[D]')
df['busday'] = df.apply(lambda row : np.busday_count(row['MBegin'],row['MEnd']),axis=1)

>>df

     MBegin         MEnd   busday
0   2011-01-01  2011-02-01  21
1   2011-01-10  2011-02-10  23
2   2011-01-02  2011-02-02  22
0 голосов
/ 18 сентября 2018

Вы можете использовать bdate_range, также я исправил ваш ввод, так как большая часть MonthEnd раньше, чем MonthBegin

[len(pd.bdate_range(x,y))for x,y in zip(df['MonthBegin'],df['MonthEnd'])]
Out[519]: [16, 21, 22, 23, 20]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...