# 3-3-3-10. Dealing with NaN

Before we can begin analyzing data or using it to train our learning algorithms,

we need to clean it.

This means we need a way to detect and correct errors in our data.

While any given dataset can have many types of

bad data such as outliers or incorrect values,

the type of bad data we encounter almost always is missing values.

As we saw earlier,

Pandas assigns the value NaN,

or not a number to missing data.

In this section, we will learn how to detect and deal with these NaN values.

In this DataFrame, we have three NaN values.

One in store one,

and two in store three.

However, in cases where we load

very large datasets into a DataFrame possibly with millions of items,

the number of NaN values isn’t easily visualized like this.

For these cases, we can use a combination of

methods to count the number of NaN values in our data.

This combines to is null and sum methods to count

the number of NaN values in our DataFrame. Let’s break this down.

The is null method returns a DataFrame with

a Boolean for each value in the store items DataFrame.

True, when the value is NaN.

In Pandas, logical true values have the numerical value

one and logical false values have the numerical value zero.

Therefore, we can count the number of NaN values by

counting the number of logical true values from this DataFrame.

Using sum ones gives us a number of NaNs in each column.

We use sum again to get the total number of NaNs for the entire DataFrame.

Instead of counting the number of NaN values,

we can also do the opposite and count the number of non-NaN values with the count method.

Now that we know how to find out if our dataset has any NaN values,

the next step is to decide what to do with them.

In general, we have two options.

We can either remove or replace missing values.

To remove them, we can use the drop na method.

We can set the axis parameter to zero to eliminate any rows with NaN values.

We can also set axis to one to eliminate any columns with NaN values.

The dropna method drops these rows or columns out of place.

Meaning, the original DataFrame is not modified.

You can remove them in-place by setting the keyword in-place to true like this.

Now, instead of eliminating NaN values,

let’s replace them with actual values.

As an example, we could choose to replace all NaNs with the value zero.

The fillna method can be used for this.

We can also replace NaNs with values from

the previous row or column with something called forward filling.

This replaces each NaN with the value from the previous value along the given axis.

Here’s the original DataFrame again.

Notice that the two NaN values in store three

have been replaced with the previous values in their column.

However, notice that the NaN value in store one did not get replaced.

That’s because there were no previous values in

this column since NaN is the first value in this column.

However, if we do forward fill using the previous row values this won’t happen.

We see that in this case,

all the NaN values have been replaced with the previous value in that row.

Similarly, you can choose to replace

the NaNs with the values that go after them in the DataFrame.

This is known as backward filling.

This replaces each NaN with the next value in that column.

The NaN value in store one has been replaced by the next value in it’s column.

But the two NaN values in store three did

not since they are the last values in their columns.

The fillna method fills the NaN values out of place.

So, set the parameter in place to true if you want to modify the original DataFrame.

We can also choose to replace NaNs by using different interpolation methods.

For example, this uses linear interpolation to

replace NaN values using the values along the column axis.

The two NaN values in store three have been replaced with linear interpolated values.

However, NaN value in store one did not get replaced since

there is no data before it to allow the interpolation function to calculate a value.

We can replace NaN values with linear interpolation using row values like this.

Like the other methods we saw,

the interpolate method replaces NaN values out of place.

데이터 분석을 시작하거나 학습 알고리즘을 훈련하는 데 사용하기 전에

우리는 그것을 청소해야합니다.

즉, 데이터의 오류를 감지하고 수정할 수 있는 방법이 필요합니다.

주어진 데이터 세트에는 여러 유형이 있을 수 있지만

이상값 또는 잘못된 값과 같은 잘못된 데이터,

우리가 접하는 잘못된 데이터 유형은 거의 항상 결측값입니다.

앞에서 보았듯이,

Pandas는 값을 NaN으로 할당합니다.

또는 누락된 데이터에 대한 숫자가 아닙니다.

이 섹션에서는 이러한 NaN 값을 감지하고 처리하는 방법을 배웁니다.

이 DataFrame에는 3개의 NaN 값이 있습니다.

매장에 하나,

