如何使用python为所有id填充缺失的日期

rqqzpn5f  于 2023-08-08  发布在  Python
关注(0)|答案(3)|浏览(130)

我有一个pandas dataframe A,ID,date_yyyymmdd,金额和小时如下所示。并非所有日历日期都已填充。
| 日期_yyyymmdd|数量|小时数| hours |
| --|--|--| ------------ |
| 20230101|一千四百二十八点九五|十一个| 11 |
| 20230103|一七九一点二九|十三个| 13 |
| 20230101| 2516.84|十五个| 15 |
| 20230105| 3046.08|五个| 5 |
| 20230102|七一三七点九二|十一个| 11 |
| 20230103|一千一百零四点三十五|一个| 1 |
| 20230104|二十五个|一个| 1 |
我想在两个变量start_date和end_date之间填充缺少的日历日期,并生成另一个数据框B,如下所示,并将这些日期的金额和小时数填充为0。在下面的示例中,开始日期是20230101,结束日期是20230105。我发现了一个使用日期作为索引并填充缺失值的代码。我不认为它会在我的情况下工作。我想为每个ID填写日期。我怎么能做到这一点?- 谢谢-谢谢
| 日期_yyyymmdd|数量|小时数| hours |
| --|--|--| ------------ |
| 20230101|一千四百二十八点九五|十一个| 11 |
| 20230102| 0个|0个| 0 |
| 20230103|一七九一点二九|十三个| 13 |
| 20230104| 0个|0个| 0 |
| 20230105| 0个|0个| 0 |
| 20230101| 2516.84|十五个| 15 |
| 20230102| 0个|0个| 0 |
| 20230103| 0个|0个| 0 |
| 20230104| 0个|0个| 0 |
| 20230105| 3046.08|五个| 5 |
| 20230101| 0个|0个| 0 |
| 20230102|七一三七点九二|十一个| 11 |
| 20230103|一千一百零四点三十五|一个| 1 |
| 20230104|二十五个|一个| 1 |
| 20230105| 0个|0个| 0 |

smdnsysy

smdnsysy1#

下面是一种方法,通过构造一个新的MultiIndex,并使用它来reindex您的df。

cols = ['id','date_yyyymmdd']

start_date = '1/1/2023'
end_date = '1/5/2023'

df['date_yyyymmdd'] = pd.to_datetime(df['date_yyyymmdd'],format = '%Y%m%d')

df = (df.set_index(cols)
      .reindex(pd.MultiIndex.from_product([df['id'].unique(),pd.date_range(start_date,end_date,freq='D')],names = cols))
      .fillna(0)
      .sort_index()
      .reset_index())

字符串
输出量:

id date_yyyymmdd   amount  hours
0    1    2023-01-01  1428.95   11.0
1    1    2023-01-02     0.00    0.0
2    1    2023-01-03  1791.29   13.0
3    1    2023-01-04     0.00    0.0
4    1    2023-01-05     0.00    0.0
5    2    2023-01-01  2516.84   15.0
6    2    2023-01-02     0.00    0.0
7    2    2023-01-03     0.00    0.0
8    2    2023-01-04     0.00    0.0
9    2    2023-01-05  3046.08    5.0
10   3    2023-01-01     0.00    0.0
11   3    2023-01-02  7137.92   11.0
12   3    2023-01-03  1104.35    1.0
13   3    2023-01-04    25.00    1.0
14   3    2023-01-05     0.00    0.0

wgx48brx

wgx48brx2#

试试看:

df["date_yyyymmdd"] = pd.to_datetime(df["date_yyyymmdd"], format="%Y%m%d")
r = pd.date_range(df["date_yyyymmdd"].min(), df["date_yyyymmdd"].max())

df = (
    df.groupby("id", group_keys=False)
    .apply(
        lambda x: (newdf := x.set_index("date_yyyymmdd").reindex(r)).assign(
            id=newdf["id"].ffill().bfill()
        )
    )
    .reset_index()
    .fillna(0)
)
df["id"] = df["id"].astype(int)

print(df)

字符串
印刷品:

index  id   amount  hours
0  2023-01-01   1  1428.95   11.0
1  2023-01-02   1     0.00    0.0
2  2023-01-03   1  1791.29   13.0
3  2023-01-04   1     0.00    0.0
4  2023-01-05   1     0.00    0.0
5  2023-01-01   2  2516.84   15.0
6  2023-01-02   2     0.00    0.0
7  2023-01-03   2     0.00    0.0
8  2023-01-04   2     0.00    0.0
9  2023-01-05   2  3046.08    5.0
10 2023-01-01   3     0.00    0.0
11 2023-01-02   3  7137.92   11.0
12 2023-01-03   3  1104.35    1.0
13 2023-01-04   3    25.00    1.0
14 2023-01-05   3     0.00    0.0

63lcw9qa

63lcw9qa3#

一个选项是具有pyjanitor's完整功能:

# pip install pyjanitor
import janitor
import pandas as pd

df = pd.read_clipboard()
df['date_yyyymmdd'] = pd.to_datetime(df['date_yyyymmdd'],format = 'ISO8601')
# create variable containing all possible dates
dates = {"date_yyyymmdd": pd.date_range("2023-01-01", "2023-01-05", freq="D")}
df.complete('id', dates, fill_value=0)
    id date_yyyymmdd   amount  hours
0    1    2023-01-01  1428.95     11
1    1    2023-01-02     0.00      0
2    1    2023-01-03  1791.29     13
3    1    2023-01-04     0.00      0
4    1    2023-01-05     0.00      0
5    2    2023-01-01  2516.84     15
6    2    2023-01-02     0.00      0
7    2    2023-01-03     0.00      0
8    2    2023-01-04     0.00      0
9    2    2023-01-05  3046.08      5
10   3    2023-01-01     0.00      0
11   3    2023-01-02  7137.92     11
12   3    2023-01-03  1104.35      1
13   3    2023-01-04    25.00      1
14   3    2023-01-05     0.00      0

字符串

相关问题