4 minute read

This notebook is an exercise in the Pandas course. You can reference the tutorial at this link.


Introduction

Now you are ready to get a deeper understanding of your data.

Run the following cell to load your data and some utility functions (including code to check your answers).

import pandas as pd
pd.set_option("display.max_rows", 5)
reviews = pd.read_csv("../input/wine-reviews/winemag-data-130k-v2.csv", index_col=0)

from learntools.core import binder; binder.bind(globals())
from learntools.pandas.summary_functions_and_maps import *
print("Setup complete.")

reviews.head()
Setup complete.
country description designation points price province region_1 region_2 taster_name taster_twitter_handle title variety winery
0 Italy Aromas include tropical fruit, broom, brimston... Vulkà Bianco 87 NaN Sicily & Sardinia Etna NaN Kerin O’Keefe @kerinokeefe Nicosia 2013 Vulkà Bianco (Etna) White Blend Nicosia
1 Portugal This is ripe and fruity, a wine that is smooth... Avidagos 87 15.0 Douro NaN NaN Roger Voss @vossroger Quinta dos Avidagos 2011 Avidagos Red (Douro) Portuguese Red Quinta dos Avidagos
2 US Tart and snappy, the flavors of lime flesh and... NaN 87 14.0 Oregon Willamette Valley Willamette Valley Paul Gregutt @paulgwine Rainstorm 2013 Pinot Gris (Willamette Valley) Pinot Gris Rainstorm
3 US Pineapple rind, lemon pith and orange blossom ... Reserve Late Harvest 87 13.0 Michigan Lake Michigan Shore NaN Alexander Peartree NaN St. Julian 2013 Reserve Late Harvest Riesling ... Riesling St. Julian
4 US Much like the regular bottling from 2012, this... Vintner's Reserve Wild Child Block 87 65.0 Oregon Willamette Valley Willamette Valley Paul Gregutt @paulgwine Sweet Cheeks 2012 Vintner's Reserve Wild Child... Pinot Noir Sweet Cheeks

Exercises

1.

What is the median of the points column in the reviews DataFrame?

median_points = reviews.points.median()

# Check your answer
q1.check()
<IPython.core.display.Javascript object>

Correct

#q1.hint()
#q1.solution()

2.

What countries are represented in the dataset? (Your answer should not include any duplicates.)

reviews.country.unique()
array(['Italy', 'Portugal', 'US', 'Spain', 'France', 'Germany',
       'Argentina', 'Chile', 'Australia', 'Austria', 'South Africa',
       'New Zealand', 'Israel', 'Hungary', 'Greece', 'Romania', 'Mexico',
       'Canada', nan, 'Turkey', 'Czech Republic', 'Slovenia',
       'Luxembourg', 'Croatia', 'Georgia', 'Uruguay', 'England',
       'Lebanon', 'Serbia', 'Brazil', 'Moldova', 'Morocco', 'Peru',
       'India', 'Bulgaria', 'Cyprus', 'Armenia', 'Switzerland',
       'Bosnia and Herzegovina', 'Ukraine', 'Slovakia', 'Macedonia',
       'China', 'Egypt'], dtype=object)
countries = reviews.country.unique()

# Check your answer
q2.check()
<IPython.core.display.Javascript object>

Correct

#q2.hint()
#q2.solution()

3.

How often does each country appear in the dataset? Create a Series reviews_per_country mapping countries to the count of reviews of wines from that country.

reviews_per_country = reviews.country.value_counts()

# Check your answer
q3.check()
<IPython.core.display.Javascript object>

Correct

#q3.hint()
#q3.solution()

4.

Create variable centered_price containing a version of the price column with the mean price subtracted.

(Note: this ‘centering’ transformation is a common preprocessing step before applying various machine learning algorithms.)

centered_price = reviews.price - reviews.price.mean()

# Check your answer
q4.check()
<IPython.core.display.Javascript object>

Correct

#q4.hint()
#q4.solution()

5.

