写在前面:刚开始自学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. 多行的时候可以使用:
    1.反斜杠 (容易出错)
    2.3个单/双引号
  2. “+ * len",分别是拼接,重复拼接,计算长度
  3. split():拆分成列表,默认使用空格拆分。
  4. join():合成一个字符串,用连接的参数调用,如" ‘,’.join(a)"
  5. strip():去除字符串两端不想要的字符。还有lstrip(),rstrip(),多个参数直接写在一起,如:s.strip(’$_-+’)
  6. replace():替代
  7. lower、upper、capitalize:首字母大写capitalize
  • 正则表达式:import re
  • 列表:
  1. len():计算元素数量
  2. max()、min()最大值最小值
  3. count():计算某元素出现次数
  4. 索引值:[-1]倒数第一个,[-2]倒数第二个
  5. 切片:list[0:2],得到第一第二个组成的新列表
  6. 复制:list1 = list2[:]
  7. 连接:+
  8. in和not in:if a in list: #返回的是布尔值
  9. 追加、删除、弹出:append()向列表末尾追加一个新元素,remove()从列表中删除一个特定元素,pop()从列表末尾删除一个元素 a_list.append(4)
  10. 反转: reverse(),注意他是原地反转,改变了自己
  11. 排序:sort(),原地排序
  12. 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文件
  1. 基础实现,不使用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')
# 因为数据里有逗号,所以拆分失败
  1. 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)
  1. 使用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)
  • 筛选特定行:
  1. 行中的值满足某个条件
  2. 行中的值属于某个集合
  3. 行中的值匹配于某个模式(正则表达式)

行中的值满足某个条件,基础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 文件至少在两个重要方面有所不同。

  1. 首先,与 CSV 文 件不同, Excel 文件不是纯文本文件,所以你不能在文本编辑器中打开它并查看数据。为 了验证这一点,可以点击刚才创建的 Excel 工作簿并按鼠标右键,然后用一个文本编辑器 (比如 Notepad 或者 TextWrangler)打开它。 你会看到一堆乱码,而不是正常字符。
  2. 其次,与 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/ 然后在命令行安装

python 0表示是还是否 python中{0:}_数据

在pycharm里还是用不了的,要导入:
pycharm内无法import已安装的模块

cl.exed的问题:
python windows 解决 cl.exe 的问题

  • 前前后后折腾了快一整天,经历了绝望、惊喜、落空、无奈,最后成功的时刻反而很平静。
    *PS:我是本来就装了VS的,网上有人说跟这个有关系,我也不太清楚。
  • 顺便把这个过程中对python的理解说一下:
  1. 安装了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
  2. 直接把模块拖过去是用不了的,要安装(不知道怎么装),但它可以显示出来,所以需要用上面导入的方法

连接数据库的时候报错:

UnicodeEncodeError: ‘latin-1’ codec can’t encode characters in position 0-2: ordinal not in range(256)

python 0表示是还是否 python中{0:}_CSV_02

编码的问题:

con = MySQLdb.connect(host='localhost', port=3307, db='my_suppliers',
                      user='clinton', passwd='secret_password', charset="gbk")
# 这里遇到编码问题,加上 charset="gbk"就可以,utf8,也可以,不能是utf-8。

编译通过了,输出正常,但可能是我数据库编码设置有什么问题,在命令行显示的还是乱码,而在图形界面显示正常。

python 0表示是还是否 python中{0:}_CSV_03


python 0表示是还是否 python中{0:}_python 0表示是还是否_04

解决:改变结果的编码即可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文件中数据的任意数目分类计算统计量:
  1. 字典是无序的,输出不是按照输入文件的顺序了。
  2. 大范围使用变量设在最前面比较好,程序更加明了
# 这个不是我自己打的,是复制书上的源码
#!/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)
  • 为文本文件中数据的任意数目分类计算统计量:
  1. python3中,map返回的不是一个列表,而是一个对象,使用join函数后得到一个字符串。这里用map处理了数据,因为上面计数的数据是int而csv中只能是字符串,所以和前面案例的处理方式不同。
  2. 计数的数据是int而csv中只能是字符串,所以记得要转换
  3. extend和append区别:前者将一个序列(列表)加入,后者仅是将一个对象加入
  4. 看案例或者以后自己作业,都应该先清楚自己要输出的格式是怎样的,在此基础上再进行学习或者设计
# 复制书上的代码

#!/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’

第七章

这章我主要去尝试做了葡萄酒质量的案例,问题很多。
一点一点去折腾花了好多时间。
已经忘记遇到过什么问题了

八九章

后面的内容是开拓性的。至此终于看完这本书了,不能说融会贯通,但是对数据分析已经有了基本了解,再接再厉!