그리고 2개는 매장 3개에 있습니다.

그러나 우리가 로드하는 경우

수백만 개의 항목이 있는 DataFrame에 매우 큰 데이터 세트,

NaN 값의 수는 이렇게 쉽게 시각화되지 않습니다.

이러한 경우 다음을 조합하여 사용할 수 있습니다.

데이터의 NaN 값 수를 계산하는 메서드입니다.

이것은 null 및 합계 방법을 결합하여 계산합니다.

DataFrame에 있는 NaN 값의 수입니다. 이것을 분해해 봅시다.

is null 메서드는 다음과 함께 DataFrame을 반환합니다.

스토어 항목 DataFrame의 각 값에 대한 부울.

값이 NaN인 경우 참입니다.

Pandas에서 논리적 true 값에는 숫자 값이 있습니다.

1 및 논리적 거짓 값은 숫자 값이 0입니다.

따라서 다음과 같이 NaN 값의 수를 셀 수 있습니다.

이 DataFrame에서 논리적 참 값의 수를 계산합니다.

합을 사용하면 각 열에 많은 수의 NaN이 제공됩니다.

합계를 다시 사용하여 전체 DataFrame에 대한 총 NaN 수를 얻습니다.

NaN 값의 수를 계산하는 대신

우리는 또한 반대를 수행하고 count 메소드를 사용하여 비 NaN 값의 수를 계산할 수 있습니다.

이제 데이터 세트에 NaN 값이 있는지 확인하는 방법을 알았으므로

다음 단계는 그들로 무엇을 할 것인지 결정하는 것입니다.

일반적으로 두 가지 옵션이 있습니다.

누락된 값을 제거하거나 대체할 수 있습니다.

그것들을 제거하기 위해 drop na 메소드를 사용할 수 있습니다.

축 매개변수를 0으로 설정하여 NaN 값이 있는 행을 제거할 수 있습니다.

또한 축을 1로 설정하여 NaN 값이 있는 열을 제거할 수도 있습니다.

dropna 메서드는 이러한 행이나 열을 제자리에서 삭제합니다.

즉, 원본 DataFrame은 수정되지 않습니다.

이와 같이 키워드 in-place를 true로 설정하여 제자리에서 제거할 수 있습니다.

이제 NaN 값을 제거하는 대신

실제 값으로 바꾸자.

예를 들어 모든 NaN을 값 0으로 바꾸도록 선택할 수 있습니다.

이를 위해 fillna 방법을 사용할 수 있습니다.

NaN을 다음 값으로 바꿀 수도 있습니다.

정방향 채우기라고 하는 이전 행 또는 열.

이렇게 하면 각 NaN이 지정된 축을 따라 이전 값의 값으로 바뀝니다.

여기 다시 원래 DataFrame이 있습니다.

세 번째 저장소에 있는 두 개의 NaN 값에 유의하십시오.

열의 이전 값으로 대체되었습니다.

그러나 저장소 1의 NaN 값은 대체되지 않았습니다.

에 이전 값이 없었기 때문입니다.

NaN이 이 열의 첫 번째 값이기 때문에 이 열입니다.

그러나 이전 행 값을 사용하여 정방향 채우기를 수행하면 이러한 일이 발생하지 않습니다.

우리는 이 경우에,

모든 NaN 값은 해당 행의 이전 값으로 대체되었습니다.

마찬가지로 교체를 선택할 수 있습니다.

DataFrame에서 그 뒤에 오는 값이 있는 NaN.

이것을 후방 채우기라고 합니다.

이렇게 하면 각 NaN이 해당 열의 다음 값으로 바뀝니다.

저장소 1의 NaN 값은 해당 열의 다음 값으로 대체되었습니다.

그러나 세 번째 저장소에 있는 두 개의 NaN 값은

열의 마지막 값이기 때문이 아닙니다.

fillna 메서드는 NaN 값을 제자리에서 채웁니다.

따라서 원래 DataFrame을 수정하려면 매개변수를 true로 설정하십시오.

다른 보간 방법을 사용하여 NaN을 대체하도록 선택할 수도 있습니다.

