填充数据框中缺失的日期值

时间:2021-07-19 22:04:09

标签: python pandas numpy

我有一个数据框 df,我想在其中填写缺失的日期值以及缺失的 id。 我还有一些 id 值要添加到数据框中,例如“dd”、“ee”等。

数据

id  date    pwr
aa  Q1.22   10
aa  Q1.22   1
aa  Q2.22   1
aa  Q2.22   5
bb  Q1.22   5
bb  Q1.22   1
bb  Q2.22   1
bb  Q2.22   1
cc  Q1.22   2
cc  Q2.22   2

需要

id  date    pwr
aa  Q1.22   10
aa  Q1.22   1
aa  Q2.22   1
aa  Q2.22   5
aa  Q3.22   
aa  Q4.22   
bb  Q1.22   5
bb  Q1.22   1
bb  Q2.22   1
bb  Q2.22   1
bb  Q3.22   
bb  Q4.22   
cc  Q1.22   2
cc  Q2.22   2
cc  Q3.22   
cc  Q4.22   
dd  Q1.22   
dd  Q2.22   
dd  Q3.22   
dd  Q4.22   

我相信我必须建立一个范围,但不确定如何将日期包括在内。 我还在研究。任何建议表示赞赏。

r = pd.date_range(start=df.dt.min(), end=df.dt.max())
df.set_index('dt').reindex(r).fillna(0.0).rename_axis('dt').reset_index()

2 个答案:

答案 0 :(得分:2)

将日期转换为期间日期类型:

pat = r"(?P<Q>.)(?P<quarter>\d+)\.(?P<year>.+)"
repl = lambda m: f"{m.group('quarter')}{m.group('Q')}20{m.group('year')}"
df = df.assign(date = df.date
                       .str.replace(pat, repl, regex=True)
                       .transform(pd.Period)
               )

df
 
   id    date  pwr
0  aa  2022Q1   10
1  aa  2022Q1    1
2  aa  2022Q2    1
3  aa  2022Q2    5
4  bb  2022Q1    5
5  bb  2022Q1    1
6  bb  2022Q2    1
7  bb  2022Q2    1
8  cc  2022Q1    2
9  cc  2022Q2    2

df.dtypes
 
id             object
date    period[Q-DEC]
pwr             int64
dtype: object

暴露缺失值的一种便捷方法是使用 complete 中的 pyjanitor 函数:

# create the period ranges within a dictionary
new_values = {"date" : lambda date: pd.period_range(date.min(), 
                                          periods = 4)}

new_values = [new_values]

# pip install pyjanitor
import janitor
import pandas as pd
df.complete(new_values, by='id')
 
    id    date   pwr
0   aa  2022Q1  10.0
1   aa  2022Q1   1.0
2   aa  2022Q2   1.0
3   aa  2022Q2   5.0
4   aa  2022Q3   NaN
5   aa  2022Q4   NaN
6   bb  2022Q1   5.0
7   bb  2022Q1   1.0
8   bb  2022Q2   1.0
9   bb  2022Q2   1.0
10  bb  2022Q3   NaN
11  bb  2022Q4   NaN
12  cc  2022Q1   2.0
13  cc  2022Q2   2.0
14  cc  2022Q3   NaN
15  cc  2022Q4   NaN

仅使用 Pandas,让我们从 df 获取唯一行:

temp = df.drop_duplicates(['id', 'date'])

唯一值的原因是我们可以为每个 id 创建周期范围并重新索引(重新索引不适用于非唯一索引):

temp = (temp
        .set_index('date')
        .groupby('id')
        .apply(lambda df: df.reindex(pd.period_range(df.index.min(), 
                                                     periods = 4)))
        .drop(columns=['id', 'pwr'])
        )

让我们加入temp回到df

In [119]: df.merge(temp, 
                   left_on=['id', 'date'], 
                   right_index = True, 
                   how = 'right')
Out[119]: 
   id    date   pwr
0  aa  2022Q1  10.0
1  aa  2022Q1   1.0
2  aa  2022Q2   1.0
3  aa  2022Q2   5.0
9  aa  2022Q3   NaN
9  aa  2022Q4   NaN
4  bb  2022Q1   5.0
5  bb  2022Q1   1.0
6  bb  2022Q2   1.0
7  bb  2022Q2   1.0
9  bb  2022Q3   NaN
9  bb  2022Q4   NaN
8  cc  2022Q1   2.0
9  cc  2022Q2   2.0
9  cc  2022Q3   NaN
9  cc  2022Q4   NaN

答案 1 :(得分:1)

我会用范围制作一个额外的数据框并将它们合并