【问题标题】:Replace NaN values in all levels of a Pandas MultiIndex在 Pandas MultiIndex 的所有级别中替换 NaN 值
【发布时间】:2017-01-22 23:11:08
【问题描述】:

阅读带有 MultiIndex 的 excel 工作表后,我在索引中出现了 np.nan,因为其中一些值是“N/A”并且 pd.read_excel 认为转换它们是个好主意。但是我想将它们保留为“N/A”以保留多索引。我认为使用MultiIndex.fillna 将它们改回来很容易,但我收到了这个错误:

index = pd.MultiIndex(levels=[[u'foo', u'bar'], [u'one', np.nan]],
           codes=[[0, 0, 1, 1], [0, 1, 0, 1]],
           names=[u'first', u'second'])
df = pd.DataFrame(index=index, columns=['A', 'B'])
df

df.index.fillna("N/A")

输出:

---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
<ipython-input-17-09e14dcdc74f> in <module>
----> 1 df.index.fillna("N/A")

/anaconda3/envs/torch/lib/python3.7/site-packages/pandas/core/indexes/multi.py in fillna(self, value, downcast)
   1456         fillna is not implemented for MultiIndex
   1457         """
-> 1458         raise NotImplementedError("isna is not defined for MultiIndex")
   1459 
   1460     @Appender(_index_shared_docs["dropna"])

NotImplementedError: isna is not defined for MultiIndex

更新:

更新代码以反映 Pandas 1.0.2。在 0.24.0 版本之前,pd.MultiIndexcodes 属性称为 labels。此外,回溯详细信息从isnull is not defined 更改为isna is not defined,如上。

【问题讨论】:

  • 我猜这是一种解决方案:new_index = pd.MultiIndex(levels=[index.levels[0].fillna('N/A'), index.levels[1].fillna('N/A')], labels=index.labels, names=index.names) 但我的实际数据框是 6 级 MultiIndex,所以有点乱!
  • 我建议在没有任何索引提示的情况下加载数据帧,按摩 NA 的东西,然后 set_index。你有什么理由不能按那个顺序继续?
  • 感谢@Boud,这也可以。

标签: pandas dataframe nan multi-index


【解决方案1】:

接受的解决方案对我也不起作用。即使单独检查 df.index.levels 没有显示 NA 值,它仍然在索引中留下 NA 值。

Jorge 的solution 为我指明了正确的方向,但也不太适合我的情况。这是我的方法,包括处理单个 Index 案例,如已接受答案的 cmets 中所述。

if isinstance(df.index, pd.MultiIndex):
    df.index = pd.MultiIndex.from_frame(
        df.index.to_frame().fillna(my_fillna_value)
    )
else:
    df.index = df.index.fillna(my_fillna_value)

【讨论】:

  • 我今天测试了@piRSquared 先前接受的解决方案,实际上它似乎不起作用(请参阅我的评论)。这个和 Jorge 的作品,我决定接受这个,因为它解决了我最初的问题。谢谢。
【解决方案2】:

当前的解决方案在拥有多级列时对我不起作用。我所做的和为我工作的如下:

df.columns = pd.MultiIndex.from_frame(df.columns.to_frame().fillna(''))

【讨论】:

    【解决方案3】:

    使用set_levels

    df.index.set_levels([l.fillna('N/A') for l in df.index.levels], inplace=True)
    df
    

    【讨论】:

    • OP 有 6 个级别!更新答案以一次性修复所有级别?
    • @NehalJWani 更新帖子,完全概括。谢谢
    • :-o 不知道 set_levels 在其论点中支持 List!
    • @NehalJWani,为什么不呢?它只需要一个可迭代的。我猜 dict 也会起作用,键被转换为级别名称。不过没试过。
    • 我在使用这个时遇到一个错误:AttributeError Traceback (most recent call last) in () 1 #replace nans in index -- --> 2 df.index.set_levels([l.fillna('N/A') for l in df.index.levels], inplace=True) 3 4 df AttributeError: 'Index' object has no attribute 'set_levels'
    猜你喜欢
    • 2021-03-08
    • 2022-07-06
    • 2017-07-03
    • 1970-01-01
    • 2018-11-18
    • 2020-02-14
    • 2016-11-13
    • 2021-06-29
    • 2018-11-14
    相关资源
    最近更新 更多