Loading

笔记|《Python数据分析基础》

https://img2.doubanio.com/view/subject/l/public/s29506063.jpg

本书附带代码:

https://github.com/cbrownley/foundations-for-analytics-with-python

python基础

Strategy for Finding a Regex

We need a strategy to find a regex that matches all the winners but none of the losers. I came up with this approach:

  • Generate a pool of regex parts: small regexes of a few characters, such as or or ."bu""r.e$""j"
  • Consider only parts that match at least one winner, but no losers.
  • Our solution will be formed by "or"-ing together some of these parts (e.g. )."bu|n.e|j"
  • This is a set cover problem: pick some of the parts so that they cover all the winners.
  • Set cover is an NP-hard problem, so I feel justified in using an approximation approach that finds a small but not necessarily smallest solution.
  • For many NP-hard problems a good approximation can be had with a greedy algorithm: Pick the "best" part first (the one that covers the most winners with the fewest characters), and repeat, choosing the "best" each time until there are no more winners to cover.
  • To guarantee that we will find a solution, make sure that each winner has at least one part that matches it.

There are three ways this strategy can fail to find the shortest possible regex:

  • The shortest regex might not be a disjunction. Our strategy can only find disjunctions (of the form )."a|b|c|..."
  • The shortest regex might be a disjunction formed with different parts. For example, is not in our pool of parts."[rn]t"
  • The greedy algorithm isn't guaranteed to find the shortest solution. We might have all the right parts, but pick the wrong ones.

寻找正则表达式的策略

我们需要一种策略来找到一个匹配所有赢家但不匹配输家的正则表达式。我想出了这种方法:

  • 生成一个正则表达式_部分_池:几个字符的小正则表达式,例如 or 或 ."bu""r.e$""j"
  • 只考虑至少匹配一个赢家的部分,但没有输家。
  • 我们的解决方案将通过“或”将这些部分(例如)组合在一起形成。"bu|n.e|j"
  • 这是一个设置覆盖问题:选择一些部分,以便它们覆盖所有获胜者。
  • 集合覆盖是一个NP困难的问题,所以我觉得使用近似方法找到一个小但不一定最小的解决方案是合理的。
  • 对于许多NP难题,使用贪婪算法可以得到很好的近似:首先选择“最佳”部分(用最少的字符覆盖最多获胜者的部分),然后重复,每次选择“最佳”,直到没有更多的获胜者要覆盖。
  • 为了保证我们能找到解决方案,请确保每个获胜者至少有一个与之匹配的部分。

此策略有三种方法可能无法找到最短的正则表达式:

  • 最短的正则表达式可能不是析取。我们的策略只能找到(形式)的析取。"a|b|c|..."
  • 最短的正则表达式可能是由不同部分形成的析取。例如,不在我们的零件库中。"[rn]t"
  • 贪婪的算法不能保证找到最短的解决方案。我们可能拥有所有正确的零件,但选择了错误的零件。

读取文本文件

《Python数据分析基础》试读:1.6 使用glob读取多个文本文件

列表

Python中的operator.itemgetter函数

CSV文件

# 删除指定行的数据,通过 drop() 方法删除行索引为 [0, 1, 2, 16, 17, 18] 的行
data_frame = data_frame.drop([0, 1, 2, 16, 17, 18])

# 将第一行的数据作为新的列名,通过 columns 属性修改 DataFrame 的列名
data_frame.columns = data_frame.iloc[0]

# 删除指定行,通过 reindex() 方法删除行索引为 3 的行
data_frame = data_frame.reindex(data_frame.index.drop(3))
# 定义列名列表
header_list = ['A', 'B', 'C', 'D', 'E']

# 使用 pandas 的 read_csv() 方法读取输入文件,并指定 header=None 表示输入文件没有列名,
# 然后通过 names 参数指定列名列表为 header_list,从而为 DataFrame 添加列名。
data_frame = pd.read_csv(input_file, header=None, names=header_list)

# 使用 pandas 的 to_csv() 方法将 DataFrame 写入输出文件,并指定 index=False 表示不将行索引写入文件。
data_frame.to_csv(output_file, index=False)

pandas一次读取多个csv文件并合成一个csv文件 - urls - 博客园

# 使用 glob.glob() 方法获取符合条件的所有文件路径,匹配以 'sales_' 开头的文件
all_files = glob.glob(os.path.join(input_path, 'sales_*'))

