Pandas 데이터 프레임에서 모두 0이있는 행 삭제


103

pandas dropna()기능을 사용 하여 일부 또는 모든 열이 NA's'로 설정된 행을 제거 할 수 있습니다 . 값이 0 인 모든 열이있는 행을 삭제하는 것과 동일한 기능이 있습니까?

P   kt  b   tt  mky depth
1   0   0   0   0   0
2   0   0   0   0   0
3   0   0   0   0   0
4   0   0   0   0   0
5   1.1 3   4.5 2.3 9.0

이 예에서는 데이터 프레임에서 처음 4 개 행을 삭제하려고합니다.

감사!


명확히하기 위해 이것은 두 가지 질문입니다. 하나와 열을 드롭 하는 모든 기능에 대해, 또한 값이 0으로하지만 등가 로 열을 드롭 할 dropna ()의 모든 0 값으로
연금술

답변:


111

이것은 벡터화 된 방식으로 멋지게 표현 될 수 있습니다.

> df = pd.DataFrame({'a':[0,0,1,1], 'b':[0,1,0,1]})
> df = df[(df.T != 0).any()]
> df
   a  b
1  0  1
2  1  0
3  1  1

6
니스,하지만 난 당신이 부정을 방지 할 수 있다고 생각df = df[(df.T != 0).any()]
Akavall

1
@Akavall 훨씬 좋습니다!
U2EF1 2014 년

1
참고 : OP는 드롭을 원했지만 방법 rows with all columns having value 0을 추론 할 수 있습니다 all.
paulochf

1
이 모든 답변은 모두 0으로 행을 삭제하는 방법을 설명하지만 첫 번째 열에 0이있는 행을 삭제하고 싶었습니다. 이 게시물의 모든 토론과 답변의 도움으로 df.loc [df.iloc [:, 0]! = 0]을 수행하여이를 수행했습니다. 이 문제는이 질문과 관련이 있기 때문에 공유하고 싶었습니다 !!
hemanta

2
전치가 필요하지 않으며 any ()는 축을 매개 변수로 사용할 수 있습니다. 이 작동 : 그래서 DF DF = [df.any (축선 = 1)]
라울 제이 자

129

짧막 한 농담. 조옮김이 필요하지 않습니다.

df.loc[~(df==0).all(axis=1)]

대칭을 좋아하는 사람들에게도 효과가 있습니다 ...

df.loc[(df!=0).any(axis=1)]

1
간결함을 위해 (그리고 제 생각에는 목적의 명확성을 위해) 이것을 Akavall의 의견과 결합하십시오 : df.loc[(df != 0).any(1)]. 팀워크!
Dan Allan

1
+1, 30 % 더 빠른 조옮김-491 ~ 614 마이크로 초, 저는 axis=1명시적인 것을 좋아합니다 . 내 의견으로는 더 pythonic
gt6989b

원래 질문에서 dropna의 동등성을 언급했기 때문에 .all과 .any 사용의 차이점에 대해 언급해야합니다. 0을 포함하는 열이있는 모든 행을 삭제하려면 위의 답변에서 .all 및 .any를 반대로해야합니다. 그 기능을 찾고 있었을 때 이것을 깨닫는 데 시간이 걸렸습니다.
Zak Keirn

이것은 동일한 나를 위해 작동하지만, 반환 나하지 않습니다df
Robvh

이것의 '인플레 이스'버전이 있습니까? 나는이 될 필요가있을 것이다, 영업 이익은 요청에 따라 그는 안양 행을 드롭 볼 df = df.loc[(df!=0).all(axis=1)]df = df.loc[(df!=0).any(axis=1)]dropna에 실제 해당 될 것 같은 () 어떤 제로로 행을 드롭.
alchemy

19

저는이 질문을 한 달에 한 번 찾아보고 항상 댓글에서 가장 좋은 답변을 찾아야합니다.

df.loc[(df!=0).any(1)]

감사합니다 Dan Allan!


2
파기가 필요하지 않습니다. @ 8one6은 2014 년에 "그리고 대칭을 좋아하는 사람들을 위해 ..."라는 부분을 그의 답변에 포함 시켰습니다.
Rahul Murmuria

14

0을 nan로 바꾼 다음 모든 항목이있는 행을 nan. 그 후 nan0으로 대체하십시오 .

import numpy as np
df = df.replace(0, np.nan)
df = df.dropna(how='all', axis=0)
df = df.replace(np.nan, 0)

3
데이터에 기존 NaN이 있으면 실패합니다.
OmerB


7

특히 더 큰 데이터 세트의 경우이를 찾는 동안 도움이되는 몇 가지 솔루션 :

df[(df.sum(axis=1) != 0)]       # 30% faster 
df[df.values.sum(axis=1) != 0]  # 3X faster 

@ U2EF1의 예를 계속합니다.

