Pandas-添加具有重复年份的时间序列数据中缺失的年份

问题描述 投票:0回答:6

我有一个像这样的数据集,其中缺少一些年份的数据。

County Year Pop
12     1999 1.1
12     2001 1.2
13     1999 1.0
13     2000 1.1

我想要类似的东西

County Year Pop
12     1999 1.1
12     2000 NaN
12     2001 1.2
13     1999 1.0
13     2000 1.1
13     2001 nan

我尝试将索引设置为年份,然后使用仅年方法的另一个数据框重新索引(此处提到Pandas:添加缺失月份的数据),但它给了我错误无法使用重复值重新索引。我也尝试过 df.loc 但它有同样的问题。我什至尝试了仅几年的空白 df 的完整外部连接,但这也不起作用。

我该如何解决这个问题?

python pandas time-series missing-data reindex
6个回答
12
投票

创建一个多重索引,这样就不会出现重复项:

df.set_index(['County', 'Year'], inplace=True)

然后用所有组合构造一个完整的 MultiIndex:

index = pd.MultiIndex.from_product(df.index.levels)

然后重新索引:

df.reindex(index)

多重索引的构造未经测试,可能需要一些调整(例如,如果所有县都完全没有一年),但我想你明白了。


5
投票

我假设您可能想要添加最小年份和最大年份之间的所有年份。您可能会缺少

12
13
县的 2000。

我将使用

pd.MultiIndex
列中的
from_product
值以及
unique
列中最小和最大年份(包括)之间的所有整数年份构造
'County'
'Year'

注意:此解决方案会填充所有缺失的年份,即使它们当前不存在。

mux = pd.MultiIndex.from_product([
        df.County.unique(),
        range(df.Year.min(), df.Year.max() + 1)
    ], names=['County', 'Year'])

df.set_index(['County', 'Year']).reindex(mux).reset_index()

   County  Year  Pop
0      12  1999  1.1
1      12  2000  NaN
2      12  2001  1.2
3      13  1999  1.0
4      13  2000  1.1
5      13  2001  NaN

2
投票

您可以使用

pivot_table

In [11]: df.pivot_table(values="Pop", index="County", columns="Year")
Out[11]:
Year    1999  2000  2001
County
12       1.1   NaN   1.2
13       1.0   1.1   NaN

stack
结果(需要一个系列):

In [12]: df.pivot_table(values="Pop", index="County", columns="Year").stack(dropna=False)
Out[12]:
County  Year
12      1999    1.1
        2000    NaN
        2001    1.2
13      1999    1.0
        2000    1.1
        2001    NaN
dtype: float64

2
投票

或者你可以尝试一些黑魔法:P

min_year, max_year = df.Year.min(), df.Year.max()

df.groupby('County').apply(lambda g: g.set_index("Year").reindex(range(min_year, max_year+1))).drop("County", axis=1).reset_index()

2
投票

您提到您已尝试加入空白 df,并且这种方法实际上可行。

设置:

df = pd.DataFrame({'County': {0: 12, 1: 12, 2: 13, 3: 13},
 'Pop': {0: 1.1, 1: 1.2, 2: 1.0, 3: 1.1},
 'Year': {0: 1999, 1: 2001, 2: 1999, 3: 2000}})

解决方案

#create a new blank df with all the required Years for each County
df_2 = pd.DataFrame(np.r_[pd.tools.util.cartesian_product([df.County.unique(),np.arange(1999,2002)])].T, columns=['County','Year'])

#Left join the new dataframe to the existing dataframe to populate the Pop values.
pd.merge(df_2,df,on=['Year','County'],how='left')
Out[73]: 
   County  Year  Pop
0      12  1999  1.1
1      12  2000  NaN
2      12  2001  1.2
3      13  1999  1.0
4      13  2000  1.1
5      13  2001  NaN

1
投票

这是一个受已接受答案启发的函数,但适用于时间变量在不同组 ID 的不同位置开始和停止的情况。与接受的答案的唯一区别是它手动构建多重索引。

def fill_gaps_in_panel(df, group_col, year_col):
    """
    Fills the gaps in a panel by constructing an index
    based on the group col and the sequence of years between min-year
    and max-year for each group id.
    """
    index_group = []
    index_time = []
    for group in df[group_col].unique():
        _min = df.loc[df[group_col]==group, year_col].min()
        _max = df.loc[df[group_col]==group, year_col].max() + 1
        index_group.extend([group for t in range(_min, _max)])
        index_time.extend([t for t in range(_min, _max)])
    multi_index = pd.MultiIndex.from_arrays(
        [index_group, index_time], names=(group_col, year_col))
    df.set_index([group_col, year_col], inplace=True)
    return df.reindex(multi_index)
© www.soinside.com 2019 - 2024. All rights reserved.