예를 들어 선형 보간을 사용하여

열 축을 따라 값을 사용하여 NaN 값을 바꿉니다.

세 번째 저장소에 있는 두 개의 NaN 값은 선형 보간 값으로 대체되었습니다.

그러나 저장소 1의 NaN 값은 다음 이후로 대체되지 않았습니다.

보간 기능이 값을 계산할 수 있도록 그 앞에 데이터가 없습니다.

이와 같은 행 값을 사용하여 NaN 값을 선형 보간법으로 대체할 수 있습니다.

우리가 본 다른 방법과 마찬가지로,

보간 방법은 제자리에 없는 NaN 값을 대체합니다.

Dealing with NaN

As mentioned earlier, before we can begin training our learning algorithms with large datasets, we usually need to clean the data first. This means we need to have a method for detecting and correcting errors in our data. While any given dataset can have many types of bad data, such as outliers or incorrect values, the type of bad data we encounter almost always is missing values. As we saw earlier, Pandas assigns NaN values to missing data. In this lesson we will learn how to detect and deal with NaN values.

We will begin by creating a DataFrame with some NaN values in it.

#### Example 1. Create a DataFrame

# We create a list of Python dictionaries
items2 = [{'bikes': 20, 'pants': 30, 'watches': 35, 'shirts': 15, 'shoes':8, 'suits':45},
{'watches': 10, 'glasses': 50, 'bikes': 15, 'pants':5, 'shirts': 2, 'shoes':5, 'suits':7},
{'bikes': 20, 'pants': 30, 'watches': 35, 'glasses': 4, 'shoes':10}]

# We create a DataFrame  and provide the row index
store_items = pd.DataFrame(items2, index = ['store 1', 'store 2', 'store 3'])

# We display the DataFrame
store_items


We can clearly see that the DataFrame we created has 3 NaN values: one in store 1 and two in store 3. However, in cases where we load very large datasets into a DataFrame, possibly with millions of items, the number of NaN values is not easily visualized. For these cases, we can use a combination of methods to count the number of NaN values in our data. The following example combines the .isnull() and the sum() methods to count the number of NaN values in our DataFrame

#### Example 2 a. Count the total NaN values

# We count the number of NaN values in store_items
x =  store_items.isnull().sum().sum()

# We print x
print('Number of NaN values in our DataFrame:', x)


Number of NaN values in our DataFrame: 3

In the above example, the .isnull() method returns a Boolean DataFrame of the same size as store_items and indicates with True the elements that have NaN values and with False the elements that are not. Let’s see an example:

#### Example 2 b. Return boolean True/False for each element if it is a NaN

store_items.isnull()


In Pandas, logical True values have numerical value 1 and logical False values have numerical value 0. Therefore, we can count the number of NaN values by counting the number of logical True values. In order to count the total number of logical True values we use the .sum() method twice. We have to use it twice because the first sum returns a Pandas Series with the sums of logical True values along columns, as we see below:

#### Example 2 c. Count NaN down the column.

store_items.isnull().sum()


bikes            0
glasses        1
pants           0
shirts           1
shoes          0
suits            1
watches      0
dtype: int64

The second sum will then add up the 1s in the above Pandas Series.

Instead of counting the number of NaN values we can also do the opposite, we can count the number of non-NaN values. We can do this by using the .count() method as shown below:

#### Example 3. Count the total non-NaN values

# We print the number of non-NaN values in our DataFrame
print()
print('Number of non-NaN values in the columns of our DataFrame:\n', store_items.count())


Number of non-NaN values in the columns of our DataFrame:
bikes            3
glasses        2
pants           3
shirts           2
shoes          3
suits            2
watches      3
dtype: int64

## Eliminating NaN Values

Now that we learned how to know if our dataset has any NaN values in it, the next step is to decide what to do with them. In general, we have two options, we can either delete or replace the NaN values. In the following examples, we will show you how to do both.

We will start by learning how to eliminate rows or columns from our DataFrame that contain any NaN values. The .dropna(axis) method eliminates any rows with NaN values when axis = 0 is used and will eliminate any columns with NaN values when axis = 1 is used.