In [88]: df = pd.DataFrame({'a':[0,0,1,1], 'b':[0,1,0,1]})

In [91]: %timeit df[(df.T != 0).any()]
1000 loops, best of 3: 686 µs per loop

In [92]: df[(df.sum(axis=1) != 0)]
Out[92]: 
   a  b
1  0  1
2  1  0
3  1  1

In [95]: %timeit df[(df.sum(axis=1) != 0)]
1000 loops, best of 3: 495 µs per loop

In [96]: %timeit df[df.values.sum(axis=1) != 0]
1000 loops, best of 3: 217 µs per loop

더 큰 데이터 세트에서 :

In [119]: bdf = pd.DataFrame(np.random.randint(0,2,size=(10000,4)))

In [120]: %timeit bdf[(bdf.T != 0).any()]
1000 loops, best of 3: 1.63 ms per loop

In [121]: %timeit bdf[(bdf.sum(axis=1) != 0)]
1000 loops, best of 3: 1.09 ms per loop

In [122]: %timeit bdf[bdf.values.sum(axis=1) != 0]
1000 loops, best of 3: 517 µs per loop

행에 -1과 1이 있으면 나쁜 일이 발생합니까?
Rhys Ulerich

물론, 동일한 행의 합이 0이되면 합계가 작동하지 않습니다. 여기에 약간만 느린 빠른 해결 방법이 있습니다. df[~(df.values.prod(axis=1) == 0) | ~(df.values.sum(axis=1)==0)]
clocker

prod () 함수는 아무것도 해결하지 않습니다. 0을 반환 할 행에 0이있는 경우. [-1, -0.5, 0, 0.5, 1]과 같은 행을 처리해야하는 경우 두 솔루션 모두 작동하지 않습니다.
Rahul Murmuria

다음은 허용 된 답변보다 3 배 빠르게 작동하는 올바른 버전입니다.bdf[np.square(bdf.values).sum(axis=1) != 0]
Rahul Murmuria 2017-06-19

5
import pandas as pd

df = pd.DataFrame({'a' : [0,0,1], 'b' : [0,0,-1]})

temp = df.abs().sum(axis=1) == 0      
df = df.drop(temp)

결과:

>>> df
   a  b
2  1 -1

1 열 데이터 프레임으로 나를 위해 작동하지 않았습니다. GotValueError: labels [True ... ] not contained in matrix
The Unfun Cat 2015-04-24

대신 df = df.drop(temp)사용df = df.drop(df[temp].index)
Douglas Ferreira

3

빠른 lambda기능을 사용 하여 주어진 행의 모든 ​​값이 0. 그런 다음이를 적용한 결과를 lambda해당 조건과 일치하거나 일치하지 않는 행만 선택하는 방법으로 사용할 수 있습니다.

import pandas as pd
import numpy as np

np.random.seed(0)

df = pd.DataFrame(np.random.randn(5,3), 
                  index=['one', 'two', 'three', 'four', 'five'],
                  columns=list('abc'))

df.loc[['one', 'three']] = 0

print df
print df.loc[~df.apply(lambda row: (row==0).all(), axis=1)]

수율 :

              a         b         c
one    0.000000  0.000000  0.000000
two    2.240893  1.867558 -0.977278
three  0.000000  0.000000  0.000000
four   0.410599  0.144044  1.454274
five   0.761038  0.121675  0.443863

[5 rows x 3 columns]
             a         b         c
two   2.240893  1.867558 -0.977278
four  0.410599  0.144044  1.454274
five  0.761038  0.121675  0.443863

[3 rows x 3 columns]

1

또 다른 대안 :

# Is there anything in this row non-zero?
# df != 0 --> which entries are non-zero? T/F
# (df != 0).any(axis=1) --> are there 'any' entries non-zero row-wise? T/F of rows that return true to this statement.
# df.loc[all_zero_mask,:] --> mask your rows to only show the rows which contained a non-zero entry.
# df.shape to confirm a subset.

all_zero_mask=(df != 0).any(axis=1) # Is there anything in this row non-zero?
df.loc[all_zero_mask,:].shape

0

나를 위해이 코드 : df.loc[(df!=0).any(axis=0)] 작동하지 않았습니다. 정확한 데이터 세트를 반환했습니다.

대신 나는 df.loc[:, (df!=0).any(axis=0)] 데이터 세트에서 값이 0 인 모든 열을 하고 삭제했습니다.

이 함수 .all()는 내 데이터 세트에서 0 값이있는 모든 열을 삭제했습니다.


-1
df = df [~( df [ ['kt'  'b'   'tt'  'mky' 'depth', ] ] == 0).all(axis=1) ]

이 명령은 완벽하게 작동합니다.


-2

행에서 값이 0 인 모든 열을 삭제하려면 다음을 수행하십시오.

new_df = df[df.loc[:]!=0].dropna()
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.