在 python 中将缺失的行填写为 NaN

Fill in missing rows as NaN in python

我有一个文件,其中包含 83 个气象站的每日降水数据,每个气象站 101 年。我想确定每个站每年的 NaN 数量。

作为一个简短的例子,假设我只有一个站并且只关心 2009 年 1 年的数据。

如果我有这个:

 station_id  year    month   1    2     3 
 210018      2009    1       5    6     8 
 210018      2009    2      NaN  NaN    6
 210018      2009    12      8    5     6

我想讲这个:

 station_id  year    month   1    2     3 
 210018      2009    1       5    6     8 
 210018      2009    2      NaN  NaN    6
 210018      2009    3      NaN  NaN    NaN 
 210018      2009    4      NaN  NaN    NaN
 210018      2009    5      NaN  NaN    NaN 
 210018      2009    6      NaN  NaN    NaN 
 210018      2009    7      NaN  NaN    NaN
 210018      2009    8      NaN  NaN    NaN 
 210018      2009    9      NaN  NaN    NaN
 210018      2009    10     NaN  NaN    NaN 
 210018      2009    11     NaN  NaN    NaN
 210018      2009    12      8    5      6

所以我的电台需要 12 行来表示所有 12 个月和一年的每一行。在真实的例子中我又一次有 101 年。

我正在尝试使用此代码:

df_indexed=df.set_index(['year'])
new_index=np.arange(1910,2011,1)
idx=pd.Index(new_index)
df2=df_indexed.reindex(idx, method=None)

但它 returns 一个以

结尾的长错误

ValueError: cannot reindex from a duplicate axis

我希望这是有道理的。

[编辑]

这不是 PANDAS 答案:当我开始回答时,问题没有被标记 pandas,我会把它放在这里,因为它可以使某人受益。

假设您使用字典组织数据,其中键是 (station_id, year, month) 的元组,值是数据点的数组 - 您可以使用 collections.defaultdict:

>>> data = defaultdict(lambda: [None, None, None])
>>> data[(210018, 2009, 3)]
[None, None, None]

您可能正在从文件中读取,我不会为您完成所有作业 - 只提供一些提示。

for line in file:
    station_id, year, month, d1, d2, d3 = parse_line(line)
    data[(station_id, year, month)] = [
        None if d == 'NaN' else float(d) for d in (d1, d2, d3)
    ]

编写 parse_line 函数留作 reader 的练习。

我可能会做的是创建一个目标 MultiIndex,然后使用它进行索引。例如:

>>> target_ix = pd.MultiIndex.from_product([df.station_id.unique(),
    np.arange(1910, 2011, 1), np.arange(1,13)], 
    names=["station_id", "year", "month"])
>>> df = df.set_index(["station_id", "year", "month"])
>>> new_df = df.loc[target_ix]
>>> new_df.tail(24)
                        1   2   3
station_id year month            
210018     2009 1       5   6   8
                2     NaN NaN   6
                3     NaN NaN NaN
                4     NaN NaN NaN
                5     NaN NaN NaN
                6     NaN NaN NaN
                7     NaN NaN NaN
                8     NaN NaN NaN
                9     NaN NaN NaN
                10    NaN NaN NaN
                11    NaN NaN NaN
                12      8   5   6
           2010 1     NaN NaN NaN
                2     NaN NaN NaN
                3     NaN NaN NaN
                4     NaN NaN NaN
                5     NaN NaN NaN
                6     NaN NaN NaN
                7     NaN NaN NaN
                8     NaN NaN NaN
                9     NaN NaN NaN
                10    NaN NaN NaN
                11    NaN NaN NaN
                12    NaN NaN NaN

如果您愿意,现在可以.reset_index()