# 创建一个空列表 all_data_frames,用于存储读取的所有数据
all_data_frames = []

# 遍历所有文件路径
for file in all_files:
    # 使用 pandas 的 read_csv() 方法读取当前文件,并设置 index_col=None 表示不使用任何列作为索引
    data_frame = pd.read_csv(file, index_col=None)
    # 将当前文件读取的数据 DataFrame 添加到 all_data_frames 列表中
    all_data_frames.append(data_frame)

# 使用 pandas 的 concat() 方法将所有 DataFrame 合并为一个新的 DataFrame
# 参数 axis=0 表示沿着行的方向合并,ignore_index=True 表示重置合并后的 DataFrame 的行索引
data_frame_concat = pd.concat(all_data_frames, axis=0, ignore_index=True)

# 使用 pandas 的 to_csv() 方法将合并后的 DataFrame 写入输出文件
# 参数 index=False 表示不写入行索引,只将 DataFrame 中的数据写入文件
data_frame_concat.to_csv(output_file, index=False)
# 使用 glob.glob() 方法获取符合条件的所有文件路径,匹配以 'sales_' 开头的文件
all_files = glob.glob(os.path.join(input_path, 'sales_*'))

# 创建一个空列表 all_data_frames,用于存储读取的所有数据
all_data_frames = []

# 遍历所有文件路径
for input_file in all_files:
    # 使用 pandas 的 read_csv() 方法读取当前文件,并设置 index_col=None 表示不使用任何列作为索引
    data_frame = pd.read_csv(input_file, index_col=None)
    
    # 计算当前文件中 'Sale Amount' 列的总销售额
    total_sales = pd.DataFrame([float(str(value).strip('$').replace(',', ''))\
                               for value in data_frame.loc[:, 'Sale Amount']]).sum()
    
    # 计算当前文件中 'Sale Amount' 列的平均销售额
    average_sales = pd.DataFrame([float(str(value).strip('$').replace(',', ''))\
                               for value in data_frame.loc[:, 'Sale Amount']]).mean()
    
    # 创建一个字典 data,用于存储当前文件的文件名、总销售额和平均销售额
    data = {'file_name': os.path.basename(input_file),
            'total_sales': total_sales,
            'average_sales': average_sales}
    
    # 将字典 data 转换为 DataFrame,并添加到 all_data_frames 列表中
    all_data_frames.append(pd.DataFrame(data, columns=['file_name', 'total_sales', 'average_sales']))

# 使用 pandas 的 concat() 方法将所有 DataFrame 合并为一个新的 DataFrame
# 参数 axis=0 表示沿着行的方向合并,ignore_index=True 表示重置合并后的 DataFrame 的行索引
data_frames_concat = pd.concat(all_data_frames, axis=0, ignore_index=True)

# 使用 pandas 的 to_csv() 方法将合并后的 DataFrame 写入输出文件
# 参数 index=False 表示不写入行索引,只将 DataFrame 中的数据写入文件
data_frames_concat.to_csv(output_file, index=False)

Excel文件

# 读
data = xlrd.open_workbook('excel.xls')
table = data.sheets()[0]
# 写
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('test')
worksheet.write(0, 0, "no")
workbook.save('save.xls')
workbook=openpyxl.load_workbook('excel.xlsx')
sheet=workbook.get_sheet_by_name('Sheet1')

workbook=openpyx1.Workbook()
sheet=workbook.active
sheet['A1']='你好,小李!'
workbook.save('new.xlsx')
data=pd.read_excel('excel.xls',header=None)

data=[ 'name':['张三','李四','王五'],
	'age':[11,12,13], 
	'sex':'男','女','男']}#写入excel数据 
df = DataFrame(data)#创建DataFrame 
df.to_excel("new.xls")#保存excel
# 使用 glob.glob() 方法获取符合条件的所有工作簿文件路径,匹配以 '*.xls*' 结尾的文件
all_workbooks = glob.glob(os.path.join(input_path, '*.xls*'))

# 创建一个空列表 data_frames,用于存储读取的所有数据
data_frames = []

