python数据分析_Python数据分析实战之数据获取三大招

一个数据分析师,最怕的一件事情莫过于在没有数据的情况下,让你去做一个详细的数据分析报告。 确实,巧妇难为无米之炊,数据是数据分析、数据挖掘乃至数据可视化最最基础的元素。 利用Python进行数据分析最重要到一步,就是利用合适的方法将数据导入到Python。然而,当你面对一堆数据,你真的会快速、正确的读取吗?

        在本期Python数据分析实战学习中,将从常见的数据获取方法入手,对常用的数据获取方式进行详细的介绍:

  • Open( ) 函数读取数据

  • Pandas 库读取数据

  • Numpy 库读取数据


第一招 Open( )函数读取数据

Python内置函数open( ),主要用来从文本中读取数据。

Python可以读取任何格式的文本数据。一般分为三个步骤:定义数据文件、创建文件对象、读取文件内容。
  • 定义数据文件
语法

将文件赋值给一个文件对象,为了后续操作更加便捷,减少代码冗余。

file_name1 = './test.txt'file_name2 = '/Users/jim/Documents/Python/test.txt'
file_name1 为相对路径,其要求需脚本路径与文件路径一致。 file_name2:为绝对路径,无其他要求。
  • 创建文件对象

1、语法

要以读文件的模式打开一个文件对象,使用Python内置的open( )函数,传入文件名和标示符,其意义在于后续的操作均是基于该对象产生的。

file_object = open(name [, mode][, buffering])
name: 要读取的文件名称 mode: 打开文件的模式,选填。r, r+, w, w+, a, a+ 使用最多。 buffering: 文件所需的缓冲区大小, 选填。0表示无缓冲, 1表示线路缓冲。
Mode Describe
r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
w 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。
rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
r+ 打开一个文件用于读写。文件指针将会放在文件的开头。
w+ 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab+ 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。

>>> file_object = open(file_name, 'r')# 文件不存在,即报错Traceback (most recent call last):  File "", line 1, in FileNotFoundError: [Errno 2] No such file or directory: './test.txt'>>> file_object.read()'Hello world!'

2、Python基于文件对象分为3种方法

hon基于文件对象分为3种方法

Methods Describe Return
read 读取文件中的全部数据,直到到达定义的size字节数上限 内容字符串,所有行合并为一个字符串
readline 读取文件中的一行数据,直到到达定义的size字节数上限 内容字符串
readlines 读取文件中的全部数据,直到到达定义的size字节数上限 内容列表,每行数据作为列表中的一个对象

# test.txt中有两行内容:"""line1: Hello world!line2: Life is short. I learn Python!""">>> file_object = open(file_name)>>> read_data = file_object.read()>>> print(read_data)line1: Hello world!line2: Life is short. I learn Python!>>> readline_data = file_object.readline()>>> print(readline_data)line1: Hello world!>>> readlines_data = file_object.readlines()>>> print(readlines_data)line1: Hello world!line2: Life is short. I learn Python!
遇到有些编码不规范的文件,你可能会遇到UnicodeDecodeError,因为在文本文件中可能夹杂了一些非法编码的字符。遇到这种情况,open( )函数还接收一个errors参数,表示如果遇到编码错误后如何处理。最简单的方式是直接忽略:
file_object = open('/Users/jim/Documents/Python/gbk.txt', 'r', encoding='gbk', errors='ignore' )
readline 每次只读取一行数据,需配合seek, next等指针操作,才能完整遍历所有数据记录。
>>> fout = open('text.txt')  # 获得文件对象>>> print(fout.tell())  # 输出指针位置0>>> line1 = fout.readline()  # 获得文件第一行数据>>> print(line1)  # 输出第一行数据line1: Hello world!>>> print(fin.tell())  # 输出指针位置21>>> line2 = fout.readline()  # 获得文件第二行数据>>> print(line2)  # 输出第二行数据line2: Life is short. I learn Python!>>> print(fout.tell())  # 输出指针位置>>> fout.close()  # 关闭文件对象60
由于文件读写时都有可能产生IOError,一旦出错,后面的fout.close()就不会调用。可以使用try … finally来保证无论是否出错都能正确地关闭文件:
>>> try:...   file_object = open('./text.txt', 'r')...   print(file_object.read())... finally:...   if file_object:...     file_object.close()
3、基于with的 文件打开方法  相信很多时候,在使用 open( ) 函数时,总不是很方便。此时使用基于 with的文件打开 方法,可以自动做上下文管理,而无需单独做close操作,简单又方便:

