我有一个〜300K行和~40列的数据帧。 我想知道是否有任何行包含空值 - 并将这些'null'行放入一个单独的数据帧中,以便我可以轻松地探索它们。
我可以明确地创建一个掩码:
mask=False
for col in df.columns: mask = mask | df[col].isnull()
dfnulls = df[mask]
或者我可以这样做:
df.ix[df.index[(df.T == np.nan).sum() > 1]]
是否有一种更优雅的方法(找到包含空值的行)?
答案 0 :(得分:286)
[已更新以适应现代pandas
,其中isnull
作为DataFrame
的方法..]
您可以使用isnull
和any
构建一个布尔系列,并使用它来索引您的框架:
>>> df = pd.DataFrame([range(3), [0, np.NaN, 0], [0, 0, np.NaN], range(3), range(3)])
>>> df.isnull()
0 1 2
0 False False False
1 False True False
2 False False True
3 False False False
4 False False False
>>> df.isnull().any(axis=1)
0 False
1 True
2 True
3 False
4 False
dtype: bool
>>> df[df.isnull().any(axis=1)]
0 1 2
1 0 NaN 0
2 0 0 NaN
[对于年龄较大的pandas
:]
您可以使用函数isnull
代替方法:
In [56]: df = pd.DataFrame([range(3), [0, np.NaN, 0], [0, 0, np.NaN], range(3), range(3)])
In [57]: df
Out[57]:
0 1 2
0 0 1 2
1 0 NaN 0
2 0 0 NaN
3 0 1 2
4 0 1 2
In [58]: pd.isnull(df)
Out[58]:
0 1 2
0 False False False
1 False True False
2 False False True
3 False False False
4 False False False
In [59]: pd.isnull(df).any(axis=1)
Out[59]:
0 False
1 True
2 True
3 False
4 False
导致相当紧凑:
In [60]: df[pd.isnull(df).any(axis=1)]
Out[60]:
0 1 2
1 0 NaN 0
2 0 0 NaN
答案 1 :(得分:41)
nans = lambda df: df[df.isnull().any(axis=1)]
然后当你需要它时,你可以输入:
nans(your_dataframe)
答案 2 :(得分:2)
.any()
和.all()
非常适合极端情况,但当您要查找特定数量的null值时则不然。这是一种我认为您要问的非常简单的方法。它很冗长,但很实用。
import pandas as pd
import numpy as np
# Some test data frame
df = pd.DataFrame({'num_legs': [2, 4, np.nan, 0, np.nan],
'num_wings': [2, 0, np.nan, 0, 9],
'num_specimen_seen': [10, np.nan, 1, 8, np.nan]})
# Helper : Gets NaNs for some row
def row_nan_sums(df):
sums = []
for row in df.values:
sum = 0
for el in row:
if el != el: # np.nan is never equal to itself. This is "hacky", but complete.
sum+=1
sums.append(sum)
return sums
# Returns a list of indices for rows with k+ NaNs
def query_k_plus_sums(df, k):
sums = row_nan_sums(df)
indices = []
i = 0
for sum in sums:
if (sum >= k):
indices.append(i)
i += 1
return indices
# test
print(df)
print(query_k_plus_sums(df, 2))
输出
num_legs num_wings num_specimen_seen
0 2.0 2.0 10.0
1 4.0 0.0 NaN
2 NaN NaN 1.0
3 0.0 0.0 8.0
4 NaN 9.0 NaN
[2, 4]
然后,如果您像我一样,并且想清除这些行,则只需编写以下内容:
# drop the rows from the data frame
df.drop(query_k_plus_sums(df, 2),inplace=True)
# Reshuffle up data (if you don't do this, the indices won't reset)
df = df.sample(frac=1).reset_index(drop=True)
# print data frame
print(df)
输出:
num_legs num_wings num_specimen_seen
0 4.0 0.0 NaN
1 0.0 0.0 8.0
2 2.0 2.0 10.0
答案 3 :(得分:2)
如果要按一定数量的具有空值的列过滤行,则可以使用以下方法:
$linkPairs = explode(",", $atts); // separate the pairs
$output = '';
$output .= '<li class="slide">
<p><img src="' . esc_url($atts['image']) . '" alt="" /></p>
<p>'. $atts['headline'] .'</p>
<p>'. $atts['body'] .'</p>';
$li=count($linkPairs);//number of element of array
$i=1;//track the current location of array_pointer
foreach($linkPairs as $linkPair) {
if($i!=$li){
$symbol="|";//add | if the link is not the last link
}
else {
$symbol="";//add nothing if the link is the last link
}
$pair = explode("|", $linkPair); // separate the title and url
$output .= '<a href="' . $pair[1] . '" target="_blank">' . $pair[0] . '</a>'.$symbol;//$symbol is used to add | to the link
$i++;
}
$output .= '</li>';
所以,这是示例:
您的数据框:
df.iloc[df[(df.isnull().sum(axis=1) >= qty_of_nuls)].index]
如果要选择包含两列或多列具有空值的行,请运行以下命令:
>>> df = pd.DataFrame([range(4), [0, np.NaN, 0, np.NaN], [0, 0, np.NaN, 0], range(4), [np.NaN, 0, np.NaN, np.NaN]])
>>> df
0 1 2 3
0 0.0 1.0 2.0 3.0
1 0.0 NaN 0.0 NaN
2 0.0 0.0 NaN 0.0
3 0.0 1.0 2.0 3.0
4 NaN 0.0 NaN NaN
答案 4 :(得分:0)
少四个字符,但多两个毫秒
%%timeit
df.isna().T.any()
# 52.4 ms ± 352 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%%timeit
df.isna().any(axis=1)
# 50 ms ± 423 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
我可能会使用axis=1
答案 5 :(得分:-1)
df1 = df[df.isna().any(axis=1)]
参考链接:(Display rows with one or more NaN values in pandas dataframe)