Назначение количества уникальных комбинаций год-месяц - PullRequest
0 голосов
/ 27 декабря 2018

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

test_df = pd.DataFrame(
    data={'email': ['a', 'a', 'b', 'b', 'c', 'c', 'c'], 
          'purchases': ['2016-08-25 01:09:42',
                        '2016-08-23 13:30:20',
                        '2018-10-23 05:33:15',
                        '2016-09-20 17:41:04',
                        '2017-04-09 17:59:00',
                        '2018-02-25 15:14:53',
                        '2016-02-25 15:14:53']})
test_df['purchases'] = pd.to_datetime(test_df['purchases'], yearfirst=True)

После этого у меня есть этот DF с purchases в качестве меток времени

   email    purchases
0   a   2016-08-25 01:09:42
1   a   2016-08-23 13:30:20
2   b   2018-10-23 05:33:15
3   b   2016-09-20 17:41:04
4   c   2017-04-09 17:59:00
5   c   2018-02-25 15:14:53
6   c   2016-02-25 15:14:53

После этого я вычисляю количество месяцев и присваиваю значения новому столбцу months_of_active:

test_df['months_of_active'] = 
pd.DatetimeIndex(test_df.purchases).to_period("M").nunique()

, который создает следующий вывод:

   email    purchases       months_of_active
0   a   2016-08-25 01:09:42   6
1   a   2016-08-23 13:30:20   6
2   b   2018-10-23 05:33:15   6
3   b   2016-09-20 17:41:04   6
4   c   2017-04-09 17:59:00   6
5   c   2018-02-25 15:14:53   6
6   c   2016-02-25 15:14:53   6

Требуемый вывод:

   email    purchases      months_of_active
0   a   2016-08-25 01:09:42   1
1   a   2016-08-23 13:30:20   1
2   b   2018-10-23 05:33:15   2
3   b   2016-09-20 17:41:04   2
4   c   2017-04-09 17:59:00   3
5   c   2018-02-25 15:14:53   3
6   c   2016-02-25 15:14:53   3

a = 1, потому что есть два похожих месяца b = 2, потому что есть два разных месяца c = 2, потому что есть два разных месяца (2 одинаковых и 1 другой)

Не могу понять, что добавить в вышеописанную функцию для выполнения to_period () на отфильтрованных сериях.

ОБНОВЛЕНИЕ: Мне также нужно учитывать годы, 2017-1 и 2018-1 будутсчитается 2.

Ответы [ 2 ]

0 голосов
/ 27 декабря 2018

Чтобы избежать преобразования в строки год-месяц или серию object dtype, вы можете нормализовать дневную и временную составляющие вашей серии datetime, а затем использовать pd.Series.nunique:

# convert purchases series to datetime
df['purchases'] = pd.to_datetime(df['purchases'])

# normalize day to 1 and zero time component
df['year_month'] = (df['purchases'] + pd.offsets.MonthBegin(1)).dt.normalize()

# calculate counts
email_counts = df.groupby('email')['year_month'].nunique()

# assign counts to series and drop helper series
df = df.assign(count=df['email'].map(email_counts)).drop('year_month', 1)

print(df)

  email           purchases  count
0     a 2016-08-25 01:09:42      1
1     a 2016-08-23 13:30:20      1
2     b 2018-10-23 05:33:15      2
3     b 2016-09-20 17:41:04      2
4     c 2017-04-09 17:59:00      3
5     c 2018-02-25 15:14:53      3
6     c 2016-02-25 15:14:53      3
0 голосов
/ 27 декабря 2018

Вам нужно сгруппироваться по «электронной почте» и использовать transform с nunique, чтобы получить уникальные значения, транслируемые в исходные строки DataFrame:

s = pd.Series(pd.DatetimeIndex(df.purchases).to_period('M'), index=df.index)
df['months_of_active'] = s.groupby(df.email).transform('nunique')


df
  email           purchases  months_of_active
0     a 2016-08-25 01:09:42                 1
1     a 2016-08-23 13:30:20                 1
2     b 2018-10-23 05:33:15                 2
3     b 2016-09-20 17:41:04                 2
4     c 2017-04-09 17:59:00                 3
5     c 2018-02-25 15:14:53                 3
6     c 2016-02-25 15:14:53                 3

В качестве альтернативы, используя dt.strftime чтобы получить комбинацию год-месяц:

df['months_of_active'] = (
   df.purchases.dt.strftime('%Y-%m').groupby(df.email).transform('nunique'))

df
  email           purchases  months_of_active
0     a 2016-08-25 01:09:42                 1
1     a 2016-08-23 13:30:20                 1
2     b 2018-10-23 05:33:15                 2
3     b 2016-09-20 17:41:04                 2
4     c 2017-04-09 17:59:00                 3
5     c 2018-02-25 15:14:53                 3
6     c 2016-02-25 15:14:53                 3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...