我有一个看起来像这样的数据框
customer Start_date End_date
100 2016-06-01 2018-01-01
101 2017-06-01 2019-01-01
102 2016-04-01 2017-04-01
103 2015-06-03 2016-01-01
104 2016-06-01 2018-01-01
现在我想创建一个带有句点索引的数据框,该索引的列数包含每个句点的客户数量,如下所示:
Period Customers
2017-01 3
2017-02 5
2017-03 8
2017-04 9
我已经编写了一个自定义循环来执行此操作,但它非常低效。必须有一种更快的方法来使用pandas功能来完成这项工作。非常感谢任何帮助!
答案 0 :(得分:2)
您可以按to_period
创建月份期间,列表理解每个customer
的所有期间和groupby
的最后nunique
:
df['Start_date'] = pd.to_datetime(df['Start_date']).dt.to_period('m')
df['End_date'] = pd.to_datetime(df['End_date']).dt.to_period('m')
#if want exclude last periods per rows subtract 1
#df['End_date'] = pd.to_datetime(df['End_date']).dt.to_period('m') - 1
L = [(a, d) for a,b,c in df.values for d in pd.period_range(b,c, freq='m')]
for all unique customers per period
df = pd.DataFrame(L, columns=['v','d']).groupby('d')['v'].nunique()
print (df.head(10))
d
2015-06 1
2015-07 1
2015-08 1
2015-09 1
2015-10 1
2015-11 1
2015-12 1
2016-01 1
2016-04 1
2016-05 1
Freq: M, dtype: int64
包含测试解决方案的不同数据的示例:
print (df)
customer Start_date End_date
0 100 2016-03-01 2016-06-01
1 100 2016-08-01 2016-10-01
2 102 2016-04-01 2017-01-01
3 103 2016-06-03 2016-01-01
4 103 2016-06-01 2016-05-01
df['Start_date'] = pd.to_datetime(df['Start_date']).dt.to_period('m')
df['End_date'] = pd.to_datetime(df['End_date']).dt.to_period('m')
L = [(a, d) for a,b,c in df.values for d in pd.period_range(b,c, freq='m')]
df = pd.DataFrame(L, columns=['v','d'])
print (df)
v d
0 100 2016-03
1 100 2016-04
2 100 2016-05
3 100 2016-06
4 100 2016-08
5 100 2016-09
6 100 2016-10
7 102 2016-04
8 102 2016-05
9 102 2016-06
10 102 2016-07
11 102 2016-08
12 102 2016-09
13 102 2016-10
14 102 2016-11
15 102 2016-12
16 102 2017-01
df1 = df.groupby('d')['v'].nunique().reset_index()
print (df1)
d v
0 2016-03 1
1 2016-04 2
2 2016-05 2
3 2016-06 2
4 2016-07 1
5 2016-08 2
6 2016-09 2
7 2016-10 2
8 2016-11 1
9 2016-12 1
10 2017-01 1
答案 1 :(得分:1)
DT[,ReplB := all(diff(mapply(function(x)which(letters==x),place)) == 1),by=id][
!(ReplB & place == "c"),.(id, place = ifelse(place=="b" & ReplB,"z",place),seq)]
# id place seq
# 1: 1 a 1
# 2: 1 z 2
# 3: 1 d 4
# 4: 2 a 1
# 5: 2 b 2
# 6: 2 d 3
# 7: 2 e 4