# 遍历所有工作簿文件路径
for workbook in all_workbooks:
    # 使用 pandas 的 read_excel() 方法读取当前工作簿中的所有工作表,并设置 sheetname=None 表示读取所有工作表,
    # index_col=None 表示不使用任何列作为索引
    all_worksheets = pd.read_excel(workbook, sheetname=None, index_col=None)
    
    # 遍历当前工作簿中的每个工作表和对应的数据
    for worksheet_name, data in all_worksheets.items():
        # 将当前工作表的数据添加到 data_frames 列表中
        data_frames.append(data)

# 使用 pandas 的 concat() 方法将所有 DataFrame 合并为一个新的 DataFrame
# 参数 axis=0 表示沿着行的方向合并,ignore_index=True 表示重置合并后的 DataFrame 的行索引
all_data_concatenated = pd.concat(data_frames, axis=0, ignore_index=True)

# 创建一个 Excel writer 对象,用于写入合并后的数据到输出文件
writer = pd.ExcelWriter(output_file)

# 使用 pandas 的 to_excel() 方法将合并后的 DataFrame 写入 Excel 文件中,
# 并指定 sheet_name='all_data_all_workbooks' 表示将数据写入名为 'all_data_all_workbooks' 的工作表,
# 参数 index=False 表示不写入行索引,只将 DataFrame 中的数据写入文件
all_data_concatenated.to_excel(writer, sheet_name='all_data_all_workbooks', index=False)

# 保存 Excel 文件
writer.save()

数据库

import sqlite3

# 导入 sqlite3 模块,用于操作 SQLite3 数据库。

# 创建一个内存中的 SQLite3 数据库,并与之建立连接。
con = sqlite3.connect(':memory:')

# 定义一个 SQL 查询语句 query,用于创建名为 sales 的表,表中包含四个属性:customer、product、amount 和 date。
query = """CREATE TABLE sales
			(customer VARCHAR(20), 
			 product VARCHAR(40),
			 amount FLOAT,
			 date DATE);"""

# 使用 execute() 方法执行 SQL 查询语句 query,创建表,并通过 commit() 提交更改,使之生效。
con.execute(query)
con.commit()

# 定义要插入到表中的数据 data,每行数据包含 customer、product、amount 和 date 四个字段的值。
data = [('Richard Lucas', 'Notepad', 2.50, '2014-01-02'),
		('Jenny Kim', 'Binder', 4.15, '2014-01-15'),
		('Svetlana Crow', 'Printer', 155.75, '2014-02-03'),
		('Stephen Randolph', 'Computer', 679.40, '2014-02-20')]

# 定义一个 SQL 语句 statement,用于向 sales 表中插入数据。
# 使用 executemany() 方法执行多次插入操作,将数据一次性插入到表中,并通过 commit() 提交更改,使之生效。
statement = "INSERT INTO sales VALUES(?, ?, ?, ?)"
con.executemany(statement, data)
con.commit()

# 使用 SQL 查询语句 "SELECT * FROM sales" 查询 sales 表中的所有数据,并通过 cursor.fetchall() 获取查询结果。
cursor = con.execute("SELECT * FROM sales")
rows = cursor.fetchall()

# 定义变量 row_counter 用于统计输出的行数。
# 使用 for 循环遍历查询结果 rows,打印每一行的数据,并通过 row_counter 统计行数。
row_counter = 0
for row in rows:
	print(row)
	row_counter += 1

# 打印总行数,格式化输出结果。
print('Number of rows: {}'.format(row_counter))

import csv
import sqlite3
import sys

# CSV输入文件的路径和名称
input_file = sys.argv[1]

# 创建一个内存中的SQLite3数据库
# 创建一个名为Suppliers的表,包含五个属性
con = sqlite3.connect('Suppliers.db')
c = con.cursor()
create_table = """CREATE TABLE IF NOT EXISTS Suppliers
                (Supplier_Name VARCHAR(20),
                Invoice_Number VARCHAR(20),
                Part_Number VARCHAR(20),
                Cost FLOAT,
                Purchase_Date DATE);"""
c.execute(create_table)
con.commit()

# 读取CSV文件
# 将数据插入Suppliers表中
file_reader = csv.reader(open(input_file, 'r'), delimiter=',')
header = next(file_reader, None)
for row in file_reader:
    data = []
    for column_index in range(len(header)):
        data.append(row[column_index])
    print(data)
    c.execute("INSERT INTO Suppliers VALUES (?, ?, ?, ?, ?);", data)
