我想使用fillna方法用另一列中的值填充一列中的缺失值。

(我读到循环遍历将是非常糟糕的做法,最好一次完成所有操作,但我无法找到如何使用fillna进行操作。)

之前的数据:

Day  Cat1  Cat2
1    cat   mouse
2    dog   elephant
3    cat   giraf
4    NaN   ant


之后的数据:

Day  Cat1  Cat2
1    cat   mouse
2    dog   elephant
3    cat   giraf
4    ant   ant


#1 楼

您可以将此列提供给fillna(请参阅文档),它将使用匹配索引上的那些值来填充:

In [17]: df['Cat1'].fillna(df['Cat2'])
Out[17]:
0    cat
1    dog
2    cat
3    ant
Name: Cat1, dtype: object


评论


真好!我不知道fillna需要一系列。

– Ami Tavory
15年5月20日在18:15

谢谢!我认为该系列必须是NA值数量的确切大小。

–xav
15年5月20日在21:04

它也适用于多列行的数据帧。 fillna的功能非常有帮助。

–Wertikal
19年5月30日在9:14

我必须说我喜欢这个!

– Taylrl
11月24日16:34



#2 楼

您可以

df.Cat1 = np.where(df.Cat1.isnull(), df.Cat2, df.Cat1)


RHS上的整体构造使用来自pandas食谱的三元模式(在任何情况下都需要阅读)。它是a? b: c的矢量版本。

评论


不是我用于此问题的解决方案,而是非常有趣的模式!谢谢!

–xav
15年5月20日在21:04

有没有一种方法可以用于多列?例如如果此df具有cat1,cat2,cat3,cat4,cat5,并且假设cat5为空。如果cat1为空然后cat2,如果cat2为空然后cat3,有没有办法用cat1的值填充cat5?

–user8322222
19年2月14日在12:36

@ user8322222我肯定来晚了,但是如果有人遇到这个问题,您可以嵌套np.where,就像在excel cell = np.where(cond,val_true,np.where(cond,val_true,val_false)中一样, )。

–凯撒
19年5月23日19:06



您想提到的是,这只是重新定义了内置在pd.DataFrame.fillna()中的熊猫。我怀疑极端情况下的行为可能会有所不同,例如用于来自不同数据帧的不匹配序列长度:dfA ['Cat1'],dfB ['Cat2']

–smci
19年7月8日在2:08

#3 楼

只需使用value参数而不是method即可:

In [20]: df
Out[20]:
  Cat1      Cat2  Day
0  cat     mouse    1
1  dog  elephant    2
2  cat     giraf    3
3  NaN       ant    4

In [21]: df.Cat1 = df.Cat1.fillna(value=df.Cat2)

In [22]: df
Out[22]:
  Cat1      Cat2  Day
0  cat     mouse    1
1  dog  elephant    2
2  cat     giraf    3
3  ant       ant    4


评论


感谢你的回答!使用价值而不是joris所描述的方法会发生什么变化?

–xav
15年5月20日在21:06

@xav值是第一个参数,因此joris实际上在做同样的事情。正如他所说,请参阅文档。

–chrisaycock
15年5月20日在22:02

是的,该文档字符串有点误导,因为该方法首先在此处列出。

– joris
2015年5月21日在6:27

#4 楼

pandas.DataFrame.combine_first也可以。

(注意:由于“结果索引列将是各个索引和列的并集”,因此应检查索引和列是否匹配。)

import numpy as np
import pandas as pd
df = pd.DataFrame([["1","cat","mouse"],
    ["2","dog","elephant"],
    ["3","cat","giraf"],
    ["4",np.nan,"ant"]],columns=["Day","Cat1","Cat2"])

In: df["Cat1"].combine_first(df["Cat2"])
Out: 
0    cat
1    dog
2    cat
3    ant
Name: Cat1, dtype: object


与其他答案进行比较:

%timeit df["Cat1"].combine_first(df["Cat2"])
181 µs ± 11.3 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

%timeit df['Cat1'].fillna(df['Cat2'])
253 µs ± 10.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit np.where(df.Cat1.isnull(), df.Cat2, df.Cat1)
88.1 µs ± 793 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)


我在下面没有使用此方法:

def is_missing(Cat1,Cat2):    
    if np.isnan(Cat1):        
        return Cat2
    else:
        return Cat1

df['Cat1'] = df.apply(lambda x: is_missing(x['Cat1'],x['Cat2']),axis=1)


因为会引发异常:

TypeError: ("ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''", 'occurred at index 0')


,这意味着np.isnan可以应用于本机dtype的NumPy数组(例如np.float64),
但是在应用于对象数组时会引发TypeError。

所以我修改了方法:

def is_missing(Cat1,Cat2):    
    if pd.isnull(Cat1):        
        return Cat2
    else:
        return Cat1

%timeit df.apply(lambda x: is_missing(x['Cat1'],x['Cat2']),axis=1)
701 µs ± 7.38 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)


#5 楼

这是一种更通用的方法(fillna方法可能更好)

def is_missing(Cat1,Cat2):    
    if np.isnan(Cat1):        
        return Cat2
    else:
        return Cat1

df['Cat1'] = df.apply(lambda x: is_missing(x['Cat1'],x['Cat2']),axis=1)


#6 楼

我知道这是一个老问题,但是最近我需要做类似的事情。我可以使用以下内容:

df = pd.DataFrame([["1","cat","mouse"],
    ["2","dog","elephant"],
    ["3","cat","giraf"],
    ["4",np.nan,"ant"]],columns=["Day","Cat1","Cat2"])

print(df)

  Day Cat1      Cat2
0   1  cat     mouse
1   2  dog  elephant
2   3  cat     giraf
3   4  NaN       ant

df1 = df.bfill(axis=1).iloc[:, 1]
df1 = df1.to_frame()
print(df1)


哪个产量:

  Cat1
0  cat
1  dog
2  cat
3  ant


希望这对有人!