pandas DataFrame에서 선행 값으로 NaN을 바꾸는 방법은 무엇입니까?


140

NaNs 가있는 DataFrame이 있다고 가정합니다 .

>>> import pandas as pd
>>> df = pd.DataFrame([[1, 2, 3], [4, None, None], [None, None, 9]])
>>> df
    0   1   2
0   1   2   3
1   4 NaN NaN
2 NaN NaN   9

내가해야 할 일은 위의 동일한 열에서 모든 값을 NaN첫 번째가 아닌 NaN값으로 바꾸는 것입니다. 첫 번째 행에는 결코을 포함하지 않는 것으로 가정합니다 NaN. 이전 예제의 경우 결과는

   0  1  2
0  1  2  3
1  4  2  3
2  4  2  9

열 단위, 요소 단위로 전체 DataFrame을 반복하고 값을 직접 설정할 수 있지만 이것을 달성하는 쉬운 (최적의 루프가없는) 방법이 있습니까?

답변:


213

fillnaDataFrame에서 메소드를 사용하고 메소드를 ffill(전달) 으로 지정할 수 있습니다 .

>>> df = pd.DataFrame([[1, 2, 3], [4, None, None], [None, None, 9]])
>>> df.fillna(method='ffill')
   0  1  2
0  1  2  3
1  4  2  3
2  4  2  9

이 방법...

마지막 유효 관측치를 다음 유효로 전파

반대 방향으로 가려면 bfill방법도 있습니다.

이 메서드는 DataFrame을 수정하지 않습니다. 반환 된 DataFrame을 변수에 리 바인드하거나 다른 방법으로 지정해야합니다 inplace=True.

df.fillna(method='ffill', inplace=True)

31

허용 된 답변은 완벽합니다. 나는 관련이 있지만 약간 다른 상황이 있었지만 그룹 내에서만 작성해야했습니다. 누군가 같은 요구가있는 경우 fillna가 DataFrameGroupBy 오브젝트에서 작동 함을 알아야합니다.

>>> example = pd.DataFrame({'number':[0,1,2,nan,4,nan,6,7,8,9],'name':list('aaabbbcccc')})
>>> example
  name  number
0    a     0.0
1    a     1.0
2    a     2.0
3    b     NaN
4    b     4.0
5    b     NaN
6    c     6.0
7    c     7.0
8    c     8.0
9    c     9.0
>>> example.groupby('name')['number'].fillna(method='ffill') # fill in row 5 but not row 3
0    0.0
1    1.0
2    2.0
3    NaN
4    4.0
5    4.0
6    6.0
7    7.0
8    8.0
9    9.0
Name: number, dtype: float64

정확히 내가 찾던 것, ty
Tony

18

옵션 pandas.DataFrame.fillna과 함께 사용할 수 있습니다 method='ffill'. 'ffill''앞으로 채우기'를 나타내며 마지막 유효한 관측치를 앞으로 전파합니다. 대안은 'bfill'같은 방식으로 작동하지만 거꾸로 작동합니다.

import pandas as pd

df = pd.DataFrame([[1, 2, 3], [4, None, None], [None, None, 9]])
df = df.fillna(method='ffill')

print(df)
#   0  1  2
#0  1  2  3
#1  4  2  3
#2  4  2  9

pandas.DataFrame.ffill일을 더 단순하게하기 위한 직접적인 동의어 함수도 있습니다 .


14

이 솔루션을 시도 할 때 주목할 점은 배열의 시작 또는 끝에 N / A가 있으면 ffill 및 bfill이 제대로 작동하지 않는다는 것입니다. 둘 다 필요합니다.

In [224]: df = pd.DataFrame([None, 1, 2, 3, None, 4, 5, 6, None])

In [225]: df.ffill()
Out[225]:
     0
0  NaN
1  1.0
...
7  6.0
8  6.0

In [226]: df.bfill()
Out[226]:
     0
0  1.0
1  1.0
...
7  6.0
8  NaN

In [227]: df.bfill().ffill()
Out[227]:
     0
0  1.0
1  1.0
...
7  6.0
8  6.0

훌륭한. 내 문제에 정확히 이것이 필요했습니다. 전과 후를 모두 채우십시오. 고마워
Prometheus

큰. 이 솔루션이 필요합니다. 감사합니다
Junkrat


5

단 하나의 열 버전

  • 마지막 유효 값으로 NAN을 채 웁니다.
df[column_name].fillna(method='ffill', inplace=True)
  • 다음 유효한 값으로 NAN을 채 웁니다.
df[column_name].fillna(method='backfill', inplace=True)

5

ffill메소드에 동의 하지만 추가 정보는 키워드 인수로 앞으로 채우기를 제한 할 수 있다는 것 limit입니다.

>>> import pandas as pd    
>>> df = pd.DataFrame([[1, 2, 3], [None, None, 6], [None, None, 9]])

>>> df
     0    1   2
0  1.0  2.0   3
1  NaN  NaN   6
2  NaN  NaN   9

>>> df[1].fillna(method='ffill', inplace=True)
>>> df
     0    1    2
0  1.0  2.0    3
1  NaN  2.0    6
2  NaN  2.0    9

이제와 limit키워드 인수

>>> df[0].fillna(method='ffill', limit=1, inplace=True)

>>> df
     0    1  2
0  1.0  2.0  3
1  1.0  2.0  6
2  NaN  2.0  9

1

필자의 경우 다른 장치의 시계열이 있지만 일부 장치는 일정 기간 동안 어떤 값도 보낼 수 없습니다. 따라서 모든 장치와 기간에 대해 NA 값을 작성하고 그 후에는 fillna를 작성해야합니다.

df = pd.DataFrame([["device1", 1, 'first val of device1'], ["device2", 2, 'first val of device2'], ["device3", 3, 'first val of device3']])
df.pivot(index=1, columns=0, values=2).fillna(method='ffill').unstack().reset_index(name='value')

결과:

        0   1   value
0   device1     1   first val of device1
1   device1     2   first val of device1
2   device1     3   first val of device1
3   device2     1   None
4   device2     2   first val of device2
5   device2     3   first val of device2
6   device3     1   None
7   device3     2   None
8   device3     3   first val of device3

0

fillnaNaN 값을 제거하거나 바꾸는 데 사용할 수 있습니다 .

NaN 제거

import pandas as pd

df = pd.DataFrame([[1, 2, 3], [4, None, None], [None, None, 9]])

df.fillna(method='ffill')
     0    1    2
0  1.0  2.0  3.0
1  4.0  2.0  3.0
2  4.0  2.0  9.0

NaN 교체

df.fillna(0) # 0 means What Value you want to replace 
     0    1    2
0  1.0  2.0  3.0
1  4.0  0.0  0.0
2  0.0  0.0  9.0

참조 pandas.DataFrame.fillna

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