con.commit()

# 查询Suppliers表
output = c.execute("SELECT * FROM Suppliers")
rows = output.fetchall()
for row in rows:
    output = []
    for column_index in range(len(row)):
        output.append(str(row[column_index]))
    print(output)
import csv
import sqlite3
import sys

# 输入文件的路径和名称
input_file = sys.argv[1]

# 创建一个内存中的 SQLite3 数据库
# 创建一个名为 sales 的表,包含四个属性
con = sqlite3.connect(':memory:')
query = """CREATE TABLE IF NOT EXISTS sales
			(customer VARCHAR(20), 
				product VARCHAR(40),
				amount FLOAT,
				date DATE);"""
con.execute(query)
con.commit()

# 向表中插入几行数据
data = [('Richard Lucas', 'Notepad', 2.50, '2014-01-02'),
		('Jenny Kim', 'Binder', 4.15, '2014-01-15'),
		('Svetlana Crow', 'Printer', 155.75, '2014-02-03'),
		('Stephen Randolph', 'Computer', 679.40, '2014-02-20')]
for tuple in data:
	print(tuple)
statement = "INSERT INTO sales VALUES(?, ?, ?, ?)"
con.executemany(statement, data)
con.commit()
	
# 读取 CSV 文件并更新特定行的数据
file_reader = csv.reader(open(input_file, 'r'), delimiter=',')
header = next(file_reader, None)
for row in file_reader:
	data = []
	for column_index in range(len(header)):
		data.append(row[column_index])
	print(data)
	con.execute("UPDATE sales SET amount=?, date=? WHERE customer=?;", data)
con.commit()

# 查询 sales 表中的数据
cursor = con.execute("SELECT * FROM sales")
rows = cursor.fetchall()
for row in rows:
	output = []
	for column_index in range(len(row)):
		output.append(str(row[column_index]))
	print(output)

import csv
import MySQLdb
import sys
from datetime import datetime, date

# CSV输入文件的路径和名称
input_file = sys.argv[1]

# 连接MySQL数据库
con = MySQLdb.connect(host='localhost', port=3306, db='my_suppliers', user='user20230806', passwd='user20230806')
c = con.cursor()

# 读取CSV文件
# 将数据插入Suppliers表中
file_reader = csv.reader(open(input_file, 'r'), delimiter=',')
header = next(file_reader)
for row in file_reader:
    data = []
    for column_index in range(len(header)):
        if column_index < 4:
            data.append(str(row[column_index]).lstrip('$').replace(',', '').strip())
        else:
            a_date = date.strftime(datetime.strptime(str(row[column_index]), '%m/%d/%y'), '%Y-%m-%d')
            data.append(a_date)
    print(data)
    c.execute("""INSERT INTO Suppliers VALUES (%s, %s, %s, %s, %s);""", data)
con.commit()

# 查询Suppliers表
c.execute("SELECT * FROM Suppliers")
rows = c.fetchall()
for row in rows:
    row_list_output = []
    for column_index in range(len(row)):
        row_list_output.append(str(row[column_index]))
    print(row_list_output)
python .\4db_mysql_load_from_csv.py .\supplier_data.csv
import csv
import MySQLdb
import sys

# CSV输出文件的路径和名称
output_file = sys.argv[1]

# 连接MySQL数据库
con = MySQLdb.connect(host='localhost', port=3306, db='my_suppliers', user='user20230806', passwd='user20230806')
c = con.cursor()

# 创建文件写入对象并写入标题行
filewriter = csv.writer(open(output_file, 'w', newline=''), delimiter=',')
header = ['Supplier Name', 'Invoice Number', 'Part Number', 'Cost', 'Purchase Date']
filewriter.writerow(header)

# 查询Suppliers表并将结果写入CSV文件
c.execute("""SELECT * 
		FROM Suppliers 
		WHERE Cost > 700.0;""")

rows = c.fetchall()
for row in rows:
	filewriter.writerow(row)
python .\5db_mysql_write_to_file.py .\db_select_output_files\5output.csv
import csv
import MySQLdb
import sys

# CSV输入文件的路径和名称
input_file = sys.argv[1]

# 连接MySQL数据库
con = MySQLdb.connect(host='localhost', port=3306, db='my_suppliers', user='user20230806', passwd='user20230806')
c = con.cursor()

