用索引值

时间:2016-02-24 04:33:59

标签: python-2.7 pandas

我有DataFrame,其中包含nan个值。我想用索引值填充nan s。实际的用例是使用包含索引值的字符串模板填充nan s,您可以将其作为奖励回答。

假设:

In [31]: df
Out[31]:
          0         1         2         3
0       NaN  0.069419       NaN       NaN
1  2.439000  1.943944  0.279904  0.755746
2  0.013795  1.189474  0.834894  2.202108
3  0.520385       NaN       NaN  1.451822
4  0.153863  0.957394       NaN  0.052726
5  1.274204       NaN       NaN  0.169636
6       NaN  1.031703       NaN  0.267850
7  0.419157       NaN       NaN  0.409045
8       NaN  1.526764  0.947936  0.442226
9       NaN       NaN       NaN  0.458331

In [35]: tmp
Out[35]: 'i=%(idx)s'

输出应如下所示:

          0         1         2         3
0       i=0  0.069419       i=0       i=0
1  2.439000  1.943944  0.279904  0.755746
2  0.013795  1.189474  0.834894  2.202108
3  0.520385       i=3       i=3  1.451822
4  0.153863  0.957394       i=4  0.052726
5  1.274204       i=5       i=5  0.169636
6       i=6  1.031703       i=6  0.267850
7  0.419157       i=7       i=7  0.409045
8       i=8  1.526764  0.947936  0.442226
9       i=9       i=9       i=9  0.458331

只是尝试用索引填充nan

尝试

In [32]: df.fillna(df.index)

ValueError: invalid fill value with a <class 'pandas.core.index.Int64Index'>

尝试

In [33]: df.replace(np.nan, df.index)

TypeError: Invalid "to_replace" type: 'float'

尝试

In [41]: df.fillna(df.index.values)

ValueError: invalid fill value with a <type 'numpy.ndarray'>

尝试

In [53]: df1 = df.astype(object)

并重复上述内容,收到同样的错误。

使用pandas==0.17.1

3 个答案:

答案 0 :(得分:3)

与使用where的@maxymoo解决方案类似,但使用pd.Series代替lambda

s = pd.Series(['i={}'.format(i) for i in df.index])

In [49]: df.where(df.notnull(), s, axis=0)
Out[49]:
          0         1         2         3
0       i=0  0.069419       i=0       i=0
1     2.439   1.94394  0.279904  0.755746
2  0.013795   1.18947  0.834894   2.20211
3  0.520385       i=3       i=3   1.45182
4  0.153863  0.957394       i=4  0.052726
5    1.2742       i=5       i=5  0.169636
6       i=6    1.0317       i=6   0.26785
7  0.419157       i=7       i=7  0.409045
8       i=8   1.52676  0.947936  0.442226
9       i=9       i=9       i=9  0.458331

<强>时序

def f1():
    nan_strings = ["i={}".format(i) for i in df.index]
    df.apply(lambda c: c.where(c.notnull(), nan_strings))

def f2():
    s = pd.Series(['i={}s'.format(i) for i in df.index])
    df.where(df.notnull(), s, axis=0)

In [51]: %timeit f1()
100 loops, best of 3: 5.17 ms per loop

In [52]: %timeit f2()
1000 loops, best of 3: 1.34 ms per loop

答案 1 :(得分:2)

您可以使用where进行替换(它类似于使用反转掩码进行分配),但您需要逐列应用,我可以&# 39;不要想到如何一次完成所有工作:

In [1]: nan_strings = ["i={}".format(i) for i in df.index]

In [2]: df.apply(lambda c: c.where(c.notnull(), nan_strings))
Out[2]:
          0         1         2         3
0       i=0  0.069419       i=0       i=0
1     2.439   1.94394  0.279904  0.755746
2  0.013795   1.18947  0.834894   2.20211
3  0.520385       i=3       i=3   1.45182
4  0.153863  0.957394       i=4  0.052726
5    1.2742       i=5       i=5  0.169636
6       i=6    1.0317       i=6   0.26785
7  0.419157       i=7       i=7  0.409045
8       i=8   1.52676  0.947936  0.442226
9       i=9       i=9       i=9  0.458331

答案 2 :(得分:0)

好的,所以你正在做的事情会导致问题。首先,您的列似乎全是float64'i=%(idx)s'是一个字符串。因此,您必须将所有列转换为object,否则您必须填充nan的浮点值。那就是说,你为什么不尝试这个,如果你得到答案就告诉我:

df.fillna(df.index.values, inplace=True)

由于您说奖金,我们首先尝试将列转换为object类型:

fill_val = ['i={}'.format(i) for i in df.index.values]
df.astype('object', inplace=True)
df.fillna(fill_val, inplace=True)