I’m an economical wine buyer. Which wine is the “best bargain”? Create a variable bargain_wine with the title of the wine with the highest points-to-price ratio in the dataset.

bargain_idx = (reviews.points / reviews.price).idxmax()
bargain_wine = reviews.loc[bargain_idx, 'title']

# Check your answer
q5.check()
<IPython.core.display.Javascript object>

Correct

bargain_wine
'Bandit NV Merlot (California)'
badwine_idx = (reviews.points / reviews.price).idxmin()
bad_wine = reviews.loc[badwine_idx, 'title']
bad_wine
'Château les Ormes Sorbet 2013  Médoc'
q5.hint()
q5.solution()
<IPython.core.display.Javascript object>

Hint: The idxmax method may be useful here.

<IPython.core.display.Javascript object>

Solution:

bargain_idx = (reviews.points / reviews.price).idxmax()
bargain_wine = reviews.loc[bargain_idx, 'title']

6.

There are only so many words you can use when describing a bottle of wine. Is a wine more likely to be “tropical” or “fruity”? Create a Series descriptor_counts counting how many times each of these two words appears in the description column in the dataset. (For simplicity, let’s ignore the capitalized versions of these words.)

reviews.columns
Index(['country', 'description', 'designation', 'points', 'price', 'province',
       'region_1', 'region_2', 'taster_name', 'taster_twitter_handle', 'title',
       'variety', 'winery'],
      dtype='object')
reviews.description.count()
129971
n_trop = reviews.description.map(lambda desc: 'tropical' in desc).sum()
n_fruity = reviews.description.map(lambda desc: 'fruity' in desc).sum()
descriptor_counts = pd.Series([n_trop, n_fruity], index=['tropical', 'fruity'])

# Check your answer
q6.check()
<IPython.core.display.Javascript object>

Correct

q6.hint()
q6.solution()
<IPython.core.display.Javascript object>

Hint: Use a map to check each description for the string tropical, then count up the number of times this is True. Repeat this for fruity. Finally, create a Series combining the two values.

<IPython.core.display.Javascript object>

Solution:

n_trop = reviews.description.map(lambda desc: "tropical" in desc).sum()
n_fruity = reviews.description.map(lambda desc: "fruity" in desc).sum()
descriptor_counts = pd.Series([n_trop, n_fruity], index=['tropical', 'fruity'])

7.

We’d like to host these wine reviews on our website, but a rating system ranging from 80 to 100 points is too hard to understand - we’d like to translate them into simple star ratings. A score of 95 or higher counts as 3 stars, a score of at least 85 but less than 95 is 2 stars. Any other score is 1 star.

Also, the Canadian Vintners Association bought a lot of ads on the site, so any wines from Canada should automatically get 3 stars, regardless of points.

Create a series star_ratings with the number of stars corresponding to each review in the dataset.

type(reviews)
pandas.core.frame.DataFrame
def make_star(row):
    if row.country == 'Canada':
        return 3
    elif row.points >= 95:
        return 3
    elif row.points >= 85 and row.points <95:
        return 2
    else:
        return 1
        

star_ratings = reviews.apply(make_star, axis='columns')

# Check your answer
q7.check()
<IPython.core.display.Javascript object>

Correct

star_ratings.describe()
count    129971.000000
mean          1.924999
             ...      
75%           2.000000
max           3.000000
Length: 8, dtype: float64
q7.hint()
q7.solution()
<IPython.core.display.Javascript object>

Hint: Begin by writing a custom function that accepts a row from the DataFrame as input and returns the star rating corresponding to the row. Then, use DataFrame.apply to apply the custom function to every row in the dataset.

<IPython.core.display.Javascript object>

Solution:

def stars(row):
    if row.country == 'Canada':
        return 3
    elif row.points >= 95:
        return 3
    elif row.points >= 85:
        return 2
    else:
        return 1
    
star_ratings = reviews.apply(stars, axis='columns')

Keep going

Continue to grouping and sorting.


Have questions or comments? Visit the course discussion forum to chat with other learners.

Leave a comment