Python-Project-8-学习笔记

[TOC]

任务一:导入数据(文件 ➔ 变量)

  1. 结合之前我们已经写过的读取文件的代码,读取 Android 数据集和 iOS 数据集,并将它们另存为包含列表的列表:
    • App Store 数据集存储在名为 AppleStore.csvCSV 文件中,Google Play 数据集存储在名为googleplaystore.csvCSV 文件中。两个 CSV 文件数据集已保存在 assets/dataset 文件夹中。
    • 如果遇到名为 UnicodeDecodeError 的错误,请在 open() 函数中添加 encoding=“utf8”,例如,使用 open('AppleStore.csv', encoding='utf8')
    • 你需要分别将 Android 数据集的标题行和数据集内容存放到 android_headerandroid 两个不同的列表中,ios 同理要存放到 ios_headerios 两个列表中。
  2. 使用 Explore_data() 函数浏览两个数据集。
    • 打印每个数据集的前 3 行,每个数据行之间要空一行。
    • 查找每个数据集的行数列数
from csv import reader


def explore_data(dataset, start, end, rows_and_columns=False):
"""
本函数以可读的形式打印行
- `dataset` 一个包含列表的列表
- `start` `end` 都是整数 表示数据集切片的开始和结束索引
- `rows_and_columns` 布尔值 默认参数为False 是否打印行列数
"""
dataset_slice = dataset[start:end]
for row in dataset_slice:
print(row)
print('\n')

if rows_and_columns:
print('Number of rows:', len(dataset))
print('Number of columns:', len(dataset[0]))


def open_dataset(path='assets/dataset/AppleStore.csv'):
"""
- 从指定路径`path`读取CSV文件
- return `(文件标题行,文件内容)`
"""
fs = list(reader(open(path, encoding='utf-8')))
return fs[0], fs[1:]


# The Google Play data set #
android_header, android = open_dataset('assets/dataset/googleplaystore.csv')

# The App Store data set #
ios_header, ios = open_dataset('assets/dataset/AppleStore.csv')

print(ios[0])
print('\n')
explore_data(android, 0, 3, True)

任务二:数据清洗(删除错误和重复)

  1. 创建一个名为 reviews_max 的空字典:
    • 每个字典键是一个唯一的应用程序名称,对应的字典值是该应用程序的最高评论数。
    • 循环浏览 Google Play 数据集,其中每次迭代需要完成:
      • 将应用程序名称分配给名为 name的变量。
      • 将评论数转换为浮点数。将其分配给一个名为 n_reviews 的变量。
      • 如果 name 已作为字典的键存在于 reviews_max 字典中,并且 reviews_max[name]<n_reviews,则更新 reviews_max 字典中该条目的评论数。
      • 如果 name 不作为字典的键存在于 reviews_max 字典中,则在字典中创建一个新条目,其中键是name,值是 reviews 的数量。请确保此处使用 elif 而不是使用 else,否则每当 reviews_max[name]<n_reviews 时,都会被计算为 False,并且会错误地更新评论数。
    • 最后为了确保计算正确,字典的预期长度是 9659 个条目(9660也是对的)
  2. 使用上面创建的词典删除重复行:
    • 首先创建两个空列表:android_clean(它将存储我们新清理的数据集)和 already_added(它只存储应用程序名称)。
    • 循环浏览 Google Play 数据集,其中每次迭代需要完成:
      • 将应用程序名称分配给名为 name 的变量。
      • 将评论数量转换为浮动,并将其分配给名为 n_reviews 的变量。
    • 如果 n_reviews 与应用程序名称 name 的最大评论数相同(可以在评论最大词典中找到该数字),并且 name 不在已添加的列表中:
      • 将整行追加到 android_clean 列表(它最终将是一个包含列表的列表的存储已清理的数据集)。
      • 将应用程序名称 name 添加到 already_added 列表中,这有助于我们跟踪已添加的应用程序。
  3. 探索 android_clean 数据集,确保一切按预期进行,数据集应该有 9659 行,以上两个步骤比较复杂(9660也是对的)
# ... 保留任务一中的全部代码
def task_2(content):
"""
- 本函数完成任务二: 删除 `content` 中的错误行和重复行
- 本函数目前不支持对 IOS 数据集的处理
- 因为两个数据集的 `标题行` 有一定区别
- `return 完成清理的数据:list`
"""
reviews_max = {}

for app in content:
name = app[0]
n_reviews = float(app[3])

if name in reviews_max and reviews_max[name] < n_reviews:
reviews_max[name] = n_reviews

elif name not in reviews_max:
reviews_max[name] = n_reviews

content_clean = []
already_added = []

for app in content:
name = app[0]
n_reviews = float(app[3])

if (reviews_max[name] == n_reviews) and (name not in already_added):
content_clean.append(app)
already_added.append(name) # make sure this is inside the if block

print(len(content_clean))

return content_clean

android = task_2(android)

任务三:删除非英语应用

  1. 编写一个函数,它接受一个字符串,如果输入字符串有超过三个字符超出ASCII范围(0-127),则函数应返回False,否则应返回True。

    • 在函数内部,迭代遍历输入字符串。对于每次迭代,检查与字符对应的ASCII码是否大于127。当有超过三个字符大于127时,函数应立即返回False,应用程序名可能不是英语,因为它包含不属于通用英语字符集的字符。
    • 如果循环正常执行,则表示没有字符对应的ASCII码超出ASCII范围(0-127),应用程序名称可能是英语,因此函数应返回True。
  2. 浏览数据集,查看每个数据集剩余多少行。

# ... 保留之前的所有代码
def task_3(android: list, ios: list):
"""
- 本函数完成任务三: 筛选出应用名称中非ASCII字符数量不大于3的APP
- `return (android_english,ios_english)`
"""
android_english = []
ios_english = []

for app in android:
name = app[0]
if is_english(name):
android_english.append(app)

for app in ios:
name = app[1]
if is_english(name):
ios_english.append(app)

return android_english, ios_english


# The Google Play data set #
android_header, android = open_dataset('assets/dataset/googleplaystore.csv')

# The App Store data set #
ios_header, ios = open_dataset('assets/dataset/AppleStore.csv')

android = task_2(android)

android_english, ios_english = task_3(android=android, ios=ios)
explore_data(android_english, 0, 3, True)
print('\n')
explore_data(ios_english, 0, 3, True)

任务四:删除非免费的应用

# ... 保留之前的所有代码
def task_4(android: list, android_price_index: int, ios: list, ios_price_index: int):
"""
- 本函数完成任务四: 筛选出免费的应用
- `return (android_free,ios_free)`
"""

android_free = []
ios_free = []

for app in android_english:
price = app[android_price_index]
if price == '0':
android_free.append(app)

for app in ios_english:
price = app[ios_price_index]
if price == '0.0':
ios_free.append(app)

return android_free, ios_free


# First: get Data
android_header, android = open_dataset('assets/dataset/googleplaystore.csv')
ios_header, ios = open_dataset('assets/dataset/AppleStore.csv')

android = task_2(android)
android_english, ios_english = task_3(android=android, ios=ios)
android_free, ios_free = task_4(android=android, android_price_index=7, ios=ios, ios_price_index=4)

print(len(android_free))
print(len(ios_free))