如何按“pandas”中的列获取缺失/NaN数据的汇总计数?

eqoofvh9  于 2022-11-27  发布在  其他
关注(0)|答案(8)|浏览(130)

在 * R * 中,我可以使用summary命令快速查看丢失数据的计数,但等效的pandas DataFrame方法describe不报告这些值。
我想我可以做一些

len(mydata.index) - mydata.count()

来计算每一列缺少的值的数量,但我想知道是否有更好的习惯用法(或者我的方法是否正确)。

luaexgnf

luaexgnf1#

describeinfo均报告非缺失值的计数。

In [1]: df = DataFrame(np.random.randn(10,2))

In [2]: df.iloc[3:6,0] = np.nan

In [3]: df
Out[3]: 
          0         1
0 -0.560342  1.862640
1 -1.237742  0.596384
2  0.603539 -1.561594
3       NaN  3.018954
4       NaN -0.046759
5       NaN  0.480158
6  0.113200 -0.911159
7  0.990895  0.612990
8  0.668534 -0.701769
9 -0.607247 -0.489427

[10 rows x 2 columns]

In [4]: df.describe()
Out[4]: 
              0          1
count  7.000000  10.000000
mean  -0.004166   0.286042
std    0.818586   1.363422
min   -1.237742  -1.561594
25%   -0.583795  -0.648684
50%    0.113200   0.216699
75%    0.636036   0.608839
max    0.990895   3.018954

[8 rows x 2 columns]

In [5]: df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 10 entries, 0 to 9
Data columns (total 2 columns):
0    7 non-null float64
1    10 non-null float64
dtypes: float64(2)

要计算丢失的数量,您的解决方案是正确的

In [20]: len(df.index)-df.count()
Out[20]: 
0    3
1    0
dtype: int64

你也可以这么做

In [23]: df.isnull().sum()
Out[23]: 
0    3
1    0
dtype: int64
epfja78i

epfja78i2#

作为一个微小的补充,为了获得DataFrame列缺少的百分比,结合上面的@Jeff和@userS的答案可以得到:

100*(df.isnull().sum())/len(df)
kxe2p93d

kxe2p93d3#

下面的代码就能达到这个目的,它将返回每列的空值计数:
df.isnull().sum(axis=0)
df.isnull()返回具有True / False值的 Dataframe
sum(axis=0)对某列的所有行的值求和

nlejzf6q

nlejzf6q4#

这不是一个完整的摘要,但它可以给予您快速了解列级数据

def getPctMissing(series):
    num = series.isnull().sum()
    den = series.count()
    return 100*(num/den)
gywdnpxw

gywdnpxw5#

如果要查看每列的非空汇总,只需使用df.info(null_counts=True)
例一:

df = pd.DataFrame(np.random.randn(10,5), columns=list('abcde'))
df.iloc[:4,0] = np.nan
df.iloc[:3,1] = np.nan
df.iloc[:2,2] = np.nan
df.iloc[:1,3] = np.nan

df.info(null_counts=True)

输出:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 10 entries, 0 to 9
Data columns (total 5 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   a       6 non-null      float64
 1   b       7 non-null      float64
 2   c       8 non-null      float64
 3   d       9 non-null      float64
 4   e       10 non-null     float64
dtypes: float64(5)
memory usage: 528.0 bytes

另外,如果您想定制结果,比如添加nan_rate,我写了一个方法

def describe_nan(df):
    return pd.DataFrame([(i, df[df[i].isna()].shape[0],df[df[i].isna()].shape[0]/df.shape[0]) for i in df.columns], columns=['column', 'nan_counts', 'nan_rate'])

describe_nan(df)

>>> column  nan_counts  nan_rate
0   a   4   0.4
1   b   3   0.3
2   c   2   0.2
3   d   1   0.1
4   e   0   0.0
camsedfj

camsedfj6#

如果您不关心哪些列包含Nan的值,而只想检查整个列,只需添加第二个.sum()来获取单个值。

result = df.isnull().sum().sum()
result > 0

一个Series只需要一个。sum()和Panel()需要三个

bz4sfanl

bz4sfanl7#

我不得不处理大量的大型数据集来获取NaN信息(每列的计数和份额),而时间是一个问题。因此,我对各种方法进行了计时,以在单独的 Dataframe 中获取每列NaN的汇总计数,并将列名、NaN计数和NaN份额作为列:

# create random dataframe
dfa = pd.DataFrame(np.random.randn(100000,300))
# add 30% random NaNs
dfa = dfa.mask(np.random.random(dfa.shape) < 0.3)

Pandas的方法只

%%timeit
nans_dfa = dfa.isna().sum().rename_axis('Columns').reset_index(name='Counts')
nans_dfa["NaNportions"] = nans_dfa["Counts"] / dfa.shape[0]

# Output:
# 10 loops, best of 5: 57.8 ms per loop

使用列表理解,基于来自@Mithril的精细answer

%%timeit
nan_dfa_loop2 = pd.DataFrame([(col, dfa[dfa[col].isna()].shape[0], dfa[dfa[col].isna()].shape[0]/dfa.shape[0]) for col in dfa.columns], columns=('Columns', 'Counts', 'NaNportions'))

# Output:
# 1 loop, best of 5: 13.9 s per loop

使用列表解析和第二个for循环来存储方法调用的结果,以减少对这些方法的调用:

%%timeit
nan_dfa_loop1 = pd.DataFrame([(col, n, n/dfa.shape[0]) for col in dfa.columns for n in (dfa[col].isna().sum(),) if n], columns=('Columns', 'Counts', 'NaNportions'))

# Output:
# 1 loop, best of 5: 373 ms per loop

以上所有操作将生成相同的 Dataframe :

Columns Counts  NaNportions
0   0   29902   0.29902
1   1   30101   0.30101
2   2   30008   0.30008
3   3   30194   0.30194
4   4   29856   0.29856
... ... ... ...
295 295 29823   0.29823
296 296 29818   0.29818
297 297 29979   0.29979
298 298 30050   0.30050
299 299 30192   0.30192

('Columns'对于此测试 Dataframe 是多余的。它只是用作占位符,在真实的数据集中,它可能表示初始 Dataframe 中的属性名称。)

vyu0f0g1

vyu0f0g18#

我推荐使用missingno包(https://github.com/ResidentMario/missingno),它可以让你快速轻松地可视化Pandas Dataframe 中缺失的数据。

import missingno as msno
import pandas as pd

df = pd.read_csv('some_data.csv')

msno.bar(df.sample(1000))

相关问题