Tip: Remember, you learned that you can read axis = 0 as “down” and axis = 1 as “across” the given Numpy ndarray or Pandas dataframe object.

Let’s see some examples.

#### Example 4. Drop rows having NaN values

# We drop any rows with NaN values
store_items.dropna(axis = 0)


#### Example 5. Drop columns having NaN values

# We drop any columns with NaN values
store_items.dropna(axis = 1)


Notice that the .dropna() method eliminates (drops) the rows or columns with NaN values out of place. This means that the original DataFrame is not modified. You can always remove the desired rows or columns in place by setting the keyword inplace = True inside the dropna() function.

## Substituting NaN Values

Now, instead of eliminating NaN values, we can replace them with suitable values. We could choose for example to replace all NaN values with the value 0. We can do this by using the .fillna() method as shown below.

#### Example 6. Replace NaN with 0

# We replace all NaN values with 0
store_items.fillna(0)


We can also use the .fillna() method to replace NaN values with previous values in the DataFrame, this is known as forward filling. When replacing NaN values with forward filling, we can use previous values taken from columns or rows. The .fillna(method = 'ffill', axis) will use the forward filling (ffill) method to replace NaN values using the previous known value along the given axis. Let’s see some examples:

#### Example 7. Forward fill NaN values down (axis = 0) the dataframe

# We replace NaN values with the previous value in the column
store_items.fillna(method = 'ffill', axis = 0)


Notice that the two NaN values in store 3 have been replaced with previous values in their columns. However, notice that the NaN value in store 1 didn’t get replaced. That’s because there are no previous values in this column, since the NaN value is the first value in that column. However, if we do forward fill using the previous row values, this won’t happen. Let’s take a look:

#### Example 8. Forward fill NaN values across (axis = 1) the dataframe

# We replace NaN values with the previous value in the row
store_items.fillna(method = 'ffill', axis = 1)


We see that in this case all the NaN values have been replaced with the previous row values.

Similarly, you can choose to replace the NaN values with the values that go after them in the DataFrame, this is known as backward filling. The .fillna(method = 'backfill', axis) will use the backward filling (backfill) method to replace NaN values using the next known value along the given axis. Just like with forward filling we can choose to use row or column values. Let’s see some examples:

#### Example 9. Backward fill NaN values down (axis = 0) the dataframe

# We replace NaN values with the next value in the column
store_items.fillna(method = 'backfill', axis = 0)


Notice that the NaN value in store 1 has been replaced with the next value in its column. However, notice that the two NaN values in store 3 didn’t get replaced. That’s because there are no next values in these columns, since these NaN values are the last values in those columns. However, if we do backward fill using the next row values, this won’t happen. Let’s take a look:

#### Example 10. Backward fill NaN values across (axis = 1) the dataframe

# We replace NaN values with the next value in the row
store_items.fillna(method = 'backfill', axis = 1)


Notice that the .fillna() method replaces (fills) the NaN values out of place. This means that the original DataFrame is not modified. You can always replace the NaN values in place by setting the keyword inplace = True inside the fillna() function.

We can also choose to replace NaN values by using different interpolation methods. For example, the .interpolate(method = 'linear', axis) method will use linear interpolation to replace NaN values using the values along the given axis. Let’s see some examples:

#### Example 11. Interpolate (estimate) NaN values down (axis = 0) the dataframe

# We replace NaN values by using linear interpolation using column values
store_items.interpolate(method = 'linear', axis = 0)


Notice that the two NaN values in store 3 have been replaced with linear interpolated values. However, notice that the NaN value in store 1 didn’t get replaced. That’s because the NaN value is the first value in that column, and since there is no data before it, the interpolation function can’t calculate a value. Now, let’s interpolate using row values instead:

#### Example 12. Interpolate (estimate) NaN values across (axis = 1) the dataframe

# We replace NaN values by using linear interpolation using row values
store_items.interpolate(method = 'linear', axis = 1)


Just as with the other methods we saw, the .interpolate() method replaces NaN values out of place.