【问题标题】:Find the single non-nan value in a multi-indexed dataframe在多索引数据框中查找单个非 nan 值
【发布时间】:2020-04-01 16:15:09
【问题描述】:

编辑:我注意到我过于简化了我的问题。这可能是因为我假设所提出的解决方案会以与我最初的蛮力解决方案类似的方式工作。我更改了多索引以更好地显示我的问题。对于已经付出努力的人,我深表歉意,非常感谢!

我有一个多索引的熊猫数据框。假设索引有三个级别,第二个级别包含颜色的名称。我知道在每一行中,索引中具有blue 颜色的所有列都包含NaN,除了一个,所以它看起来像这样:

import pandas as pd
import numpy as np

iterables = [['bar', 'baz', 'foo', 'qux'], ["red", "blue", "green"], ['one', 'two']]
mi = pd.MultiIndex.from_product(iterables)

df = pd.DataFrame(np.random.randn(5, 24), columns=mi)
df[("bar", "blue","one")] = [2     , np.nan, np.nan, 3     , np.nan]
df[("baz", "blue","two")] = [np.nan, 4.4   , np.nan, np.nan, 5     ]
df[("qux", "blue","one")] = [np.nan, np.nan, 1     , np.nan, np.nan]

输出:

        bar                                               ...       qux                                             
        red           blue               green            ...       red           blue               green          
        one       two  one       two       one       two  ...       one       two  one       two       one       two
0  0.046326 -0.999092  2.0  0.073113  0.958438  0.276653  ... -0.258202 -0.772636  NaN -0.639735  1.438262 -0.033578
1  0.257776 -2.499286  NaN  0.854263 -0.037380 -0.571258  ...  1.656198 -1.110911  NaN  0.757692  0.498118  1.070371
2 -0.314146  0.941367  NaN  0.265850 -0.153231 -1.092106  ... -0.208089 -0.363624  1.0  0.046457 -2.158373  0.572496
3 -1.198977  0.605490  3.0 -0.790985  0.000563 -0.958261  ...  1.339086 -1.057270  NaN -0.355639  1.050980 -1.727684
4 -0.562230 -1.721894  NaN  0.856543 -1.137364  1.185481  ...  0.986215  1.028128  NaN -0.264889  0.571484 -0.505340

现在我想创建一个新的数据框,其中包含该行在相应列中的非 nan 值,并命名该多索引的其他索引。

    word number blue
0   bar  one    2.0
1   baz  two    4.4
2   qux  one    1.0
3   bar  one    3.0
4   baz  two    5.0

即新数据帧的 wordnumber 条目应该是原始数据帧具有非 nan 值的索引,而新的 blue 列应该包含这些值。

我有一个蛮力解决方案,我基本上遍历每个条目,但我的最终数据框将包含大约 2000 列,这将需要很长时间才能运行。

【问题讨论】:

  • 我们是否应该假设'red','green'列无处不在?即除了一个“蓝色”列之外的每一列都是不适用的。
  • @smci,我添加了代码以生成具有属性的数据框。此外,我最初的示例具有误导性,其他列也可以包含浮点数。

标签: python pandas dataframe multi-index


【解决方案1】:

如果通过DataFrame.xs 选择,则仅通过DataFrame.stack 重塑,通过reset_indexdrop=True 删除第一个多索引级别,最后通过Series.rename_axis 和@987654324 将Series 转换为2DataFrame @:

df = (df.xs('blue', axis=1, level=1)
        .stack()
        .reset_index(level=0, drop=True)
        .rename_axis('number')
        .reset_index(name='blue'))
print (df)
   number  blue
0       1   2.0
1       2   4.4
2       3   1.0
3       1   3.0
4       2   5.0

编辑:解决方案类似,仅通过DataFrame.isnaDataFrame.anyDataFrame.loc 过滤至少一个NaNs 列,然后由DataFrame.stack 两个MultiIndex 级别使用:

df1 = (df.loc[:, df.isna().any()]
         .xs('blue', axis=1, level=1)
         .stack([0,1])
         .reset_index(level=0, drop=True)
         .rename_axis(('word','number'))
         .reset_index(name='blue'))

print (df1)
  word number  blue
0  bar    one   2.0
1  baz    two   4.4
2  qux    one   1.0
3  bar    one   3.0
4  baz    two   5.0

【讨论】:

  • 感谢您的回答!不幸的是,我注意到我无法在我的案例中重现该解决方案,因为我过于简化了原始案例,对此感到抱歉。我会改写我的问题。
【解决方案2】:

您可以堆叠一层,只保留blue 列,并删除 NaN 值:

resul = df.stack(level=0)['blue'].reset_index(level=1).rename(columns={'level_1': 'number'}).dropna()

它给出:

   number  blue
0       1   2.0
1       2   4.4
2       3   1.0
3       1   3.0
4       2   5.0

对于已编辑的问题,您似乎只想处理包含 NaN 值的列,并且只保留非 NaN 值。这可以解决问题:

df.loc[:,df.isna().any()].stack(level=[0,2])[['blue']].dropna()

它给出:

           blue
0 bar one   2.0
1 baz two   4.4
2 qux one   1.0
3 bar one   3.0
4 baz two   5.0

注意:如果您保留其他列,您将获得更多blue 值的结果...

【讨论】:

  • 感谢您的回答!不幸的是,我注意到我无法在我的案例中重现该解决方案,因为我过于简化了原始案例,对此感到抱歉。我会改写我的问题。
【解决方案3】:

你可以检查两个堆栈链

df.stack().stack().reset_index()
   level_0 level_1  level_2     0
0        0    blue        1   2.2
1        1    blue        2   5.0
2        2    blue        1  44.0
3        3    blue        3   3.3
4        4    blue        1   1.0
5        5    blue        3   1.0

【讨论】:

  • 顺便说一句,这假设“红色”、“绿色”列无处不在。
猜你喜欢
  • 2017-04-30
  • 1970-01-01
  • 2016-02-11
  • 2018-11-19
  • 2017-04-22
  • 2012-12-10
  • 2019-12-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多