<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Dealing with NaN values
Step1:  Drop NaN Values
Drop rows with any NaN values
Step2:  Drop rows with all NaN values
Step3:  Drop rows with NaN values in the x column.
Step4:  Drop and keep rows atleast 3 non-NaN values
Step5:  Drop columns with all NaN values
Step6:  Drop columns with any NaN values in row 3.
Step7:  Fill NaN values
Replace all NaN values with -1.
Step8:  Replace all NaN values with the first non-NaN value above in column
Step9:  Replace all NaN values with the first non-NaN value below in column
Step10:  Replace atmost 2 NaN values with the first non-NaN value below in column
Step11:  Replace all NaN values with the first non-NaN value to the left in the row
Step12:  Replace all NaN values with the first non-NaN value to the right in the row
<ASSISTANT_TASK:>
Python Code:
import pandas as pd
import numpy as np
from plydata import call
df = pd.DataFrame({
    'w': [1, 2, np.nan, 4, 5],
    'x': [np.nan, 2, np.nan, 4, 5],
    'y': [np.nan] * 4 + [5],
    'z': [np.nan] * 5
})
df
Explanation: Dealing with NaN values
End of explanation
df >> call(pd.DataFrame.dropna)
# You can call method on the dataframe with '.method_name'
df >> call('.dropna')
Explanation: Drop NaN Values
Drop rows with any NaN values
End of explanation
df >> call('.dropna', how='all')
Explanation: Drop rows with all NaN values
End of explanation
df >> call('.dropna', subset=['x'])
Explanation: Drop rows with NaN values in the x column.
End of explanation
df >> call('.dropna', thresh=3)
Explanation: Drop and keep rows atleast 3 non-NaN values
End of explanation
df >> call('.dropna', axis=1, how='all')
Explanation: Drop columns with all NaN values
End of explanation
df >> call('.dropna', axis=1, subset=[3])
Explanation: Drop columns with any NaN values in row 3.
End of explanation
df >> call(pd.DataFrame.fillna, -1)
df >> call('.fillna', -1)
Explanation: Fill NaN values
Replace all NaN values with -1.
End of explanation
df >> call('.fillna', method='ffill')
Explanation: Replace all NaN values with the first non-NaN value above in column
End of explanation
df >> call('.fillna', method='bfill')
Explanation: Replace all NaN values with the first non-NaN value below in column
End of explanation
df >> call('.fillna', method='bfill', limit=2)
Explanation: Replace atmost 2 NaN values with the first non-NaN value below in column
End of explanation
df >> call('.fillna', method='ffill', axis=1)
Explanation: Replace all NaN values with the first non-NaN value to the left in the row
End of explanation
df >> call('.fillna', method='bfill', axis=1)
Explanation: Replace all NaN values with the first non-NaN value to the right in the row
End of explanation
<END_TASK>