명시 적으로 열을 나열하지 않고 팬더 DataFrame에서 하나 이상의 null이있는 행을 선택하는 방법은 무엇입니까?


233

~ 300K 행과 ~ 40 열의 데이터 프레임이 있습니다. 행에 null 값이 포함되어 있는지 확인 하고이 '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]]

더 우아한 방법이 있습니까 (널이 null 인 행 찾기)?

답변:


384

[현대에 적응하기 위해 업데이트 pandas가있는 isnull방법으로DataFrame S ..]

당신은 사용할 수 있습니다 isnullany귀하의 프레임에 인덱스 부울 시리즈 및 사용을 구축 :

>>> 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

75
def nans(df): return df[df.isnull().any(axis=1)]

그런 다음 필요할 때마다 다음을 입력 할 수 있습니다.

nans(your_dataframe)

1
df[df.isnull().any(axis=1)]작동하지만 던졌습니다 UserWarning: Boolean Series key will be reindexed to match DataFrame index.. 이 경고 메시지를 트리거하지 않는 방식으로 더 명확하게 다시 작성하는 방법은 무엇입니까?
Vishal

3
@vishal 나는 당신이해야 할 일은 다음과 같이 loc을 추가하는 것이라고 생각한다. df.loc[df.isnull().any(axis=1)]
제임스 드레이퍼

2
제쳐두고- 익명 (람다) 기능의 이름을 지정해서는 안됩니다 . 람다 식을 식별자에 직접 바인딩하는 할당 문 대신 항상 def 문을 사용하십시오.
donrondadon

0

.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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.