"""
# 1. Introduction
"""
import numpy as np
import pandas as pd 
import matplotlib.pyplot as plt
import seaborn as sns
store = pd.read_csv('/kaggle/input/google-play-store-apps/googleplaystore.csv')
store.head()
store.info()
"""
## 2. Data Cleaning
"""
"""
### 2.1. Drop Unwanted Columns
"""
store.drop(['Genres', 'Last Updated', 'Current Ver', 'Android Ver'], inplace=True, axis=1)
store.head()
"""
### 2.2. Drop Duplicates
"""
store[store.duplicated(keep=False)].sort_values('App')
store.drop_duplicates(inplace=True)
"""
### 2.2. Drop Missing Rows
"""
store.isna().sum()
store[store.Type.isna()]
print(store.shape)
store.dropna(inplace=True)
print(store.shape)
# The amount of loss after cleaning.
(1 - 8890 / 10841) * 100
"""
## 3. Data Tidying
"""
"""
### 3.1. Determine Categorical Columns
"""
store.Category.value_counts()
"""
Let's clean up "Content Rating" column.
"""
store['Content Rating'].value_counts()
store.drop(store.loc[store['Content Rating'] == 'Unrated'].index, inplace=True)
store.loc[store['Content Rating'] == 'Adults only 18+', 'Content Rating'] = 'Mature 17+'
store['Content Rating'].value_counts()
store['Type'].value_counts()
store['Category'] = store['Category'].astype('category')
store['Content Rating'] = store['Content Rating'].astype('category')
store['Type'] = store['Type'].astype('category')
"""
### 3.2. Determine and Create Numerical Columns
"""
store.sort_values('Reviews', ascending=False).head()
"""
Lets consider the Installs column
"""
store['Installs'].unique()
store['Installs'] = store['Installs'].str.replace('+','',regex=True).replace(',','',regex=True)
store['Installs'].unique()
store['Installs'] = store.Installs.astype(int)
"""
Let's evaluate Reviews column
"""
store['Reviews'].unique()
store['Reviews'].str.isnumeric().sum() == store['Reviews'].count()
store['Rating'].unique()
"""
Price column needs manipulation.
"""
store['Price'].unique()
store['Price'].str.replace('$','', regex=True).unique()
store['Price'] = store['Price'].str.replace('$','', regex=True)
store['Size'].unique()
size_replace= {
    '.':'',
    'k':'000',
    'M':'000000'
              }

for key, value in size_replace.items():
    store['Size'] = store['Size'].str.replace(key,value, regex=True)
    
store['Size'].head()
store[store['Size'] == 'Varies with device'].shape
"""
If the rows which has 'Size' column with "varies with device" value have dropped, we will lose %16.51 of our data.
"""
store[store['Size'] == 'Varies with device'].shape[0] / store.shape[0] * 100
store[['Rating', 'Reviews', 'Installs', 'Price']] = store[['Rating', 'Reviews', 'Installs', 'Price']].apply(pd.to_numeric)
store.info()
"""
## 4. Exploratory Data Analysis 
"""
store.head()
store.describe(include=[np.number]).T
store.describe(include=[np.object, pd.Categorical]).T
"""
### 4.1. Categorical Analysis
"""
plt.figure(figsize=(16,6))
sns.countplot(data=store, x='Category', order = store['Category'].value_counts().index)
plt.xticks(rotation=90)
plt.show()
plt.figure(figsize=(16,6))
sns.barplot(data=store, x='Category', y='Rating', estimator=np.median)
plt.xticks(rotation=90)
plt.show()
plt.figure(figsize=(16,6))
sns.barplot(data=store, x='Category', y='Price')
plt.xticks(rotation=90)
plt.show()
plt.figure(figsize=(16,6))
sns.barplot(data=store, x='Category', y='Installs')
plt.xticks(rotation=90)
plt.show()
plt.figure(figsize=(12,6))
sns.countplot(data=store, x='Type')
plt.xticks(rotation=90)
plt.show()
plt.figure(figsize=(12,6))
sns.countplot(data=store, x='Content Rating')
plt.xticks(rotation=90)
plt.show()
"""
### 4.2. Numerical Analysis
"""
fig, axes = plt.subplots(1, 3, figsize=(15,6))
sns.histplot(data=store, x='Rating', ax=axes[0])
sns.boxplot(data=store, x='Rating', ax=axes[1])
sns.violinplot(data=store, x='Rating', ax=axes[2])
plt.show()
fig, axes = plt.subplots(1, 3, figsize=(15,6))
sns.histplot(data=store, x='Reviews', ax=axes[0])
sns.boxplot(data=store, x='Reviews', ax=axes[1])
sns.violinplot(data=store, x='Reviews', ax=axes[2]);
"""
We couldn't see anything  at histplot? This must be caused by outliers.
"""
reviews_filtered = store[store['Reviews'] < 200000]
fig, axes = plt.subplots(1, 3, figsize=(15,6))
sns.histplot(data=reviews_filtered, x='Reviews', ax=axes[0])
sns.boxplot(data=reviews_filtered, x='Reviews', ax=axes[1])
sns.violinplot(data=reviews_filtered, x='Reviews', ax=axes[2]);
fig, axes = plt.subplots(1, 3, figsize=(15,6))
sns.histplot(data=store, x='Price', ax=axes[0])
sns.boxplot(data=store, x='Price', ax=axes[1])
sns.violinplot(data=store, x='Price', ax=axes[2]);
store.Price.nlargest(50)
price_filtered = store[store['Price'] < 50]
fig, axes = plt.subplots(1, 3, figsize=(15,6))
sns.histplot(data=price_filtered, x='Price', ax=axes[0])
sns.boxplot(data=price_filtered, x='Price', ax=axes[1])
sns.violinplot(data=price_filtered, x='Price', ax=axes[2]);