[英]How to create a specific date_range for each unique id in a dataframe?
我想为数据集中的每个客户创建一个日期范围。 每个客户都有自己的范围。 如果没有 for 循环,如何做到这一点?
样本数据:
import pandas as pd
dates = ['2018-01', '2018-04', '2018-10', '2018-11', '2018-12', '2018-01', '2018-04']
customers = ['A', 'A', 'A', 'A', 'A', 'B', 'B']
df = pd.DataFrame({'customers':customers, 'date':dates})
df.head(10)
现在我希望每个客户的每一行都有一个月的时间,分别是他们的最短和最长日期,以获得:
import pandas as pd
dates = ['2018-01', '2018-02', '2018-03', '2018-04', '2018-05', '2018-06', '2018-07', '2018-08', '2018-09', '2018-10', '2018-11', '2018-12', '2018-01', '2018-02', '2018-03', '2018-04']
customers = ['A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B','B']
df1 = pd.DataFrame({'customers':customers, 'date':dates})
df1.head(16)
我的尝试是使用 for 循环,遍历每个客户,但速度太慢。 如何让它更快?
def get_date_frame(start_date, end_date):
date_frame = pd.date_range(start=start_date, end=end_date, freq='MS')
date_frame = pd.DataFrame(pd.DataFrame(date_frame.astype(str))[0].str[:7])
date_frame.columns = ['date']
return date_frame
for idx, jk in (enumerate(['A', 'B'])):
guy = df[df['customers']==jk]['date'] #get the data for that customer
guy.reset_index(drop=True, inplace=True) #reset
start = guy[0] #first date
end = guy[len(guy)-1] #last date
dframe = get_date_frame(start, end) #get range of dates
dframe['customer'] = jk #add customer id
if idx == 0:
out = dframe.copy()
else:
out = pd.concat((out, dframe.copy()), axis = 0) #concat outputs
df['date'] = pd.to_datetime(df['date'], format='%Y-%d')
df2 = df.groupby(['customers']).apply(
lambda x: x.set_index('date')
.reindex(pd.date_range(start = x['date'].min(), end = x['date'].max()))
.ffill()
.rename_axis('date')
.reset_index())
print(df2)
date customers
customers
A 0 2018-01-01 A
1 2018-01-02 A
2 2018-01-03 A
3 2018-01-04 A
4 2018-01-05 A
5 2018-01-06 A
6 2018-01-07 A
7 2018-01-08 A
8 2018-01-09 A
9 2018-01-10 A
10 2018-01-11 A
11 2018-01-12 A
B 0 2018-01-01 B
1 2018-01-02 B
2 2018-01-03 B
3 2018-01-04 B
此外,如果您想转换日期列,则
df2 = df2.droplevel('customers') #drop the index customer
df2['date'] = df2['date'].dt.year.astype(str) +'-'+ df2['date'].dt.day.astype(str)
date customers
0 2018-1 A
1 2018-2 A
2 2018-3 A
3 2018-4 A
4 2018-5 A
5 2018-6 A
6 2018-7 A
7 2018-8 A
8 2018-9 A
9 2018-10 A
10 2018-11 A
11 2018-12 A
0 2018-1 B
1 2018-2 B
2 2018-3 B
3 2018-4 B
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.