web-dev-qa-db-ja.com

pandas DataFrameに欠損値がある行の数をカウントする最良の方法

私は現在、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'])

enter image description here

私が現在持っているのは

a)欠損値のあるセルのカウント:

>>> sum(df.isnull().values.ravel())
9

b)どこかに欠損値がある行のカウント:

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

2番目のカウントでは、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の場合、私の選択肢は少し高速です

更新

したがって、80,000行の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_nonzeroはこれを勝ち取った。

24
EdChum

numpy.count_nonzeroはどうですか:

 np.count_nonzero(df.isnull().values)   
 np.count_nonzero(df.isnull())           # also works  

count_nonzeroは非常に高速です。ただし、(1000,1000)配列からデータフレームを作成し、異なる位置に100ナンの値をランダムに挿入し、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

オリジナルのOPを大幅に改善するわけではありませんが、コードの混乱を減らすことができます。 2つのcount_nonzeroメソッド(.valuesの有無)の実行時間に実際には違いはありません。

10
Paul Joireman

行または列の欠損値をカウントする簡単なアプローチ

df.apply(lambda x: sum(x.isnull().values), axis = 0) # For columns
df.apply(lambda x: sum(x.isnull().values), axis = 1) # For rows

少なくとも1つの欠損値がある行の数:

sum(df.apply(lambda x: sum(x.isnull().values), axis = 1)>0)
8
Alvaro Fuentes

合計不足:

df.isnull().sum().sum()

欠落している行:

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

ここには多くの間違った答えがあります。 OPは、列ではなくNULL値を持つ行の数を要求しました。

より良い例を次に示します。

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)

`明らかに、NULL値を持つ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
2
ConanG

sum(df.count(axis=1) < len(df.columns))、非NULLが列より少ない行の数。

たとえば、次のデータフレームには、値が欠落している2つの行があります。

>>> 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
0
W.P. McNeill

結果を見てみたいだけなら、pandas func pandas.DataFrame.count があると思います。

このトピックに戻り、df.count(axis=1)を使用すると、uは次のような結果を取得します。

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

各行の非NaNパラメーターの数がわかります。一方、-(df.count(axis=1) - df.shape[1])

_a    0
b    3
c    0
d    3
e    0
f    0
g    3
h    0
dtype: int64
_
0
ruining.z