# 读取CSV文件并更新特定行
file_reader = csv.reader(open(input_file, 'r', newline=''), delimiter=',')
header = next(file_reader, None)
for row in file_reader:
    data = []
    for column_index in range(len(header)):
        data.append(str(row[column_index]).strip())
    print(data)
    c.execute("""UPDATE Suppliers SET Cost=%s, Purchase_Date=%s WHERE Supplier_Name=%s;""", data)
con.commit()

# 查询Suppliers表
c.execute("SELECT * FROM Suppliers")
rows = c.fetchall()
for row in rows:
    output = []
    for column_index in range(len(row)):
        output.append(str(row[column_index]))
    print(output)
python .\6db_mysql_update_from_csv.py .\data_for_updating_mysql.csv

应用程序

import csv
import glob
import os
import sys
from datetime import date
from xlrd import open_workbook, xldate_as_tuple

# 从命令行参数获取输入文件、文件夹路径和输出文件
item_numbers_file = sys.argv[1]
path_to_folder = sys.argv[2]
output_file = sys.argv[3]

# 存储要查找的物品编号
item_numbers_to_find = []
with open(item_numbers_file, 'r', newline='') as item_numbers_csv_file:
    filereader = csv.reader(item_numbers_csv_file)
    for row in filereader:
        item_numbers_to_find.append(row[0])
print(item_numbers_to_find)

# 创建文件写入对象
filewriter = csv.writer(open(output_file, 'a', newline=''))

file_counter = 0
line_counter = 0
count_of_item_numbers = 0

# 遍历文件夹中的文件
for input_file in glob.glob(os.path.join(path_to_folder, '*.*')):
    file_counter += 1

    # 处理CSV文件
    if input_file.split('.')[1] == 'csv':
        with open(input_file, 'r', newline='') as csv_in_file:
            filereader = csv.reader(csv_in_file)
            header = next(filereader)  # 读取CSV文件的首行作为标题
            for row in filereader:
                row_of_output = []
                for column in range(len(header)):
                    if column < 3:
                        cell_value = str(row[column]).strip()  # 去除字符串两侧的空白字符
                        row_of_output.append(cell_value)
                    elif column == 3:
                        cell_value = str(row[column]).lstrip('$').replace(',', '').split('.')[0].strip()
                        # 删除字符串开头的'$'符号,去除逗号并只保留整数部分
                        row_of_output.append(cell_value)
                    else:
                        cell_value = str(row[column]).strip()
                        row_of_output.append(cell_value)
                row_of_output.append(os.path.basename(input_file))  # 添加文件名作为额外的列
                if row[0] in item_numbers_to_find:  # 如果行中的物品编号存在于要查找的列表中
                    filewriter.writerow(row_of_output)  # 将行写入输出文件
                    count_of_item_numbers += 1
                line_counter += 1

    # 处理Excel文件
    elif input_file.split('.')[1] == 'xls' or input_file.split('.')[1] == 'xlsx':
        workbook = open_workbook(input_file)
        for worksheet in workbook.sheets():
            try:
                header = worksheet.row_values(0)  # 读取Excel工作表的首行作为标题
            except IndexError:
                pass
            for row in range(1, worksheet.nrows):
                row_of_output = []
                for column in range(len(header)):
                    if column < 3:
                        cell_value = str(worksheet.cell_value(row, column)).strip()
                        row_of_output.append(cell_value)
                    elif column == 3:
                        cell_value = str(worksheet.cell_value(row, column)).split('.')[0].strip()
                        row_of_output.append(cell_value)
                    else:
                        cell_value = xldate_as_tuple(worksheet.cell(row, column).value, workbook.datemode)
                        cell_value = str(date(*cell_value[0:3])).strip()
                        row_of_output.append(cell_value)
                row_of_output.append(os.path.basename(input_file))  # 添加文件名作为额外的列
                row_of_output.append(worksheet.name)  # 添加工作表名作为额外的列
                if str(worksheet.cell(row, 0).value).split('.')[0].strip() in item_numbers_to_find:
                    # 如果单元格中的物品编号存在于要查找的列表中
                    filewriter.writerow(row_of_output)  # 将行写入输出文件
                    count_of_item_numbers += 1
                line_counter += 1

