写在前面:刚开始自学python没多久,本来学习爬虫,因为作业的原因现在开始学习数据分析,基础很浅。下面的内容是摘自书本的笔记以及一些个人感悟和遇到的一些问题。有不对的地方大家一定提出来,谢谢。PS:使用pycharm
第一章——Python基础
笔记:
- print 语句中的语法 “{0:d}”.format(z) 。花括号( {} )是一个占位符,表示这里将要 传入 print 语句一个具体的值,这里就是变量 z 的值。 0 指向 format() 方法中的第一个参 数, 在这里, 只包含一个参数 z , 所以 0 就指向这个值;相反, 如果有多个参数, 0 就确 定地表示传入第一个参数。
冒号( : )用来分隔传入的值和它的格式。 d 表示这个值应该被格式化为整数,没有小数部 分。
为什么要使用.format,,用占位符得到用逗号分隔的变量的值,如果不用占位符要自己打逗号才会分开 - 几位小数:
print ("Output #7: {0:.3f}".format(8.3/2.7))
#.3f设定了打印的输出值应该有3位小数
- type函数:获得对象的类
- math模块中的函数:exp、log、sqrt,分别表示e的乘方、自然对数、平方根,需要导入才能使用
- 字符串:
- 多行的时候可以使用:
1.反斜杠 (容易出错)
2.3个单/双引号 - “+ * len",分别是拼接,重复拼接,计算长度
- split():拆分成列表,默认使用空格拆分。
- join():合成一个字符串,用连接的参数调用,如" ‘,’.join(a)"
- strip():去除字符串两端不想要的字符。还有lstrip(),rstrip(),多个参数直接写在一起,如:s.strip(’$_-+’)
- replace():替代
- lower、upper、capitalize:首字母大写capitalize
- 正则表达式:import re
- 列表:
- len():计算元素数量
- max()、min()最大值最小值
- count():计算某元素出现次数
- 索引值:[-1]倒数第一个,[-2]倒数第二个
- 切片:list[0:2],得到第一第二个组成的新列表
- 复制:
list1 = list2[:]
- 连接:+
- in和not in:
if a in list: #返回的是布尔值
- 追加、删除、弹出:append()向列表末尾追加一个新元素,remove()从列表中删除一个特定元素,pop()从列表末尾删除一个元素 a_list.append(4)
- 反转: reverse(),注意他是原地反转,改变了自己
- 排序:sort(),原地排序
- sorted:太长了,忽略
- 元组
- 字典
- 简化for循环:列表、集合、字典生成式:P32
# 使用列表生成式选择特定的行
my_data = [[1,2,3], [4,5,6], [7,8,9]]
rows_to_keep = [row for row in my_data if row[2] > 5]
print ("Output #130 (list comprehension): {}".format(rows_to_keep))
- 函数:使用 Google 或 Bing 来搜索“< 你需要的功 能描述 > Python function”可以帮助你找到想要的 Python 函数。
- 读取文件
with open(file,"r",newline='') as filereader:
- 读取多个文件:glob和os
- write 方法可将单个 字符串写入一个文件, writelines 方法可将一系列字符串写入一个文件。
- range:形成数字列表?
第二章
- 读写CSV文件
- 基础实现,不使用csv模块:
# __author: HY
# date: 2019/4/8
import sys
input_file = "供应商数据.csv"
output_file = "输出.csv"
# newline是换行标志
with open(input_file, "r", newline='') as filereader:
with open(output_file, "w", newline='') as filewriter:
header = filereader.readline()
header = header.strip()
header_list = header.split(',')
print(header_list)
filewriter.write(','.join(map(str, header_list)) + '\n')
# 前面经过一个readline()后指针在实际的第一行数据后面了,后面输出的就是实际数据了
for row in filereader:
row = row.strip()
row_list = row.split(',')
print(row_list)
filewriter.write(','.join(map(str, row_list)) + '\n')
# 因为数据里有逗号,所以拆分失败
- pandas实现
# __author: HY
# date: 2019/4/9
import pandas as pd
input_file = "供应商数据.csv"
output_file = "pandas输出.csv"
# python 导入数据错误:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb5 in position 0: invalid start
# 编码问题,在参数那里加上encoding='gbk'就行了,至于为什么换成gbk就行了就不知道了
data_frame = pd.read_csv(input_file, encoding='gbk')
print(data_frame)
data_frame.to_csv(output_file)
- 使用csv模块
# __author: HY
# date: 2019/4/9
import csv
input_file = "供应商数据.csv"
output_file = "csv输出.csv"
with open(input_file, "r", newline='') as csv_in_file:
with open(output_file, "w", newline='') as csv_out_file:
# filereader是一个对象<_csv.reader object at 0x000001C6A180E1E8>
filereader = csv.reader(csv_in_file, delimiter=',')
filewriter = csv.writer(csv_out_file, delimiter=',')
for row_list in filereader:
print(row_list)
filewriter.writerow(row_list)
- 筛选特定行:
- 行中的值满足某个条件
- 行中的值属于某个集合
- 行中的值匹配于某个模式(正则表达式)
行中的值满足某个条件,基础python
# __author: HY
# date: 2019/4/9
import csv
input_file = "供应商数据.csv"
output_file = "筛选-基础python.csv"
with open(input_file, "r", newline='') as csv_in_file:
with open(output_file, "w", newline='') as csv_out_file:
filereader = csv.reader(csv_in_file, delimiter=',')
filewriter = csv.writer(csv_out_file, delimiter=',')
header = next(filereader)
filewriter.writerow(header)
for row_list in filereader:
supplier = str(row_list[0]).strip()
cost = str(row_list[3]).strip('$').replace(',', '')
if supplier == '供应商 Z' or float(cost) >600.0:
filewriter.writerow(row_list)
pandas实现:
报错:could not convert string to float: '5,000 ’
没有去除逗号的原因,加上去除逗号即可
# __author: HY
# date: 2019/4/10
import pandas as pd
input_file = "供应商数据.csv"
output_file = "筛选-pandas.csv"
data_frame = pd.read_csv(input_file, encoding='gbk')
# could not convert string to float: '5,000 '
# 没有去除逗号的原因,加上去除逗号即可
data_frame['成本'] = data_frame['成本'].str.strip('$').str.replace(',', '').astype(float)
# :代表取所有列
data_frame_value_meets_condition = data_frame.loc[(data_frame['供应商名称']\
.str.contains('Z')) | (data_frame['成本'] > 600.0), :]
data_frame_value_meets_condition.to_csv(output_file, index=False)
行中的值属于某个集合
基础python:
# __author: HY
# date: 2019/4/10
import csv
input_file = "供应商数据.csv"
output_file = "行值属于集合-基础python.csv"
important_datas = ['1/20/2014', '1/30/2014']
with open(input_file, 'r', newline='') as csv_in_file:
with open(output_file, "w", newline='') as csv_out_file:
filereader = csv.reader(csv_in_file)
filewriter = csv.writer(csv_out_file)
header = next(filereader)
filewriter.writerow(header)
for row_list in filereader:
a_date = row_list[4]
if a_date in important_datas:
filewriter.writerow(row_list)
pandas实现:
# __author: HY
# date: 2019/4/10
import pandas as pd
input_file = "供应商数据.csv"
output_file = "行值属于集合-pandas.csv"
# 编码问题,在参数那里加上encoding='gbk'就行了,至于为什么换成gbk就行了就不知道了
data_frame = pd.read_csv(input_file, encoding='gbk')
important_datas = ['1/20/2014', '1/30/2014']
# loc函数同时筛选行和列,逗号后面的:表示所有列
data_frame_value_in_set = data_frame.loc[data_frame['购买日期'].isin(important_datas), :]
print(data_frame_value_in_set)
# 输出到文件中的值是否有索引,默认index是真
data_frame_value_in_set.to_csv(output_file, index=False)
第二章代码太多了,后面的不打了。。。
第二章:CSV
第三章:Excel
不同:
Excel 文件与 CSV 文件至少在两个重要方面有所不同。
- 首先,与 CSV 文 件不同, Excel 文件不是纯文本文件,所以你不能在文本编辑器中打开它并查看数据。为 了验证这一点,可以点击刚才创建的 Excel 工作簿并按鼠标右键,然后用一个文本编辑器 (比如 Notepad 或者 TextWrangler)打开它。 你会看到一堆乱码,而不是正常字符。
- 其次,与 CSV 文件不同,一个 Excel 工作簿被设计成包含多个工作表,所以你需要知道在 不用手动打开工作簿的前提下,如何通过工作簿内省(也就是内部检查)获取其中所有工 作表的信息。通过内省一个工作簿,你可以在实际开始处理工作簿中的数据之前,检查工 作表的数目和每个工作表中的数据类型和数据量。
内省 Excel 文件有助于确定文件中的数据确实是你需要的,并对数据一致性和完整性做一 个初步检查。也就是说,弄清楚输入文件的数量,以及每个文件中的行数和列数,可以使 你对数据处理工作的工作量和文件内容的一致性有个大致的概念。
在知道了如何内省工作簿中的工作表之后,下面开始分析单个工作表,然后处理多个工作 表和多个工作簿。
第四章
pycharm导入mysqlclient遇到了很大的问题
error: command ‘C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\HostX64\x64\cl.exe’ failed with exit status 2
最后我是在这个网站上下载对应模块:(.whl文件)
https://www.lfd.uci.edu/~gohlke/pythonlibs/ 然后在命令行安装
在pycharm里还是用不了的,要导入:
pycharm内无法import已安装的模块
cl.exed的问题:
python windows 解决 cl.exe 的问题
- 前前后后折腾了快一整天,经历了绝望、惊喜、落空、无奈,最后成功的时刻反而很平静。
*PS:我是本来就装了VS的,网上有人说跟这个有关系,我也不太清楚。- 顺便把这个过程中对python的理解说一下:
- 安装了python和pycharm其实是有重复了的,pycharm里内置了python
D:\Program Files\Python35\Lib\site-packages下是命令行所导入的模块,而pycharm里我的项目导入的模块则是D:\Program Files\PyCharm Community Edition 2018.3.5\MyProject\Practice\venv\Lib\site-packages- 直接把模块拖过去是用不了的,要安装(不知道怎么装),但它可以显示出来,所以需要用上面导入的方法
连接数据库的时候报错:
UnicodeEncodeError: ‘latin-1’ codec can’t encode characters in position 0-2: ordinal not in range(256)
编码的问题:
con = MySQLdb.connect(host='localhost', port=3307, db='my_suppliers',
user='clinton', passwd='secret_password', charset="gbk")
# 这里遇到编码问题,加上 charset="gbk"就可以,utf8,也可以,不能是utf-8。
编译通过了,输出正常,但可能是我数据库编码设置有什么问题,在命令行显示的还是乱码,而在图形界面显示正常。
解决:改变结果的编码即可set character_set_results=gb2312;
第五章
前面第三章处理excel文件没怎么看,对处理excel部分的代码有点陌生
总结一下在这个项目中它们操作的区别:
- 日期:excel中类型为3的数据,即包含日期的数据需要处理。worksheet.cell_type(row, column) == 3.CSV中数据都是纯文本,所以不用管
if worksheet.cell_type(row, column) == 3:
cell_value = \
xldate_as_tuple(worksheet.cell(row, column).value, workbook.datemode)
# 0-3是取前三个元素(年月日)
cell_value = str(date(*cell_value[0:3])).strip()
row_of_output.append(cell_value)
- 金钱:excel的数据不用处理,而csv需要去掉¥和空格
- 工作簿:excel里一个工作簿含有多个工作表
- 读取单元格:worksheet的cell_value函数和行列索引引用单元格的值,而csv像列表处理即可
if str(worksheet.cell(row, 0).value).split('.')[0].strip() in item_numbers_to_find:
filewriter.writerow(row_of_output)
- 在一个大文件集合中查找一组项目:
# __author: HY
# date: 2019/4/13
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_file = 'item_numbers_to_find.csv'
path_to_folder = 'file_archive'
output_file = '1app_output.csv'
# 要搜索的数值项目的文件取值,放在列表中
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, '*.*')):
# 找到一个文件则加1
file_counter += 1
# 处理csv文件。split路径名按.分割
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)
for row in filereader:
row_of_output = []
for column in range(len(header)):
# 共5列,第三列是金钱
if column == 3:
cell_value = str(row[column]).lstrip('$'). \
replace(',', '').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
workbook = open_workbook(input_file)
# 获取每个工作表标题行
for worksheet in workbook.sheets():
try:
header = worksheet.row_values(0)
except IndexError:
pass
# 跳过标题行并开始循环
for row in range(1, worksheet.nrows):
row_of_output = []
for column in range(len(header)):
# 类型为3的数据,即包含日期的数据。CSV中数据都是纯文本,所以不用管
# worksheet的cell_value函数和行列索引引用单元格的值
if worksheet.cell_type(row, column) == 3:
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)
else:
cell_value = str(worksheet.cell_value(row, column)).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:', file_counter)
print('Number of lines:', line_counter)
print('Number of item numbers:', count_of_item_numbers)
- 为CSV文件中数据的任意数目分类计算统计量:
- 字典是无序的,输出不是按照输入文件的顺序了。
- 大范围使用变量设在最前面比较好,程序更加明了
# 这个不是我自己打的,是复制书上的源码
#!/usr/bin/env python3
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
# 两个日期相等差值为0,会格式化成0:00:00
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)
for row in filereader:
current_name = row[0]
current_package = row[1]
current_package_date = row[3]
# current_name外部字典的键
if current_name not in packages:
packages[current_name] = {}
# current_package内部字典的键
if current_package not in packages[current_name]:
packages[current_name][current_package] = 0 # 先设为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 = []
print(customer_name, package_category, package_category_value)
row_of_output.append(customer_name)
row_of_output.append(package_category)
row_of_output.append(package_category_value)
filewriter.writerow(row_of_output)
- 为文本文件中数据的任意数目分类计算统计量:
- python3中,map返回的不是一个列表,而是一个对象,使用join函数后得到一个字符串。这里用map处理了数据,因为上面计数的数据是int而csv中只能是字符串,所以和前面案例的处理方式不同。
- 计数的数据是int而csv中只能是字符串,所以记得要转换
- extend和append区别:前者将一个序列(列表)加入,后者仅是将一个对象加入
- 看案例或者以后自己作业,都应该先清楚自己要输出的格式是怎样的,在此基础上再进行学习或者设计
# 复制书上的代码
#!/usr/bin/env python3
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:
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
else:
messages[day][note] += 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)
output = ','.join(map(str,row_of_output)) + '\n'
print(output)
filewriter.write(output)
filewriter.close()
第六章——图与图表
在195出现了下面的报错:
No module named ‘patsy’
是与matplotlib相关的模块,想直接安装又失败了,只好用之前whl文件的方法。
下载地址:http://www.lfd.uci.edu/~gohlke/pythonlibs/#patsy 下载后在命令提示用pip install 文件名.whl(忘记文件名是什么了)
然后这个坎运行通过了,但又出现下一个问题
module ‘seaborn’ has no attribute ‘axlabel’
第七章
这章我主要去尝试做了葡萄酒质量的案例,问题很多。
一点一点去折腾花了好多时间。
已经忘记遇到过什么问题了
八九章
后面的内容是开拓性的。至此终于看完这本书了,不能说融会贯通,但是对数据分析已经有了基本了解,再接再厉!