【问题标题】:Pandas reindex and fill missing values: "Index must be monotonic"Pandas 重新索引并填充缺失值:“索引必须是单调的”
【发布时间】:2016-06-23 04:08:26
【问题描述】:

在回答this stackoverflow question 时,我发现在重新索引数据帧时使用填充方法时出现了一些有趣的行为。

pandas 中的 old bug report 表示 df.reindex(newIndex,method='ffill') 应该等同于 df.reindex(newIndex).ffill(),但这不是我所看到的行为

这是一个说明行为的代码 sn-p

df = pd.DataFrame({'values': 2}, index=pd.DatetimeIndex(['2016-06-02', '2016-05-04', '2016-06-03']))
newIndex = pd.DatetimeIndex(['2016-05-04', '2016-06-01', '2016-06-02', '2016-06-03', '2016-06-05'])
print(df.reindex(newIndex).ffill())
print(df.reindex(newIndex, method='ffill'))

第一个打印语句按预期工作。第二个提出了一个

ValueError: index must be monotonic increasing or decreasing

这是怎么回事?


编辑:请注意样本df 有意具有非单调索引。该问题与df.reindex(newIndex, method='ffil') 中的操作顺序有关。我的期望是错误报告说它应该工作 - 首先用新索引重新索引,然后填充。

如您所见,newIndex.is_monotonicTrue,单独调用时填充有效,但作为reindex 的参数调用时会失败。

【问题讨论】:

    标签: python pandas reindex


    【解决方案1】:

    reindex 的某些元素需要对传入索引进行排序。我推断当 method 被传递时,它无法对传入的索引进行预排序并随后失败。我是基于这样的事实得出这个结论的:

    print df.sort_index().reindex(newIndex.sort_values(), method='ffill')
    

    【讨论】:

    • 这确实是堆栈跟踪的问题:1940 indexer = self.get_indexer(target) 1941 nonexact = (indexer == -1) -> 1942 indexer[nonexact] = self._searchsorted_monotonic(target[nonexact], side) 1943 if side == 'left': 1944 # searchsorted returns "indices into a sorted array such that, 表明必须对索引进行排序才能使其正常工作,这是有道理的,因为如果索引不是,你不能ffill t 排序
    • @piRSquared 昨晚我写这个问题时已经很晚了。注意all(newIndex.sort_values()==newIndex)True。使它工作的 sn-p 部分是 df.sort_index()` 调用。我的示例df 故意具有非单调索引。我对reindex(newIndex, method='ffill') 的期望是如何首先重新索引然后填充,而不是相反。
    • @EdChum,我同意ffill 非单调索引没有意义。但我的newIndex 是单调的。我对df.reindex(newIndex, method='ffill') 的期望是首先用newIndex 重新索引,然后填充。但这显然不是正在发生的事情。
    【解决方案2】:

    这似乎也需要在列上完成。

    In[76]: frame = DataFrame(np.arange(9).reshape((3, 3)), index=['a', 'c', 'd'],columns=['Ohio', 'Texas', 'California'])
    
    In[77]: frame.reindex(index=['a','b','c','d'],method='ffill',columns=states)
    ---> ValueError: index must be monotonic increasing or decreasing
    
    In[78]: frame.reindex(index=['a','b','c','d'],method='ffill',columns=states.sort())
    
    Out[78]:
      Ohio  Texas  California
    a     0      1           2
    b     0      1           2
    c     3      4           5
    d     6      7           8
    

    【讨论】:

    • 这个问题是由于列没有排序造成的。因此,我认为这个答案更准确。
    猜你喜欢
    • 2017-12-22
    • 1970-01-01
    • 1970-01-01
    • 2018-01-12
    • 1970-01-01
    • 1970-01-01
    • 2019-06-05
    • 2013-07-17
    • 1970-01-01
    相关资源
    最近更新 更多