簡體   English   中英

如何在 pandas 中重新索引基於日期時間的多重索引

[英]How to reindex a datetime-based multiindex in pandas

我有一個 dataframe,它計算每個用戶每天發生事件的次數。 用戶每天可能有 0 個事件,並且(因為該表是原始事件日志的匯總)dataframe 中缺少具有 0 個事件的行。我想添加這些缺失的行並按周對數據進行分組,以便每個用戶都有每周一次(如果適用,包括 0 次)。

這是我的輸入示例:

import numpy as np
import pandas as pd

np.random.seed(42)

df = pd.DataFrame({
    "person_id": np.arange(3).repeat(5),
    "date": pd.date_range("2022-01-01", "2022-01-15", freq="d"),
    "event_count": np.random.randint(1, 7, 15),
})

# end of each week
# Note: week 2022-01-23 is not in df, but should be part of the result
desired_index = pd.to_datetime(["2022-01-02", "2022-01-09", "2022-01-16", "2022-01-23"])

df
|    |   person_id | date                |   event_count |
|---:|------------:|:--------------------|--------------:|
|  0 |           0 | 2022-01-01 00:00:00 |             4 |
|  1 |           0 | 2022-01-02 00:00:00 |             5 |
|  2 |           0 | 2022-01-03 00:00:00 |             3 |
|  3 |           0 | 2022-01-04 00:00:00 |             5 |
|  4 |           0 | 2022-01-05 00:00:00 |             5 |
|  5 |           1 | 2022-01-06 00:00:00 |             2 |
|  6 |           1 | 2022-01-07 00:00:00 |             3 |
|  7 |           1 | 2022-01-08 00:00:00 |             3 |
|  8 |           1 | 2022-01-09 00:00:00 |             3 |
|  9 |           1 | 2022-01-10 00:00:00 |             5 |
| 10 |           2 | 2022-01-11 00:00:00 |             4 |
| 11 |           2 | 2022-01-12 00:00:00 |             3 |
| 12 |           2 | 2022-01-13 00:00:00 |             6 |
| 13 |           2 | 2022-01-14 00:00:00 |             5 |
| 14 |           2 | 2022-01-15 00:00:00 |             2 |

這就是我想要的結果:

|    |   person_id | level_1             |   event_count |
|---:|------------:|:--------------------|--------------:|
|  0 |           0 | 2022-01-02 00:00:00 |             9 |
|  1 |           0 | 2022-01-09 00:00:00 |            13 |
|  2 |           0 | 2022-01-16 00:00:00 |             0 |
|  3 |           0 | 2022-01-23 00:00:00 |             0 |
|  4 |           1 | 2022-01-02 00:00:00 |             0 |
|  5 |           1 | 2022-01-09 00:00:00 |            11 |
|  6 |           1 | 2022-01-16 00:00:00 |             5 |
|  7 |           1 | 2022-01-23 00:00:00 |             0 |
|  8 |           2 | 2022-01-02 00:00:00 |             0 |
|  9 |           2 | 2022-01-09 00:00:00 |             0 |
| 10 |           2 | 2022-01-16 00:00:00 |            20 |
| 11 |           2 | 2022-01-23 00:00:00 |             0 |

我可以使用以下方法生產它:

(
    df
    .groupby(["person_id", pd.Grouper(key="date", freq="w")]).sum()
    .groupby("person_id").apply(
        lambda df: (
            df
            .reset_index(drop=True, level=0)
            .reindex(desired_index, fill_value=0))
        )
    .reset_index()
)

但是,根據reindex的文檔,我應該可以直接將它與level=1一起用作 kwarg,而無需再執行一次groupby 但是,當我這樣做時,我得到了兩個索引的“內部連接”而不是“外部連接”:

result = (
    df
    .groupby(["person_id", pd.Grouper(key="date", freq="w")]).sum()
    .reindex(desired_index, level=1)
    .reset_index()
)
|    |   person_id | date                |   event_count |
|---:|------------:|:--------------------|--------------:|
|  0 |           0 | 2022-01-02 00:00:00 |             9 |
|  1 |           0 | 2022-01-09 00:00:00 |            13 |
|  2 |           1 | 2022-01-09 00:00:00 |            11 |
|  3 |           1 | 2022-01-16 00:00:00 |             5 |
|  4 |           2 | 2022-01-16 00:00:00 |            20 |

為什么會這樣,我應該如何正確使用df.reindex


我發現了一個關於重新索引多索引級別的類似 SO 問題,但那里接受的答案使用df.unstack ,這對我不起作用,因為並不是我想要的索引的每個級別都出現在我當前的索引中(反之亦然) ).

您需要通過兩個級別的MultiIndex重新索引:

mux = pd.MultiIndex.from_product([df['person_id'].unique(), desired_index], 
                                 names=['person_id','date'])
result = (
    df
    .groupby(["person_id", pd.Grouper(key="date", freq="w")]).sum()
    .reindex(mux, fill_value=0)
    .reset_index()
)
print (result)
    person_id       date  event_count
0           0 2022-01-02            9
1           0 2022-01-09           13
2           0 2022-01-16            0
3           0 2022-01-23            0
4           1 2022-01-02            0
5           1 2022-01-09           11
6           1 2022-01-16            5
7           1 2022-01-23            0
8           2 2022-01-02            0
9           2 2022-01-09            0
10          2 2022-01-16           20
11          2 2022-01-23            0

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM