【问题标题】:Slicing a Pandas dataframe with a period index with an array用数组对带有句点索引的 Pandas 数据帧进行切片
【发布时间】:2025-11-29 11:40:01
【问题描述】:

我正在尝试使用带有意外结果的字符串列表来分割由句点索引索引的 pandas 数据帧。

import pandas as pd
import numpy as np
idx = pd.period_range(1991,1993,freq='A')    
df = pd.DataFrame(np.arange(9).reshape(3,3),index=idx)
print df.loc[['1991','1993'],:]

结果:

KeyError: "None of [['1991', '1993']] are in the [index]"

如果最后一行切换到:

print df.ix[['1991','1993'],:]

输出是

Out[128]:
        0   1   2
1991    NaN NaN NaN
1993    NaN NaN NaN

如果我有一个周期索引而不是一个周期索引

idx = [str(year) for year in range(1991,1994)]
print df.loc[['1991','1993'],:]

那么输出如预期:

Out[127]:
        0   1   2
1991    0   1   2
1993    6   7   8

所以我的问题是:如何使用周期索引对 pandas 数据帧进行切片?

【问题讨论】:

    标签: python pandas slice


    【解决方案1】:

    Pandas 不会为您将字符串转换为句点,因此您必须更加明确。你可以使用:

    In [38]: df.loc[[pd.Period('1991'), pd.Period('1993')], :]
    Out[38]: 
          0  1  2
    1991  0  1  2
    1993  6  7  8
    

    In [39]: df.loc[map(pd.Period, ['1991', '1993']), :]
    Out[39]: 
          0  1  2
    1991  0  1  2
    1993  6  7  8
    

    In [40]: df.loc[[idx[0],idx[-1]], :]
    Out[40]: 
          0  1  2
    1991  0  1  2
    1993  6  7  8
    

    顺便说一句,当您将任意项目列表传递给df.loc 时,Pandas 会返回一个新的子数据帧,其中包含来自df 的值的副本。这不是一片。要切片,您需要使用切片符号:a:b。例如,

    In [64]: df.loc[pd.Period('1991'): pd.Period('1993'): 2, :]
    Out[64]: 
            0  1  2
    1991    0  1  2
    1993    6  7  8
    

    区别很重要,因为在 NumPy 和 Pandas slices return views while non-slice indexing return copies 中。

    【讨论】:

    • 您是否解释了为什么 Pandas 将字符串转换为不在列表中的句点? df.loc['1991',:] 甚至可以使用周期索引。
    • 在当前版本的 Pandas 中修复 an open issue