在Python Pandas中,检查DataFrame是否有一个(或多个)NaN值的最佳方法是什么?
我知道函数pd.isnan,但它返回每个元素的布尔值的数据帧。这篇文章也没有完全回答我的问题。
pd.isnan
df.isnull().any().any()应该这样做。
df.isnull().any().any()
你有两个选择。
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(10,6)) # Make a few areas have NaN values df.iloc[1:3,1] = np.nan df.iloc[5,3] = np.nan df.iloc[7:9,5] = np.nan
现在数据帧看起来是这样的:
0 1 2 3 4 5 0 0.520113 0.884000 1.260966 -0.236597 0.312972 -0.196281 1 -0.837552 NaN 0.143017 0.862355 0.346550 0.842952 2 -0.452595 NaN -0.420790 0.456215 1.203459 0.527425 3 0.317503 -0.917042 1.780938 -1.584102 0.432745 0.389797 4 -0.722852 1.704820 -0.113821 -1.466458 0.083002 0.011722 5 -0.622851 -0.251935 -1.498837 NaN 1.098323 0.273814 6 0.329585 0.075312 -0.690209 -3.807924 0.489317 -0.841368 7 -1.123433 -1.187496 1.868894 -2.046456 -0.949718 NaN 8 1.133880 -0.110447 0.050385 -1.158387 0.188222 NaN 9 -0.513741 1.196259 0.704537 0.982395 -0.585040 -1.693810
你知道isnull()会返回一个这样的数据框架:
isnull()
0 1 2 3 4 5 0 False False False False False False 1 False True False False False False 2 False True False False False False 3 False False False False False False 4 False False False False False False 5 False False False True False False 6 False False False False False False 7 False False False False False True 8 False False False False False True 9 False False False False False False
如果你把它设置为df.isnull().any(),你可以找到只有NaN值的列:
df.isnull().any()
NaN
0 False 1 True 2 False 3 True 4 False 5 True dtype: bool
多一个.any()会告诉你上面是否有True
.any()
True
> df.isnull().any().any() True
df.isnull().sum().sum()
它的操作方式与.any().any()相同,首先给出一列中NaN的值的总和,然后是这些值的总和:
.any().any()
df.isnull().sum() 0 0 1 2 2 0 3 1 4 0 5 2 dtype: int64
最后,要获得DataFrame中NaN值的总数:
df.isnull().sum().sum() 5
jwilner的回应是正确的。我正在探索是否有更快的选择,因为根据我的经验,平坦数组的和(奇怪地)比计数快。这段代码似乎更快:
df.isnull().values.any()
import numpy as np import pandas as pd import perfplot def setup(n): df = pd.DataFrame(np.random.randn(n)) df[df > 0.9] = np.nan return df def isnull_any(df): return df.isnull().any() def isnull_values_sum(df): return df.isnull().values.sum() > 0 def isnull_sum(df): return df.isnull().sum() > 0 def isnull_values_any(df): return df.isnull().values.any() perfplot.save( "out.png", setup=setup, kernels=[isnull_any, isnull_values_sum, isnull_sum, isnull_values_any], n_range=[2 ** k for k in range(25)], )
df.isnull().sum().sum()有点慢,但当然,它有额外的信息——NaNs的编号。
NaNs
根据您正在处理的数据类型,您还可以在执行EDA时通过将dropna设置为False来获得每列的值计数。
for col in df: print df[col].value_counts(dropna=False)
适用于分类变量,但当你有很多唯一值时就不那么适用了。
如果你需要知道有多少行"一个或多个# eyz0 "
df.isnull().T.any().T.sum()
或者如果你需要取出这些行并检查它们:
nan_rows = df[df.isnull().T.any()]
由于pandas必须为DataFrame.dropna()找到这一点,我看了看他们是如何实现的,并发现他们使用了DataFrame.count(),它计算了DataFrame中的所有非空值。# EYZ4 Cf。我还没有对这种技术进行基准测试,但我认为库的作者可能已经就如何实现它做出了明智的选择。
pandas
DataFrame.dropna()
DataFrame.count()
DataFrame
因为没有人提到,这里只有另一个名为hasnans的变量。
hasnans
如果pandas系列中的一个或多个值为NaN,则df[i].hasnans将输出到True,否则输出到False。注意,它不是一个函数。
df[i].hasnans
False
熊猫版本“0.19.2”和“0.20.2”
加上霍布斯的精彩回答,我对Python和熊猫很陌生,所以如果我错了,请指出来。
要找出哪些行有nan:
nan_rows = df[df.isnull().any(1)]
将执行相同的操作,而不需要通过将any()的轴指定为1来检查'True'是否在行中存在。
要找出特定列中哪些行有nan:
nan_rows = df[df['name column'].isnull()]
或者你可以在DF上使用.info(),例如:
DF
.info()
df.info(null_counts=True)返回列中的非空行数,例如:
df.info(null_counts=True)
<class 'pandas.core.frame.DataFrame'> Int64Index: 3276314 entries, 0 to 3276313 Data columns (total 10 columns): n_matches 3276314 non-null int64 avg_pic_distance 3276314 non-null float64
下面是另一种有趣的查找null并替换为计算值的方法
#Creating the DataFrame testdf = pd.DataFrame({'Tenure':[1,2,3,4,5],'Monthly':[10,20,30,40,50],'Yearly':[10,40,np.nan,np.nan,250]}) >>> testdf2 Monthly Tenure Yearly 0 10 1 10.0 1 20 2 40.0 2 30 3 NaN 3 40 4 NaN 4 50 5 250.0 #Identifying the rows with empty columns nan_rows = testdf2[testdf2['Yearly'].isnull()] >>> nan_rows Monthly Tenure Yearly 2 30 3 NaN 3 40 4 NaN #Getting the rows# into a list >>> index = list(nan_rows.index) >>> index [2, 3] # Replacing null values with calculated value >>> for i in index: testdf2['Yearly'][i] = testdf2['Monthly'][i] * testdf2['Tenure'][i] >>> testdf2 Monthly Tenure Yearly 0 10 1 10.0 1 20 2 40.0 2 30 3 90.0 3 40 4 160.0 4 50 5 250.0
df.isna().any(axis=None)
从v0.23.2开始,你可以使用DataFrame.isna + DataFrame.any(axis=None),其中axis=None指定整个数据帧的逻辑缩减。
DataFrame.isna
DataFrame.any(axis=None)
axis=None
# Setup df = pd.DataFrame({'A': [1, 2, np.nan], 'B' : [np.nan, 4, 5]}) df A B 0 1.0 NaN 1 2.0 4.0 2 NaN 5.0
df.isna() A B 0 False True 1 False False 2 True False df.isna().any(axis=None) # True
np.isnan(df.values) array([[False, True], [False, False], [ True, False]]) np.isnan(df.values).any() # True
或者,检查和:
np.isnan(df.values).sum() # 2 np.isnan(df.values).sum() > 0 # True
Series.hasnans
df['A'].hasnans # True
要检查任何列是否有nan,可以使用对any的理解(这是一个短路操作)。
any
any(df[c].hasnans for c in df) # True
这实际上是非常快速。
df.apply(axis=0, func=lambda x : any(pd.isnull(x)))
将检查每一列是否包含Nan。
我一直在使用以下和类型转换为字符串,并检查nan值
(str(df.at[index, 'column']) == 'nan')
这允许我检查一个系列中的特定值,而不只是返回如果它包含在系列中的某个地方。
最好的方法是:
df.isna().any().any()
这是为什么。因此,isna()被用来定义isnull(),但这两者当然是相同的。
isna()
这甚至比公认的答案还要快,并且涵盖了所有2D熊猫数组。
df.isnull().sum()
这将为您提供DataFrame各列中所有NaN值的计数。
让df作为Pandas数据帧的名称,任何numpy.nan的值都是空值。
df
numpy.nan
如果你想看看哪些列有空,哪些没有(只有True和False)
如果你想只看到有空值的列
df.loc[:, df.isnull().any()].columns
如果你想查看每一列中null的计数
df.isna().sum()
如果你想看到每列中null的百分比
df.isna().sum()/(len(df))*100
如果你想查看只有空值的列中空值的百分比:
df.loc[:,list(df.loc[:,df.isnull().any()].columns)].isnull().sum()/(len(df))*100
编辑1:
如果你想从视觉上看到数据缺失的地方:
import missingno missingdata_df = df.columns[df.isnull().any()].tolist() missingno.matrix(df[missingdata_df])
import missingno as msno msno.matrix(df) # just to visualize. no missing value.
你不仅可以检查是否有'NaN'存在,还可以使用下面的方法得到'NaN'在每一列中的百分比,
df = pd.DataFrame({'col1':[1,2,3,4,5],'col2':[6,np.nan,8,9,10]}) df col1 col2 0 1 6.0 1 2 NaN 2 3 8.0 3 4 9.0 4 5 10.0 df.isnull().sum()/len(df) col1 0.0 col2 0.2 dtype: float64
通过使用seaborn模块的热图生成热图,我们可以看到数据集中存在的空值
import pandas as pd import seaborn as sns dataset=pd.read_csv('train.csv') sns.heatmap(dataset.isnull(),cbar=False)
为此,我们可以使用语句df.isna().any()。这将检查我们的所有列,如果有任何缺失值则返回True,如果没有缺失值则返回NaNs,或者返回False。
df.isna().any()
试试下面的方法
或
df.isna().values.any()
另一种方法是dropna,检查长度是否相等:
dropna
>>> len(df.dropna()) != len(df) True >>>
我建议使用值属性作为数组的计算是更快的。
arr = np.random.randn(100, 100) arr[40, 40] = np.nan df = pd.DataFrame(arr) %timeit np.isnan(df.values).any() # 7.56 µs %timeit np.isnan(df).any() # 627 µs %timeit df.isna().any(axis=None) # 572 µs
结果:
7.56 µs ± 447 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) 627 µs ± 40.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 572 µs ± 15.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
注意:你需要在Jupyter笔记本上运行%timeit才能工作
%timeit
缺失值的Bar表示
import missingno missingno.bar(df)# will give you exact no of values and values missing
这将只包括至少有一个null/na值的列。
df.isnull().sum()[df.isnull().sum()>0]