# 打印统计信息
print('Number of files: {}'.format(file_counter))
print('Number of lines: {}'.format(line_counter))
print('Number of item numbers: {}'.format(count_of_item_numbers))
import csv
import sys
from datetime import date, datetime

# 定义日期差异计算函数
def date_diff(date1, date2):
	try:
		diff = str(datetime.strptime(date1, '%m/%d/%Y') - \
				datetime.strptime(date2, '%m/%d/%Y')).split()[0]
	except:
		diff = 0
	if diff == '0:00:00':
		diff = 0
	return diff
	
# 从命令行参数获取输入文件和输出文件
input_file = sys.argv[1]
output_file = sys.argv[2]

# 存储包裹信息的字典
packages = {}
previous_name = 'N/A'
previous_package = 'N/A'
previous_package_date = 'N/A'
first_row = True
today = date.today().strftime('%m/%d/%Y')

# 读取输入文件并处理数据
with open(input_file, 'r', newline='') as input_csv_file:
	filereader = csv.reader(input_csv_file)
	header = next(filereader)  # 读取CSV文件的首行作为标题
	for row in filereader:
		current_name = row[0]
		current_package = row[1]
		current_package_date = row[3]
        '''
        核心代码
        '''
		if current_name not in packages:
			packages[current_name] = {}
		if current_package not in packages[current_name]:
			packages[current_name][current_package] = 0
		if current_name != previous_name:
			if first_row:
				first_row = False
			else:
				diff = date_diff(today, previous_package_date)  # 计算日期差异
				if previous_package not in packages[previous_name]:
					packages[previous_name][previous_package] = int(diff)
				else:
					packages[previous_name][previous_package] += int(diff)
		else:
			diff = date_diff(current_package_date, previous_package_date)  # 计算日期差异
			packages[previous_name][previous_package] += int(diff)
		previous_name = current_name
		previous_package = current_package
		previous_package_date = current_package_date

# 写入输出文件
header = ['Customer Name', 'Category', 'Total Time (in Days)']
with open(output_file, 'w', newline='') as output_csv_file:
	filewriter = csv.writer(output_csv_file)
	filewriter.writerow(header)  # 写入标题行
	for customer_name, customer_name_value in packages.items():
		for package_category, package_category_value in packages[customer_name].items():
			row_of_output = []
			row_of_output.append(customer_name)
			row_of_output.append(package_category)
			row_of_output.append(package_category_value)
			filewriter.writerow(row_of_output)  # 写入数据行
import sys

# 从命令行参数获取输入文件和输出文件
input_file = sys.argv[1]
output_file = sys.argv[2]

messages = {}  # 存储消息的字典
notes = []  # 存储所有的笔记

with open(input_file, 'r', newline='') as text_file:
	for row in text_file:
		if '[Note]' in row:  # 检查行中是否包含'[Note]'
			row_list = row.split(' ', 4)  # 将行按空格分割为列表
			day = row_list[0].strip()  # 提取日期,去除首尾空格
			note = row_list[4].strip('\n').strip()  # 提取笔记内容,去除换行符和首尾空格
			if note not in notes:
				notes.append(note)  # 将笔记添加到笔记列表中
			if day not in messages:
				messages[day] = {}  # 创建日期对应的字典
			if note not in messages[day]:
				messages[day][note] = 1  # 将笔记在日期字典中计数为1
			else:
				messages[day][note] += 1  # 笔记在日期字典中计数加1

filewriter = open(output_file, 'w', newline='')
header = ['Date']
header.extend(notes)  # 将笔记列表添加到标题行
header = ','.join(map(str, header)) + '\n'
print(header)
filewriter.write(header)

for day, day_value in messages.items():
	row_of_output = []
	row_of_output.append(day)
	for index in range(len(notes)):
		if notes[index] in day_value.keys():
			row_of_output.append(day_value[notes[index]])  # 如果笔记在日期字典中存在,则将计数值添加到输出行中
		else:
			row_of_output.append(0)  # 否则将0添加到输出行中
	output = ','.join(map(str, row_of_output)) + '\n'
	print(output)
	filewriter.write(output)

filewriter.close()

按计划自动运行脚本

windows 10 如何设定计划任务自动执行 python 脚本?

posted @ 2023-08-06 14:46  LateSpring  阅读(13)  评论(0编辑  收藏  举报