Python 计算数据帧中缺少值的行数的最佳方法

Python 计算数据帧中缺少值的行数的最佳方法,python,pandas,missing-data,Python,Pandas,Missing Data,目前,我想出了一些解决方法来计算pandasDataFrame中缺失值的数量。这些都很难看,我想知道是否有更好的方法来做到这一点 让我们创建一个示例DataFrame: from numpy.random import randn df = pd.DataFrame(randn(5, 3), index=['a', 'c', 'e', 'f', 'h'], columns=['one', 'two', 'three']) df = df.reindex(['a',

目前,我想出了一些解决方法来计算pandas
DataFrame
中缺失值的数量。这些都很难看,我想知道是否有更好的方法来做到这一点

让我们创建一个示例
DataFrame

from numpy.random import randn
df = pd.DataFrame(randn(5, 3), index=['a', 'c', 'e', 'f', 'h'],
               columns=['one', 'two', 'three'])
df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])

我现在拥有的是

a) 对缺少值的单元格进行计数:

>>> sum(df.isnull().values.ravel())
9
b) 计算某处缺少值的行:

>>> sum([True for idx,row in df.iterrows() if any(row.isnull())])
3

对于第二个计数,我想只需从从
dropna
返回的行数中减去行数:

In [14]:

from numpy.random import randn
df = pd.DataFrame(randn(5, 3), index=['a', 'c', 'e', 'f', 'h'],
               columns=['one', 'two', 'three'])
df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])
df
Out[14]:
        one       two     three
a -0.209453 -0.881878  3.146375
b       NaN       NaN       NaN
c  0.049383 -0.698410 -0.482013
d       NaN       NaN       NaN
e -0.140198 -1.285411  0.547451
f -0.219877  0.022055 -2.116037
g       NaN       NaN       NaN
h -0.224695 -0.025628 -0.703680
In [18]:

df.shape[0] - df.dropna().shape[0]
Out[18]:
3
第一种方法可以使用内置方法实现:

In [30]:

df.isnull().values.ravel().sum()
Out[30]:
9
计时

In [34]:

%timeit sum([True for idx,row in df.iterrows() if any(row.isnull())])
%timeit df.shape[0] - df.dropna().shape[0]
%timeit sum(map(any, df.apply(pd.isnull)))
1000 loops, best of 3: 1.55 ms per loop
1000 loops, best of 3: 1.11 ms per loop
1000 loops, best of 3: 1.82 ms per loop
In [33]:

%timeit sum(df.isnull().values.ravel())
%timeit df.isnull().values.ravel().sum()
%timeit df.isnull().sum().sum()
1000 loops, best of 3: 215 µs per loop
1000 loops, best of 3: 210 µs per loop
1000 loops, best of 3: 605 µs per loop
因此,对于这种尺寸的df,我的备选方案要快一点

更新

因此,对于80000行的df,我得到以下结果:

In [39]:

%timeit sum([True for idx,row in df.iterrows() if any(row.isnull())])
%timeit df.shape[0] - df.dropna().shape[0]
%timeit sum(map(any, df.apply(pd.isnull)))
%timeit np.count_nonzero(df.isnull())
1 loops, best of 3: 9.33 s per loop
100 loops, best of 3: 6.61 ms per loop
100 loops, best of 3: 3.84 ms per loop
1000 loops, best of 3: 395 µs per loop
In [40]:

%timeit sum(df.isnull().values.ravel())
%timeit df.isnull().values.ravel().sum()
%timeit df.isnull().sum().sum()
%timeit np.count_nonzero(df.isnull().values.ravel())
1000 loops, best of 3: 675 µs per loop
1000 loops, best of 3: 679 µs per loop
100 loops, best of 3: 6.56 ms per loop
1000 loops, best of 3: 368 µs per loop
实际上,
np.count\u non-zero
轻而易举地赢得了这场比赛。

Total missing:

df.isnull().sum().sum()
缺少以下内容的行:

sum(map(any, df.isnull()))

那么
numpy.count\u非零呢

 np.count_nonzero(df.isnull().values)   
 np.count_nonzero(df.isnull())           # also works  
count\u non-zero
非常快。然而,我从一个(10001000)数组构建了一个数据帧,在不同的位置随机插入100个nan值,并测量了iPython中各种答案的时间:

%timeit np.count_nonzero(df.isnull().values)
1000 loops, best of 3: 1.89 ms per loop

%timeit df.isnull().values.ravel().sum()
100 loops, best of 3: 3.15 ms per loop

%timeit df.isnull().sum().sum()
100 loops, best of 3: 15.7 ms per loop
与最初的OPs相比,这并不是一个巨大的时间改进,但在代码中,您的决定可能不那么混乱。在执行时间上实际上没有任何差别
在两种
count\u非零
方法(带和不带
.values
)之间。

一种计算行或列中缺失值的简单方法

df.apply(lambda x: sum(x.isnull().values), axis = 0) # For columns
df.apply(lambda x: sum(x.isnull().values), axis = 1) # For rows
至少缺少一个值的行数:

sum(df.apply(lambda x: sum(x.isnull().values), axis = 1)>0)
sum(df.count(axis=1)
,非空值少于列的行数

例如,以下数据框有两行缺少值

>>> df = pd.DataFrame({"a":[1, None, 3], "b":[4, 5, None]})
>>> df
    a   b
0   1   4
1 NaN   5
2   3 NaN
>>> df.count(axis=1)
0    2
1    1
2    1
dtype: int64
>>> df.count(axis=1) < len(df.columns)
0    False
1     True
2     True
dtype: bool
>>> sum(df.count(axis=1) < len(df.columns))
2
数据帧({“a”:[1,无,3],“b”:[4,5,无]}) >>>df a b 0 1 4 1至5 2 3南 >>>测向计数(轴=1) 0 2 1 1 2 1 数据类型:int64 >>>测向计数(轴=1)>>总和(测向计数(轴=1)
这里有这么多错误的答案。OP询问具有空值的行数,而不是列数

下面是一个更好的例子:

from numpy.random import randn
df = pd.DataFrame(randn(5, 3), index=['a', 'c', 'e', 'f', 'h'],columns=['one','two', 'three'])
df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h','asdf'])
print(df)
`现在显然有4行具有空值

           one       two     three
a    -0.571617  0.952227  0.030825
b          NaN       NaN       NaN
c     0.627611 -0.462141  1.047515
d          NaN       NaN       NaN
e     0.043763  1.351700  1.480442
f     0.630803  0.931862  1.500602
g          NaN       NaN       NaN
h     0.729103 -1.198237 -0.207602
asdf       NaN       NaN       NaN
如果您使用了这里的一些答案,您将得到答案为3(带NaN的列数)。富恩特斯的答案是有效的

我是这样得到的:

df.isnull().any(axis=1).sum()
#4
timeit df.isnull().any(axis=1).sum()
#10000 loops, best of 3: 193 µs per loop
“富恩特斯”:

sum(df.apply(lambda x: sum(x.isnull().values), axis = 1)>0)
#4
timeit sum(df.apply(lambda x: sum(x.isnull().values), axis = 1)>0)
#1000 loops, best of 3: 677 µs per loop

我想如果你只是想看看结果,有一个熊猫函数

回到本主题,使用df.count(axis=1),u将得到如下结果:

a    3
b    0
c    3
d    0
e    3
f    3
g    0
h    3
dtype: int64
它将告诉您每行中有多少个非NaN参数。同时,,
-(测向计数(轴=1)-df.shape[1])
表示

a    0
b    3
c    0
d    3
e    0
f    0
g    3
h    0
dtype: int64

为方便起见,文档链接: