Pandas fillna与列表/数组

时间:2013-07-09 09:26:13

标签: python pandas

是否有方便的方法用数组或列的(第一个)值填充na值?

想象一下以下DataFrame:

dfcolors = pd.DataFrame({'Colors': ['Blue', 'Red', np.nan, 'Green', np.nan, np.nan, 'Brown']})

  Colors
0   Blue
1    Red
2    NaN
3  Green
4    NaN
5    NaN
6  Brown

我想用另一个DataFrame或数组中的值填充NaN值,所以:

dfalt = pd.DataFrame({'Alt': ['Cyan', 'Pink']})

           Alt
0         Cyan
1         Pink

当有更多NaN然后填充值时,一些NaN应该保留。当有更多的填充值时,并不是所有的填充值都会被使用。所以我们必须做一些计算:

n_missing = len(dfcolors) - dfcolors.count().values[0]    
n_fill = min(n_missing, len(dfalt))

数字n_fill是可以填充的值的数量。

选择可以/应该填充的NaN值可以通过以下方式完成:

dfcolors.Colors[pd.isnull(dfcolors.Colors)][:n_fill]

2    NaN
4    NaN
Name: Colors, dtype: object

选择填充值

dfalt.Alt[:n_fill]

0    Cyan
1    Pink
Name: Alt, dtype: object

而他们我就陷入了类似的困境:

dfcolors.Colors[pd.isnull(dfcolors.Colors)][:n_fill] = dfalt.Alt[:n_fill]

哪个不起作用......任何提示都会很棒。

这是我想要的输出:

  Colors
0   Blue
1    Red
2   Cyan
3  Green
4   Pink
5    NaN
6  Brown

NaN值从上到下填充,如果填充值多于NaN,则填充值也从上到下选择

2 个答案:

答案 0 :(得分:3)

你可以使用发电机。这样你可以这样写:

import pandas as pd
from pandas import np

dfcolors = pd.DataFrame({'Colors': ['Blue', 'Red', np.nan, 'Green', np.nan, np.nan, 'Brown']})
dfalt = pd.DataFrame({'Alt': ['Cyan', 'Pink']})

gen_alt = (alt for alt in dfalt.Alt)

for i, color in enumerate(dfcolors.Colors):
    if not pd.isnull(color): continue
    try:
        dfcolors.Colors[i] = gen_alt.next()
    except StopIteration:
        break
print(dfcolors)
#     Colors
# 0   Blue
# 1    Red
# 2   Cyan
# 3  Green
# 4   Pink
# 5    NaN
# 6  Brown

答案 1 :(得分:2)

这非常糟糕,但迭代空值的索引有效:

In [11]: nulls = dfcolors[pd.isnull(dfcolors['Colors'])]

In [12]: for i, ni in enumerate(nulls.index[:len(dfalt)]):
             dfcolors['Colors'].loc[ni] = dfalt['Alt'].iloc[i]

In [13]: dfcolors
Out[13]:
  Colors
0   Blue
1    Red
2   Cyan
3  Green
4   Pink
5    NaN
6  Brown