例1  对单个文件对象操作时:

>>> with open( './test.txt', 'r' ) as fout:...   print(fout.read())line1: Hello world!line2: Life is short. I learn Python!

例2  同时对多个文件对象操作,可以连续写open方法:

>>> with open( './test1.txt', 'r' ) as fout1, open( './test2.txt', 'r' ) as fout2:...   content1 = fout1.read()...   content2 = fout2.read()
调 用read()会一次性读取文件的全部内容,如果文件有10G,内存就爆了。可以反复调用read(size)方法,每次最多读取size个字节的内容。 调用readline()可以每次读取一行内容,调用readlines()一次读取所有内容并按行返回list。 如果文件很小,read()一次性读取最方便;如果不能确定文件大小,反复调用read(size)比较保险;如果是配置文件,调用readlines()最方便。

第二招 Pandas 库读取数据 在日常数据分析中,使用pandas读取数据文件更为常见。pandas不仅可以读取open()函数所读取的文本文件及其他各类文件,最重要的是pandas读取结果为DataFrame数据框,后续的数据处理更为方便。 1、语法 以最常用的读取 csv 文本文件数据为例,对pandas读取数据进行详细对介绍。
>>> import pandas as pd>>> df = pd.read_csv(r"./test.csv"    # 路径里面可以是中文,到时如果有特殊字符,可能会报错,建议路径全是英文。                 , sep = ','     # 默认分隔符为,                 , header = 'infer' # 默认将第一行作为列名 ,header = None不要一第一行作为标题。                 , encoding='gbk' # 默认用 UTF-8 进行解码,读取window系统建立的csv文件需改成`encoding='gbk'`                 , index_col=None                )                 >>> df.head(4)   # df.head()默认显示前5行, 当然可以自己制定sh
输出结果:

python数据分析_Python数据分析实战之数据获取三大招_第1张图片

常用参数说明:

sep : str, default ‘,’    指定分隔符。如果不指定参数,则会尝试使用逗号分隔。分隔符长于一个字符并且不是‘\s+’,将使用python的语法分析器。并且忽略数据中的逗号。正则表达式例子:'\r\t'

header : int or list of ints, default ‘infer’    指定行数用来作为列名,数据开始行数。如果文件中没有列名,则默认为0,否则设置为None。如果明确设定header=0 就会替换掉原来存在列名。header参数可以是一个list例如:[0,1,3],这个list表示将文件中的这些行作为列标题(意味着每一列有多个标题),介于中间的行将被忽略掉(例如本例中的2;本例中的数据1,2,4行将被作为多级标题出现,第3行数据将被丢弃,DataFrame的数据从第5行开始。)。注意:如果skip_blank_lines=True 那么header参数忽略注释行和空行,所以header=0表示第一行数据而不是文件的第一行。

index_col : int or sequence or False, default None    

用作行索引的列编号或者列名,如果给定一个序列则有多个行索引。 如果文件不规则,行尾有分隔符,则可以设定index_col=False 来是的pandas不适用第一列作为行索引。

encoding : str, default None    指定字符集类型,通常指定为'utf-8'. 

dtype : Type name or dict of column -> type, default None    每列数据的数据类型。例如 {‘a’: np.float64, ‘b’: np.int32}

nrows : int, default None    需要读取的行数(从文件头开始算起)

skiprows : list-like or integer, default None    需要忽略的行数(从文件开始处算起),或需要跳过的行号列表(从0开始)。

low_memory : boolean, default True    分块加载到内存,再低内存消耗中解析。但是可能出现类型混淆。确保类型不被混淆需要设置为False。或者使用dtype 参数指定类型。注意使用chunksize 或者iterator 参数分块读入会将整个文件读入到一个DataFrame,而忽略类型(只能在C解析器中有效)

parse_dates : boolean or list of ints or names or list of lists or dict, default False 

  • boolean. True -> 解析索引
  • list of ints or names. e.g. If [1, 2, 3] -> 解析1,2,3列的值作为独立的日期列;
  • list of lists. e.g. If [[1, 3]] -> 合并1,3列作为一个日期列使用
  • dict, e.g. {‘foo’ : [1, 3]} -> 将1,3列合并,并给合并后的列起名为"foo"

2、常见问题

  • 路径内有中csv

>>> import pandas as pd>>> #df=pd.read_csv("E:/测试文件夹/测试数据.csv")>>> f=open("E:/测试文件夹/测试数据.csv") # 解决方案>>> df=pd.read_csv(f)
  • window 中 shift+右键-->复制为路径 获取的文件路径

>>> import pandas as pd>>> # df=pd.read_csv("E:\测试文件夹\测试数据.csv")>>> df=pd.read_csv(r"E:\测试文件夹\测试数据.csv")

字符串前加 r 的作用

>>> "E:\测试文件夹\测试数据.csv"'E:\\测试文件夹\\测试数据.csv'>>> r"E:\测试文件夹\测试数据.csv"'E:\\测试文件夹\\测试数据.csv'>>> print("E:\测试文件夹\test.csv")E:\测试文件夹   est.csv  >>> print(r"E:\测试文件夹\test.csv")E:\测试文件夹\test.csv
  • 排除某些行

>>> import pandas as pd>>> df = pd.read_csv(r"./test.csv" ...                  , skiprows=3 # 要注意的是:排除前3行是skiprows=3 排除第3行是skiprows=[3]...                  , nrows=2...                  , encoding='gbk')           >>> df

输出结果:

3ae1e5f2898804a1c4a3671be9448a18.png

  • 文件中有日期时间列

>>> import pandas as pd>>> df = pd.read_csv(r"./test.csv", encoding='gbk'...                  #, parse_dates=[3]...                  )>>> df.loc[0,'就诊日期']2018/6/15                 >>> df = pd.read_csv(r"./test.csv", encoding='gbk'...                 , parse_dates=[3]...                )>>> df.loc[0,'就诊日期']Timestamp('2018-06-15 00:00:00')

避坑指南:

有日期时间格式列的文件作为缓存文件,先用test.to_csv('test.csv') 保存,再用pd.read_csv('./test.csv')读取文件时。

坑1:index列。保存文件时默认保存索引,读取文件时默认自动添加索引列,即将保存的索引作为第一列读取到DataFrame

解决方案: 

1,test.to_csv('test.csv', index=False)

2, pd.read_csv('./test.csv', index_col=0)


坑2:原本日期格式的列,保存到csv文件后仍为日期格式。但再次读取文件时将以字符串的格式读取到DataFrame

解决方案:

1,  pd.read_csv('./test.csv', parse_dates=[3]) 将特定的日期列解析为日期格式;

2, 先使用默认值file = pd.read_csv('./test.csv'),再对特定的列进行格式转换。file.loc[:, column] = file.loc[:, column].map(lambda x: parse(x).date() if isinstance(file.loc[0, column], str) else x)


更多详情,请见 pandas 官方文档查阅地址: https://pandas.pydata.org/pandas-docs/version/0.24/reference/io.html

第三招 Numpy 库读取数据

Numpy读取数据方法与Pandas类似,其包括 loadtxt, load, fromfile
Methods Describe Return
loadtxt txt文本中读取数据 从文件中读取的数组
load 使用numpyload方法可以读取numpy专用的二进制数据文件,从npy, npzpickled文件中加载数组或pickled对象 从数据文件中读取的数据、元祖、字典等
fromfile 使用numpyfromfile方法可以读取简单的文本文件数据以及二进制数据 从文件中读取的数据
  • 使用 loadtxt 方法读取数据文件

数据通常是一维或者二维的

语法

np.loadtxt( fname           , dtype=           , comments='#'           , delimiter=None           , converters=None           , skiprows=0           , usecols=None           , unpack=False           , ndmin=0           , encoding='bytes'           , max_rows=None           ,)

常用参数说明:

fname : file, str, or pathlib.Path   文件或字符串, 必填项, 指要读取的文件名称或字符串, 支持压缩的数据文件, 包括gzbz格式。 dtype : data-type, optional   数据类型, 选填, 默认为float。 comments : str or sequence of str, optional   字符串或字符串组成的列表, 选填,默认 #, 是表示注释字符集开始的标志。 delimiter : str, optional   字符串, 选填, 默认空格, 用来分隔多个列的分隔符, 如逗号、TAB符。 converters : dict, optional   字典, 选填, 默认为空, 用来将特定列的数据转换为字典中对应的函数的浮点型数据。如果第0列是一个date则'converters = {0: datestr2num} '; 'converters = {3: lambda s: float(s.strip() or 0)}' skiprows : int, optional   跳过特定行数据, 选填, 默认为0, 用来跳过特定前N条记录。 usecols : int or sequence, optional   整数或元祖, 选填, 默认为空, 用来指定要读取数据的列, 如(1, 3, 6) unpack : bool, optional   布尔值, 选填, 默认为False, 用来指定是否转置, 如果为True, 则转置 ndmin : int, optional   整数型, 选填, 默认为0, 用来指定返回的数据至少包含特定维度的数组, 值域为0/1/2 encoding : str, optional   字符串, 选填, 用于解码inputfile的编码。不适用于输入流。特殊值 "bytes" 允许向后兼容解决方案, 这可以确保接收到字节数组作为结果, 如果可能的话“latin1”编码的字符串到转换器。重写此值以接收unicode数组, 并将字符串作为输入传递给转换器。如果没有设置, 使用系统默认值。默认值是"bytes"max_rows : int, optional   整数, 选填, 默认为空, 在"skiprows"行之后读取内容的"max_rows"行。默认的就是读所有的行。

>>> import numpy as np  # 导入numpy库>>> file_name = 'numpy_data.txt'  # 定义数据文件>>> data = np.loadtxt(file_name, dtype='float32', delimiter=' ')  # 获取数据>>> print(data)  # 打印数据[[ 0.  1.  2.  3.  4.] [ 5.  6.  7.  8.  9.] [10. 11. 12. 13. 14.]]
  • 使用 load 方法读取数据文件

使用 numpyload方法可以读取numpy专用的二进制数据文件,从npy, npzpickled文件中加载数组或pickled对象, 该文件通常基于numpysavesavez产生。

语法

np.load(file        , mmap_mode=None        , allow_pickle=False        , fix_imports=True        , encoding='ASCII')
file : file-like object, string, or pathlib.Path   类文件对象或字符串格式, 必填, 要读取的文或字符串。类文件对象需要支持seek()read()方法。 mmap_mode : {None, 'r+', 'r', 'w+', 'c'}, optional   内存映射模式, 选填。 allow_pickle : bool, optional   布尔值, 选填, 默认为True, 决定是否允许加载存储在npy文件中的pickled对象数组。 fix_imports : bool, optional   布尔值, 选填, 默认为True, 只有在python3上加载python2生成的pickle文件时才有用, 其中包括包含对象数组的npy/npz文件。如果"fix_imports", 如果是True, pickle将尝试将旧的python2名称映射到新名称在python3中使用。 encoding : str, optional   在读取Python 2字符串时使用什么编码。加载python2生成了python3中的pickle文件时才有用, 其中包括包含对象数组的npy/npz文件。除了latin1, "ASCII""bytes"是不允许的, 因为它们会破坏数字数据。默认值: "ASCII"

>>> import numpy as np  # 导入numpy库>>> write_data = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])  # 定义要存储的数据>>> np.save('load_data', write_data)  # 保存为npy数据文件>>> read_data = np.load('load_data.npy')  # 读取npy文件>>> print(read_data)  # 输出读取的数据[[ 1  2  3  4] [ 5  6  7  8] [ 9 10 11 12]]
  • 使用 fromfile 方法读取数据文件

该方法读取的数据来源于numpy的tofile方法。

语法

fromfile(file, dtype=float, count=-1, sep='', offset=0)
file : file or str or Path   文件或字符串或路径 dtype : data-type, optional   数据类型, 选填, 默认为float。 count : int   整数型, 读取数据的数量, -1意味着读取所有的数据。 sep : str   字符串, 如果文件是文本文件, 那么该值为数据间的分隔符。空("")分隔符表示该文件应该作为二进制文件处理。分隔符中的空格(" ")匹配零个或多个空格字符。仅由空格组成的分隔符必须至少匹配一个空白。

>>> import numpy as np  # 导入numpy库>>> file_name = 'numpy_data.txt'  # 定义数据文件>>> data = np.loadtxt(file_name, dtype='float32', delimiter=' ')  # 获取数据>>> tofile_name = 'binary'  # 定义导出二进制文件名>>> data.tofile(tofile_name)  # 导出二进制文件>>> fromfile_data = np.fromfile(tofile_name, dtype='float32')  # 读取二进制文件>>> print(fromfile_data)  # 打印数据[ 0.  1.  2.  3.  4.  5.  6.  7.  8.  9. 10. 11. 12. 13. 14.]

另外,使用Python读取Excel文件,除了使用pandas.read_excel(),还是采用专门用于读取Excel的第三方库,最常用的是xlrd。

你可能感兴趣的:(python数据分析)