繁体   English   中英

如何为数据框中的每个唯一 ID 创建特定的 date_range?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM