熊猫pivot_table:“ margins = True”显示带有“ Period”列的“ NaN”

时间:2019-09-06 11:12:30

标签: python pandas

以下代码重现了我遇到的问题:

import pandas as pd

df = pd.DataFrame(
    {
        "a": [1, 1, 2, 2],
        "b": [
            pd.Period("2019Q1"),
            pd.Period("2019Q2"),
            pd.Period("2019Q1"),
            pd.Period("2019Q2"),
        ],
        "x": 1.0,
    }
)

df.pivot_table(index="a", columns="b", values="x", margins=True)

输出:

b   2019Q1  2019Q2  All
a           
1   1.0     1.0     1.0
2   1.0     1.0     1.0
All NaN     NaN     1.0

为什么NaN小计?我本来期望:

b   2019Q1  2019Q2  All
a           
1   1.0     1.0     1.0
2   1.0     1.0     1.0
All 1.0     1.0     1.0

这发生在Period列中。

1 个答案:

答案 0 :(得分:0)

如果还有其他人偶然发现此问题,那确实是一个错误,相关的GitHub问题是#28323#28337


潜在的问题是由get_indexer的{​​{1}}方法引起的。现在,在重新索引时,将使用PeriodIndex的{​​{1}}而不是实际的PeriodIndex。相关代码can be found here,摘要如下:

PeriodIndex

如果使用另一个_int64index重新建立索引,这显然可以很好地工作,因为目标也被转换为if isinstance(target, PeriodIndex): target = target.asi8 if tolerance is not None: tolerance = self._convert_tolerance(tolerance, target) return Index.get_indexer(self._int64index, target, method, limit, tolerance) ,但是如果另一个索引不是 PeriodIndex,这是行为的一个小例子。

int

显然,这不是理想的行为,解决方案是仅在与另一个PeriodIndex重新建立索引时使用>>> i = pd.PeriodIndex([pd.Period("2019Q1", "Q-DEC"), pd.Period("2019Q2", "Q-DEC")]) >>> j = pd.Index([pd.Period("2019Q1", "Q-DEC"), 'All']) >>> s = pd.Series([1, 2], index=i) >>> s 2019Q1 1 2019Q2 2 Freq: Q-DEC, dtype: int64 >>> s.reindex(j) 2019Q1 NaN All NaN dtype: float64 >>> s.index._int64index Int64Index([196, 197], dtype='int64') >>> s.reindex([196]) 196 1 dtype: int64 ,否则使用常规的_int64index。我提交了一份PR来解决此问题,希望可以尽快将其包括在内。