首页 > 解决方案 > 填充熊猫数据框中缺少的复合索引

问题描述

我的原始数据如下所示:

raw_data = [
    {
        "date": "02.08.2020",
        "status": "A",
        "id": 3948,
    },
    {
        "date": "02.08.2020",
        "status": "B",
        "id": 495,
    },
    {
        "date": "03.08.2020",
        "status": "A",
        "id": 433,
    },
    {
        "date": "03.08.2020",
        "status": "B",
        "id": 845,
    },
    {
        "date": "03.08.2020",
        "status": "B",
        "id": 54,
    },
    {
        "date": "03.08.2020",
        "status": "C",
        "id": 133,
    },
    {
        "date": "04.08.2020",
        "status": "B",
        "id": 384,
    },
    {
        "date": "04.08.2020",
        "status": "C",
        "id": 1234,
    },
]

然后我从中创建一个 pandas 数据框,并按日期和状态分组以获取每个日期、每个状态的计数:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

df = pd.DataFrame(raw_data)
grp = df.groupby(['date', 'status']).size().to_frame(name = 'count').reset_index()

print(grp)

输出:

0  02.08.2020      A      1
1  02.08.2020      B      1
2  03.08.2020      A      1
3  03.08.2020      B      2
4  03.08.2020      C      1
5  04.08.2020      B      1
6  04.08.2020      C      1

然后我使用 seaborn 绘制图表:

sns.barplot(x="date", y="count", hue="status", data=grp)
plt.show()

图表如下所示:

在此处输入图像描述

现在这很酷,它可以将每天的状态可视化。但我想做的是填补这些日子之间的“空白”,因为我可能需要实际可视化从 01.08.2020 到 05.08.2020 的数据。我希望我的数据框看起来像这样:

0   01.08.2020      A      0    <<< added 3 empty rows for 01.08.2020 bc. no data
1   01.08.2020      B      0    <<<
2   01.08.2020      C      0    <<<
3   02.08.2020      A      1
4   02.08.2020      B      1
5   03.08.2020      A      1
6   03.08.2020      B      2
7   03.08.2020      C      1
8   04.08.2020      B      1
9   04.08.2020      C      1
10  05.08.2020      A      0    <<< added 3 empty rows for 05.08.2020 bc. no data
11  05.08.2020      B      0    <<<
12  05.08.2020      C      0    <<<

这个想法是在图表 x 轴上显示从 01.08 到 05.08 的所有日期,即使没有给定日期的数据。目标是使 x 轴与从 01.08.2020 到 05.08.2020 的所有日子连续,数据或无数据。

我查看了另一个关于在日期时间索引中添加缺失天数的SO question 。这是我想要的,但我猜我还需要每天的状态为空。

我可以使用内置的 pandas 功能创建我想要的数据框吗?

标签: pythonpandasseaborn

解决方案


在全球范围内,您可以reindex在某个时候使用,这是一种创建grp所需缺失值的方法。可以groupby.size像您一样使用类似的想法结果

grp = (df.pivot_table(index='date', columns='status',
                      aggfunc='size', fill_value=0)
         .reindex(pd.Index(pd.date_range('2020-08-01', '2020-08-05').strftime('%d.%m.%Y'),
                           name='date'), 
                  fill_value=0)
         .stack()
         .reset_index(name='count')
      )
print(grp)
          date status  count
0   01.08.2020      A      0
1   01.08.2020      B      0
2   01.08.2020      C      0
3   02.08.2020      A      1
4   02.08.2020      B      1
5   02.08.2020      C      0
6   03.08.2020      A      1
7   03.08.2020      B      2
8   03.08.2020      C      1
9   04.08.2020      A      0
10  04.08.2020      B      1
11  04.08.2020      C      1
12  05.08.2020      A      0
13  05.08.2020      B      0
14  05.08.2020      C      0

推荐阅读