前言
这篇笔记的主要参考书是《Python数据分析基础》([美] 克林顿·布朗利(Clinton,W.,Brownley) 著,陈光欣 译),封面如下:
作者在Github上已经放了书中的源代码与数据文件。
sys.argv[]
函数
sys.argv[]
是用来获取命令行输入的参数的,argv
的是argument variable
的缩写。这个变量其实是一个List列表,其中参数和参数之间空格区分,sys.argv[0]
表示代码本身文件路径,而sys.argv[1]
表示获取的参数。现在看使用案例。
首选我们在桌面上新建一个test.py
文件,输入内容如下所示:
|
|
现在运行这段代码,如下所示:
|
|
从上面的结果可以看出来,运行test.py
文件返回了一个test.py
字符,这是因为sys.argv[0]
这个参数本身指的就是这个程序本身,这个程序就是test.py
文件。现在更改一下test.py
代码,将第2行的result = sys.argv[0]
改为result = sys.argv[1:]
,如下所示:
|
|
再次运行,如下所示:
|
|
从上面看到,当我们输入python test.py Hello, Python
时(请注意,Hello,
与Python
之间有一个空格),sys.argv[1:]
就会接收输入的参数,并且以空格来进行区分,当用空格进行区分,这就是2个参数,这个列表中就有2个参数。当我们直接输入Hello,python
(中间没有空格)时,就是一个参数,这个列表中就只有一个元素。
使用sys.argv[]
来读取文件的代码如下所示:
在桌面上新建一个文本文档test_text
,再新建一个test.py
Python文件,如下所示:
|
|
运行结果如下所示:
|
|
还有一种代码,就是使用with
,如下所示:
|
|
读取多个文本文件glob
在实际应用过程中,有可能要同时读取多个文件。读取多个文件的实现方式之一就是在命令行中将包含输入文件目录的路径名写在Python脚本之后,如果要使用这种方法,就需要os
模块与glob
模块,那么完整的代码如下所示,这段代码位于桌面,命令为directory_test.py
,代码如下所示:
|
|
使用os
模块可以使用其提供的与路径相关的函数,例如os.path.join
函数可以将一个或多个路径成分连接在一起,在上面的代码中,
glob
模块可以找出与特定模式相匹配的所有路径名。它可以将某目录下面跟通配符模式相同的文件放到一个列表中,有了这个函数中,我们想于生成所有文件的列表就不需要使用for循环遍历目录了,而是直接使用glob.glob(path + pattern)
的方式进行获取,可以看一下面的案例:
|
|
这段代码表示的内容就是,搜索当前目录下的所有.py
文件,并显示出来。
另外一个类似的函数则是iglob
,此函数则是一次只检索一个文件,如下所示:
|
|
os
模块和glob
模块组合在一起可以找出符合特定模式的某个文件夹下的所有文件。在这段代码的for
循环中使用了os.path.join
函数和glob.glob
函数来找出符合特定模式的某个文件夹下面的所有文件。指向这个文件夹的路径包含在变量input_file
中,这个变量需要在命令行中提供。os.path.join
函数将这个文件夹路径和这个文件夹中所有符合特定模式的文件名连接起来,这种特定模式可以由glob.glob
函数扩展。
这段代码使用是的模式*.txt
来匹配由.txt
结尾的所有文件名。
现在来演示一下这个案例。
在桌面上新建一个文件夹,命令为test_directory
,在此目录下新建一个文本文件,命名为test_1.txt
,输入以下内容:
|
|
在此目录新建第二个文本文件,命名为test_2.txt
,输入以下内容:
|
|
现在运行directory_test.py
代码,如下所示:
|
|
读取csv
文件
csv
文件的全称为comma-separated value
,即逗号分隔值
,这是一种常用的数据存储格式。在Python中专门的csv
模块,但这里先用最原始的python代码来实现一下。
非csv模块读取csv文件
在桌面上新建一个名为read_csv.py
的Python文件,输入以下代码:
|
|
在桌面上新建一个test_csv.csv
文件,输入以下内容:
|
|
运行结果如下所示:
|
|
现在桌面上就有了一个输出文件,名称为test_out.csv
。
使用pandas
模块读取csv文件
pandas
是一个开源的,BSD许可的库,为Python编程语言提供高性能,易于使用的数据结构和数据分析工具。pandas可以用于读取csv文件,在下面的这段代码中,会读取csv文件,然后输出读取的内容,在桌上上新建pandas_test.py
文件,代码如下所示:
|
|
运行结果如下所示:
|
|
此时在桌面上生成一个叫pandas_test.csv
的文件。
使用csv模块读取csv文件
python内置的csv
模块可以读取csv文件,现在在桌上新建一个名为csv_module.py
的文件,代码如下所示:
|
|
现在运行一下这个文件,如下所示:
|
|
现在在桌上上生成了一个名为csv_module_test.csv
的csv文件。
读取特定的行
数据处理过程中通常会有一项操作是要把满足某个条件的某行数据给挑出来,通常有这几种方法:
- 行中的值满足某个条件;
- 行中的值属于某个集合
- 行中的值匹配于某个模式(正则表达式)
满足某条件行的通用代码结构
现在看一下以下的这段虚拟代码:
|
|
这段代码描述的是在输入文件中筛选出特定行的通用代码结构。
在平时写代码过程中只需要修改***
中的代码,以使脚本满足具体需要即可。
行中的值满足某个条件
有数据分析的实现情况中,有的时候有这种需要:当行中的值满足一个具体条件时需要保留些行。例如,我们可能希望在数据集中保留那些成本高于某个阈值的行,或者希望保留所有购买日期在一个具体日期之前的行。
在这种情况下,我们就可以检验行中的值是否满足具体的条件,然后筛选出满足条件的行。现在我们来描述这么一个案例:
保留某个供应商名字为Suuplier Z
的行,或者是成本大于600的行,并将结果写入某个文件中。
使用csv
模块某列-索引方法
在csv文中选取特定列的一种方法就是使用列的索引值来提取。例如,如果想提取数据的第1列和最后1列,就使用row[0]
和row[-1]
来提取。
在下面的这个案例中,我们只想提取供应商姓名和成本这两列,就要使用索引值来聚会这两列。
现在我们在桌面上新建一个名为select_meets_condition.py
的文件,输入以下代码:
|
|
现在新建一个csv文件,这个文件就是我们要使用数据文件,把它命名为supplier_data_unnecessary_header_footer
,内容如下所示:
|
|
用Excel打开就是下面的这个样子:
现在解释一下源代码:
- 在代码中我们使用了
my_columns = [0, 3]
这个变量,0与3就是我们要提取的列的位置,也就是对应的是Supplier Name
和Cost
这两列。 - 代码中有2个for循环,对于输入的文件,每一行都要执行这些代码。在第1个for循环中,创建了一个空列表变量
row_list_output
。这个变量保存的是,每行中需要保留的值。 for index_value in my_columns
这个语句是第2个for循环语句,在my_cloumns
中的各个索引值之间进行迭代。row_list_output.append(row_list[index_value])
:使用每行中my_columns
索引位置的值添加到row_list_output
这个列表中。- 现在描述一下这段代码对于第一次外部for循环的运行过程:当读取了文件的第一行后。
index_value
的值为0,随后,append
将row[3]
,也就是csv文件中对应的成本那一列加入到row_list_output
。 - 再往下运行,
filewriter.writerow(row_list_output)
将提取的这个值写入输出文件。
现在运行这段代码,如下所示:
|
|
现在在桌面上就出现了一个新的csv文件,名称为output.csv
,打开这个文件,如下所示:
使用pandas
模块挑出某列-索引方法
使用pandas
模块来选取某列的代码如下所示,代码保存在桌面上,命名为pandas_column_by_index.py
:
|
|
运行如下所示:
|
|
这里用到了iloc
函数,这个函数的功能是:基于索引位置来选择数据集,那么代码中的[:0, 3]
表示的就是选取第0列与第3列。
iloc
与loc
函数的用法
iloc的用法可以通过代码来演示一下:
|
|
运行结果如下所示:
|
|
基于标题选取列
选取特定的列也可以使用列标题来选取,尤其是当处理的文件中有相同的标题,但是列不同的时候就可以采用这种方法。在这个案例中,还以前面的那个csv文件说明一下,现在只需要保留发票号码列和购买日期列,我们采用列标题的方式来选取,输入以下代码,命名为reader_column_by_name.py
,如下所示:
|
|
解释一下代码(略去前面已经提到的内容):
header = next(filereader, None)
:这里使用了next
函数,它的功能是返回迭代器的下一项。next
函数的用法是next(iterator[, default])
,其中iterator
是一个迭代器,而default
则是一个可选对象,也就是说,在没有下一个元素返回时,就返回该默认值,如果不设置,又没有下一个元素时,就会触发StopIteration
异常。
这段代码是《Python数据分析基础》中的代码,根据书后面的csv文件,它的前两行是其它数据,使用上面的代码无法正确读取(只会生成标题,而没有内容),因此需要手工将前面的数据删除,形成如下内容才行:
现在运行代码,如下所示:
|
|
此时就会在桌面上生成一个名为index_output.csv
的csv文件,打开如下所示:
使用pandas
按标题行进行读取
要使用pandas
来读取数据,需要输入以下代码(命名为pandas_column_by_name.py
):
|
|
需要注意的是,这个也要删除原始csv文件的前两行。
常规方法选取连续的行
在前面的原始csv表格中,我们可以发现,前两行的内容是I don’t care about this line
,后三行的内容是I don’t want this line either
,这些内容不是我们想要的,我们只想要中间的那些内容,如下所示:
因此下面演示一下如何选取中间的内容,输入以下代码,命名为11csv_reader_select_contiguous_rows.py
,如下所示:
|
|
运行代码如下所示:
|
|
此时就在桌面上生成了一个名为11.csv
的csv文件。
添加标题行
当电子表格中没有标题行 的时候,就需要添加列标题。此时还以前面的ccsv文件为例说明一下,删除前后几行,菾下面的样式:
将文保存为supplier_data_no_header_row.csv
格式。
使用常规方式添加标题行
在桌面上新建一个名为12csv_reader_add_header_row.py
的Python文件,输入以下代码:
|
|
运行代码,如下所示:
|
|
在桌面上就生成了add_header.csv
的新文件,打开如下所示:
使用pandas
包添加列标题
pandas
包中的read_csv
函数可以直接指定输入文件不包含标题行,并哦可以提供一个列标题列表。如果要给一个没有标题行的数据集添加标题行,此文件命名为pandas_add_header_row.py
,实现方式如下所示:
|
|
运行代码如下所示:
|
|
这里需要注意一下最后一行data_frame.to_csv(output_file, index=False)
里面的index=False
,如果设置为True
,则会在数据集的前面再添加1列,这1列是索引,如下所示:
读取多个csv文件
数据处理过程中常常会遇到同时处理多个csv文件的情况。
创建3个演示csv文件
在桌面上创建第1个csv文件(这个文件也可以从作者的Github上下载),命名为sales_january_2014.csv
文件内容如下所示:
创建第2个csv文件,命名为sales_february_2014.csv
,内容如下所示:
创建第3个csv文件,命名为sales_march_2014.csv
,内容如下所示:
文件计数与文件中的行列计数
这一部分是要计算一下每个文件中行与列的数量,代码文件为8csv_reader_counts_for_multiple_files.py
,代码如下所示:
|
|
运行结果如下所示:
|
|
代码解释:
for input_file in glob.glob(os.path.join(input_path, 'sales_*')):
这里使用了glob
模块中的glob
函数,这个模块可以匹配某个特定模式的所有路径名,在这段代码中,搜索的模式是sales_*
。这个模式表示要搜索所有文件名以sale_
形状并且下划线后面可以是任意字符的文件。由于我们创建了3个csv文件,所以应该知道使用这段代码可以识别出这3个文件,它们的文件名都是以sales_
形状的。如果我们要检索某个目录下的所有csv文件,则要将sales_*
改为*.csv
。os.path.basename(path)
:这是返回path
的基本文件名。即如果path
是C:\Users\Clinton\Desktop\my_input_file.csv
,那么os.path.basename(path)
则返回的是是my_input_file.csv
。
合并多个文件
有的时候需要将多个csv文件合并为一个csv文件,现在有几种合并方式。
常规合并方式
先看常规方式来合并多个csv文件,输入以下代码,命名为9csv_reader_concat_rows_from_multiple_files.py
,如下所示:
|
|
运行结果如下所示:
|
|
此时在桌面上生成了一名为merge.csv
的文件,打开后,如下所示:
使用pandas
包合并
pandas
包可以直接将多个csv文件合并为一个csv文件。基本过程就是将每个输入文件读取到pandas的数据框中,将所有数据框追加到一个数据框列表,然后使用concat
函数将所有数据框连接成一个数据框。concat
函数可以使用axis
函数来设置合并数据框的试,其中axis=0
表示从头到尾垂直合并,axis=1
表示并排地合并。
使用pandas
包合并多个csv文件的过程如下所示(文件命名为pandas_concat_rows_from_multiple_files.py
):
|
|
运行如下所示:
|
|
计算每个文件值中的总和与均值
在数据处理过程中,有的时候需要计算多个csv文件中的一些统计量,例如均值和总和。现在以前面的3个csv文件为例说明一下如何计算。
常规计算方式
现在使用Python的常规方式来计算前面3个csv文件某列的总和和均值。代码如下所示(代码名称为10csv_reader_sum_average_from_multiple_files.py
):
|
|
运行结果如下所示:
|
|
此时就会在桌面上创建一个add_col.csv
文件,打开后如下所示:
pandas
计算
pandas
包中提供了各种统计函数,例如sum
和mean
。下面的代码功能是对多个文件中的某一列计算这两个统计量(总和与均值),并将每个输入文件的计算结果写入输出文件,代码保存文件为pandas_sum_average_from_multiple_files.py
,如下所示:
|
|
运行结果如下所示:
|
|
参考资料
- sys.argv是什么?
- 克林顿·布朗利(Clinton,W.,Brownley) 著,陈光欣 译. Python数据分析基础[M]. 2017.
- Panadas中文文档
- Pandas中loc和iloc函数用法详解(源码+实例)
- 《Python数据分析基础》中源代码与数据文件