迭代 Isoweeks 熊猫

时间:2021-04-07 14:55:34

标签: python pandas date

我有一个包含 datevalueisoweek 字段的数据框,如下所示:

date       | value | isoweek 
-----------------------------
2018-04-01 | 5     | 2018-13
2018-04-10 | 10    | 2018-15
2018-05-01 | 10    | 2018-18

其中 isoweek 是相应日期的年-周。我的目标是迭代 isoweeks,找到数据中不存在的 isoweeks,然后将一行插入到数据框中,以 0 作为值。

预期的输出如下所示:

date       | value | isoweek 
-----------------------------
2018-04-01 | 5     | 2018-13
NaN        | 0     | 2018-14
2018-04-10 | 10    | 2018-15
NaN        | 0     | 2018-16
NaN        | 0     | 2018-17
2018-05-01 | 10    | 2018-18

如何遍历原始数据框,并找到数据中所有缺失的等值周?

3 个答案:

答案 0 :(得分:2)

您可以使用 pandas.date_range() 生成每周从 startend 的日期列表。

dates = pd.Series(pd.date_range(start=df['date'].min(), end=df['date'].max(), freq='W'))
isoweeks = (dates.dt.isocalendar().year.astype(str) + '-' + dates.dt.isocalendar().week.astype(str)).tolist()
max_isoweek = str(df['date'].max().isocalendar()[0]) + '-' + str(df['date'].max().isocalendar()[1])

if max_isoweek not in isoweeks:
    isoweeks.append(max_isoweek)

这是获取 start 日期和 end 日期之间的所有 iso 周。

然后你可以将 df 合并到一个辅助数据帧中以获得你想要的。

df = df.merge(pd.DataFrame({'isoweek': isoweeks}), how='right')
df['value'].fillna(0, inplace=True)
# print(df)

        date  value  isoweek
0 2018-04-01    5.0  2018-13
1        NaT    0.0  2018-14
2 2018-04-10   10.0  2018-15
3        NaT    0.0  2018-16
4        NaT    0.0  2018-17
5 2018-05-01   10.0  2018-18

答案 1 :(得分:1)

也许有点冗长,但您可以在将 isoweek 转换为日期后尝试使用 resample

s = pd.to_datetime(df['isoweek']+"-0",format='%Y-%W-%w')
u = df.set_index(s).resample("W").first()

iso_week = u.index.year.astype(str)+'-'+u.index.weekofyear.astype(str)
u['isoweek'] = u['isoweek'].fillna(pd.Series(iso_week,index=u.index))
out = u.fillna({"value":0}).reset_index(drop=True)

print(out)

         date  value  isoweek
0  2018-04-01    5.0  2018-13
1         NaN    0.0  2018-14
2  2018-04-10   10.0  2018-15
3         NaN    0.0  2018-16
4         NaN    0.0  2018-17
5  2018-05-01   10.0  2018-18

答案 2 :(得分:1)

您可以尝试使用 apply

def func(row):
    year = (row.name)
    r = row['isoweek'].str.split('-').str[1].astype(int)
    min_week = min(r)
    max_week = max(r)
    val_range = range(min_week, max_week)
    missing = (set(val_range) - set(r.values))
    for mis_week in missing:
        row = (row.append({'isoweek': f"{year}-{mis_week}", 'date': np.nan, 'value':0}, ignore_index=True))
    return (row.sort_values(by='isoweek').reset_index(drop=True))

df.groupby(df.isoweek.str.split('-').str[0],as_index=False).apply(func)

        date        value   isoweek
 0  0   2018-04-01  5       2018-13
    1   NaN         0       2018-14
    2   2018-04-10  10      2018-15
    3   NaN         0       2018-16
    4   NaN         0       2018-17
    5   2018-05-01  10      2018-18