在Pandas DataFrame中有条件地填充非NaN列的值中的NaN值

时间:2016-07-28 03:40:47

标签: python pandas

我有一个问题,即有条件地在Pandas didSelectIndex中填写UITableViewDelegate值 非NaN列的值。举例说明:

DataFrame

现在假设我有一些默认值,这取决于前三列:

NaN

换句话说,我想在import numpy as np import pandas as pd print pd.__version__ 0.18.1 df = pd.DataFrame({'a': [1, 0, 0, 0, 1], 'b': [0, 1, 0, 0, 0], 'c': [0, 0, 1, 1, 0], 'x': [0.5, 0.2, 0, 0.2, 0], 'y': [0, 0, 0, 1, 0], 'z': [0.1, 0.1, 0.9, 0, 0.4]}) df.ix[[2,4], ['x','y','z']] = np.nan print df a b c x y z 0 1 0 0 0.5 0.0 0.1 1 0 1 0 0.2 0.0 0.1 2 0 0 1 NaN NaN NaN 3 0 0 1 0.2 1.0 0.0 4 1 0 0 NaN NaN NaN 中粘贴第2行中的default_c = pd.Series([0.5, 0.5, 0.5], index=['x', 'y', 'z']) default_a = pd.Series([0.2, 0.2, 0.2], index=['x', 'y', 'z']) 值,然后在第4行粘贴default_c。为此,我想出了以下有点不优雅的解决方案:

NaN

使用default_a功能有更好的方法吗?

例如,以下不起作用,我猜是因为我正在填充nan_x = np.isnan(df['x']) is_c = df['c']==1 nan_c = nan_x & is_c print nan_c 0 False 1 False 2 True 3 False 4 False dtype: bool df.ix[nan_c, default_c.index] = default_c.values print df a b c x y z 0 1 0 0 0.5 0.0 0.1 1 0 1 0 0.2 0.0 0.1 2 0 0 1 0.5 0.5 0.5 3 0 0 1 0.2 1.0 0.0 4 1 0 0 NaN NaN NaN 的一部分:

fillna()

但这条长线确实如此:

DataFrame

无论如何,只是寻找有关如何使这段代码尽可能简单的建议。

1 个答案:

答案 0 :(得分:1)

您可以将a, b, c列设置为多索引并使用pandas combine_first

首先,您需要一个默认框架。在您的设置中,它可以是:

df0 = pd.concat([default_a, default_c], axis=1).T
df0.index = pd.Index([(1, 0, 0), (0, 0, 1)], names=list("abc"))
df0
Out[148]: 
         x    y    z
a b c               
1 0 0  0.2  0.2  0.2
0 0 1  0.5  0.5  0.5

然后将多索引设置为df1,应用combine_first并重置索引:

df1 = df.set_index(['a', 'b', 'c'])
>>> df1
Out[151]: 
         x    y    z
a b c               
1 0 0  0.5  0.0  0.1
0 1 0  0.2  0.0  0.1
  0 1  NaN  NaN  NaN
    1  0.2  1.0  0.0
1 0 0  NaN  NaN  NaN

df1.combine_first(df0)
Out[152]: 
         x    y    z
a b c               
0 0 1  0.5  0.5  0.5
    1  0.2  1.0  0.0
  1 0  0.2  0.0  0.1
1 0 0  0.5  0.0  0.1
    0  0.2  0.2  0.2

df1.combine_first(df0).reset_index()
Out[154]: 
   a  b  c    x    y    z
0  0  0  1  0.5  0.5  0.5
1  0  0  1  0.2  1.0  0.0
2  0  1  0  0.2  0.0  0.1
3  1  0  0  0.5  0.0  0.1
4  1  0  0  0.2  0.2  0.2

副作用是输出的不同排序顺序。为了保持顺序,我们可以使用原始索引(如果它是单调且唯一的,否则使用额外的临时列):

df2 = df.reset_index().set_index(['a', 'b', 'c'])
>>> df2
Out[156]: 
       index    x    y    z
a b c                      
1 0 0      0  0.5  0.0  0.1
0 1 0      1  0.2  0.0  0.1
  0 1      2  NaN  NaN  NaN
    1      3  0.2  1.0  0.0
1 0 0      4  NaN  NaN  NaN

df2.combine_first(df0).reset_index().set_index('index').sort_index()
Out[160]: 
       a  b  c    x    y    z
index                        
0      1  0  0  0.5  0.0  0.1
1      0  1  0  0.2  0.0  0.1
2      0  0  1  0.5  0.5  0.5
3      0  0  1  0.2  1.0  0.0
4      1  0  0  0.2  0.2  0.2