在熊猫数据框中填充缺少的复合索引

时间:2020-08-07 19:39:18

标签: python pandas seaborn

我的原始数据如下:

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,
    },
]

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

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()

图表如下:

enter image description here

现在很酷,它可以直观显示每天的状态。但是我想做的是填补两天之间的“空白”,因为我可能需要实际可视化从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,它是关于在日期时间索引中添加缺失的日子。这是我想要的,但是我想我每天也需要保持状态为空。

我可以使用内置的熊猫功能创建所需的数据框吗?

2 个答案:

答案 0 :(得分:2)

全球范围内,您可以随时使用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

答案 1 :(得分:2)

使用多索引和重新索引的另一种方法:

idx = pd.date_range('2020-08-01','2020-08-05').strftime('%d.%m.%Y')
idx1 = pd.MultiIndex.from_product((idx,(df['status'].unique())),names=['date','status'])
grp = (df.groupby(['date', 'status']).size().reindex(idx1,fill_value=0)
         .reset_index(name="count"))

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

enter image description here