python数据读取和分析_Python数据分析(四):数据的获取与处理

在python的学习过程中,我们会经常遇到各种格式的数据加载、处理与存储。今天我们来总结一下常见格式数据的读取与处理。

一、各种各样的文本数据

1.1 CSV与TXT读取

1、csv

csv 文件格式的本质是一种以文本存储的表格数据(使用 Excel 工具即可读写 csv 文件)。csv 文件的每行代表一行数据,每行数据中每个单元格内的数据以逗号隔开。首先我们先来看一下数据长什么样子,这里使用的是jupyter notebook编辑器。

!cat '/opt/jupyter_file/dataset/数据获取与分析/data1.csv'

a,b,c,d,message

1,2,3,4,hello

5,6,7,8,world

9,10,11,12,foo

接下来我们看一下数据的读取:

df=pd.read_csv('/opt/jupyter_file/dataset/数据获取与分析/data1.csv')

df

或者下面一种:

#需要知道分隔符

pd.read_table('/opt/jupyter_file/dataset/数据获取与分析/data1.csv',sep=',')

我们也可以设置一下参数:

#read_csv读取时会自动识别表头,

#数据有表头时不能设置header为空(默认读取第一行,即header=0);

#数据无表头时,若不设置header,第一行数据会被视为表头,应传入names参数设置表头名称或设置header=None。

pd.read_csv('/opt/jupyter_file/dataset/数据获取与分析/data1.csv',header=None)

pd.read_csv('/opt/jupyter_file/dataset/数据获取与分析/data1.csv',names=['a','b','c','d','e'])

还可以设置一下索引列:

names=['a','b','c','d','e']

pd.read_csv('/opt/jupyter_file/dataset/数据获取与分析/data1.csv',names=names,index_col='e')#制定索引列

相对复杂的索引列:

pd.read_csv('/opt/jupyter_file/dataset/数据获取与分析/csv_mindex.csv',index_col=['key1','key2'])

!cat '/opt/jupyter_file/dataset/数据获取与分析/data4.csv'

# hey!

a,b,c,d,message

# just wanted to make things more difficult for you

# who reads CSV files with computers, anyway?

1,2,3,4,hello

5,6,7,8,world

9,10,11,12,foo

pd.read_csv('/opt/jupyter_file/dataset/数据获取与分析/data4.csv',skiprows=[0,2,3])#跳过索引为0,2,3的行

result=pd.read_csv('/opt/jupyter_file/dataset/数据获取与分析/data5.csv')

result

pd.isnull(result)

result=pd.read_csv('/opt/jupyter_file/dataset/数据获取与分析/data5.csv',na_values=['null'])

result

sentinels={'message':['foo','NA'],'something':['two']}

pd.read_csv('/opt/jupyter_file/dataset/数据获取与分析/data5.csv',na_values=sentinels)#设置为0

这里我总结一下read_csv()常用到的参数

类型

说明

sep

指定分隔符。如果不指定参数,则会尝试使用逗号分隔。

delimiter

定界符,备选分隔符(如果指定该参数,则sep参数失效)

delim_whitespace

指定空格(例如’ ‘或者’ ‘)是否作为分隔符使用,等效于设定sep='\s+'。如果这个参数设定为Ture那么delimiter 参数失效。

header

指定行数用来作为列名,数据开始行数

names

用于结果的列名列表,如果数据文件中没有列标题行,就需要执行header=None。

index_col

用作行索引的列编号或者列名,如果给定一个序列则有多个行索引。

dtype

每列数据的数据类型。

skiprows

需要忽略的行数(从文件开始处算起),或需要跳过的行号列表(从0开始)。

skipfooter

从文件尾部开始忽略。 (c引擎不支持)

nrows

需要读取的行数(从文件头开始算起)。

na_values

一组用于替换NA/NaN的值。如果传参,需要制定特定列的空值。默认为‘1.#IND’, ‘1.#QNAN’, ‘N/A’, ‘NA’, ‘NULL’, ‘NaN’, ‘nan’`.

na_filter

是否检查丢失值(空字符串或者是空值)。对于大文件来说数据集中没有空值,设定na_filter=False可以提升读取速度。

skip_blank_lines

如果为True,则跳过空行;否则记为NaN。

encoding

指定字符集类型,通常指定为'utf-8'.

2、txt

第一种:适合文本类型的读取,编排没有格式要求

f=open('/opt/jupyter_file/dataset/数据获取与分析/data3.txt')

f.read()

第二种:有一定的格式,这时可以通过指定分隔符来解决

list(open('/opt/jupyter_file/dataset/数据获取与分析/data3.txt'))#提前看一下内容

[' A B C\n',

'aaa -0.264438 -1.026059 -0.619500\n',

'bbb 0.927272 0.302904 -0.032399\n',

'ccc -0.264273 -0.386314 -0.217601\n',

'ddd -0.871858 -0.348382 1.100491\n']

#或者另一种方式

!cat '/opt/jupyter_file/dataset/数据获取与分析/data3.txt'

A B C

aaa -0.264438 -1.026059 -0.619500

bbb 0.927272 0.302904 -0.032399

ccc -0.264273 -0.386314 -0.217601

ddd -0.871858 -0.348382 1.100491

pd.read_table('/opt/jupyter_file/dataset/数据获取与分析/data3.txt',sep='\s+')#分隔符,正则表达式(规则),至少有一个空格

1.2 分片/块读取文本数据

result=pd.read_csv('/opt/jupyter_file/dataset/数据获取与分析/data6.csv')

result

pd.read_csv('/opt/jupyter_file/dataset/数据获取与分析/data6.csv',nrows=5)#读取前5行

chunker=pd.read_csv('/opt/jupyter_file/dataset/数据获取与分析/data6.csv',chunksize=100)#分块读取,表明每100行为1个chunk。

#返回的reader是TextFileReader类型,它指向若干个chunk位置,只在访问数据的时候才真正把数据读入到内存。

#这是一个可迭代的类型,采用for in的形式,即可逐个访问chunk。

#每个chunk都是dataframe类型的。

chunker

tot=Series([])

for piece in chunker:

#取并集,value求和

#fill_value参数使a中value的NaN=fill_value,然后与b中相同索引的value相加

tot=tot.add(piece['key'].value_counts(),fill_value=0)#取序列中value的交集,并统计每个value出现的次数。value作为index,次数作为序列值。

tot=tot.sort_values(ascending=False)

tot[:10]

1.3、把数据写入文本格式

data=pd.read_csv('/opt/jupyter_file/dataset/数据获取与分析/data5.csv')

data

data.to_csv('/opt/jupyter_file/dataset/数据获取与分析/out.csv')

!cat '/opt/jupyter_file/dataset/数据获取与分析/out.csv'

#输出结果

,something,a,b,c,d,message

0,one,1,2,3.0,4,

1,two,5,6,,8,world

2,three,9,10,11.0,12,foo

data.to_csv(sys.stdout,sep='|')

#输出结果

|something|a|b|c|d|message

0|one|1|2|3.0|4|

1|two|5|6||8|world

2|three|9|10|11.0|12|foo

result=data.to_csv(sys.stdout,na_rep='null')

result

#输出结果

,something,a,b,c,d,message

0,one,1,2,3.0,4,null

1,two,5,6,null,8,world

2,three,9,10,11.0,12,foo

data.to_csv(sys.stdout,index=False,header=False)#不要index和header

#输出结果

one,1,2,3.0,4,

two,5,6,,8,world

three,9,10,11.0,12,foo

data.to_csv(sys.stdout,index=False,columns=['a','b','c'])

#输出结果

a,b,c

1,2,3.0

5,6,

9,10,11.0

dates=pd.date_range('1/1/2000',periods=7)#长度为7

ts=Series(np.arange(7),index=dates)

ts.to_csv('/opt/jupyter_file/dataset/数据获取与分析/tseries.csv')

!cat tseries.csv

#输出结果

2000-01-01,0

2000-01-02,1

2000-01-03,2

2000-01-04,3

2000-01-05,4

2000-01-06,5

2000-01-07,6

1.4 手动读写数据(按要求)

!cat '/opt/jupyter_file/dataset/数据获取与分析/data7.csv'

#输出结果

"a","b","c"

"1","2","3"

"1","2","3","4"

import csv

f=open('/opt/jupyter_file/dataset/数据获取与分析/data7.csv')

reader=csv.reader(f)

for line in reader:

print(line)

#输出结果

['a', 'b', 'c']

['1', '2', '3']

['1', '2', '3', '4']

lines=list(csv.reader(open('/opt/jupyter_file/dataset/数据获取与分析/data7.csv')))

lines[0]

#输出结果

['a', 'b', 'c']

header,values=lines[0],lines[1:]

#参数为可迭代的对象,并且可以有多个参数。该函数返回一个以元组为元素的列表,其中第 i 个元组包含每个参数序列的第 i 个元素。返回的列表长度被截断为最短的参数序列的长度。只有一个序列参数时,它返回一个1元组的列表。没有参数时,它返回一个空的列表。

data_dict={h: v for h,v in zip(header,zip(*values))}

data_dict

#输出结果

{'a': ('1', '1'), 'b': ('2', '2'), 'c': ('3', '3')}

a=[1,2,3,4]

b=[1,2,3]

c=[1,2,3,4,5]

zz=zip(a,b,c)

for line in zz:

print(line)

#输出结果

(1, 1, 1)

(2, 2, 2)

(3, 3, 3)

#csv的文件的形式有很多,只需定义csv.dialect的一个子类即可定义出新格式(如专门的分隔符、字符串引用约定、行结束符等)

#第一行是继承(my_dialect继承自csv.Dialect)后面四行是赋值

class my_dialect(csv.Dialect):

lineterminator='\n'

delimiter='|'

quotechar='"'

quoting=csv.QUOTE_MINIMAL

with open('/opt/jupyter_file/dataset/数据获取与分析/mydata.csv','w') as f:

writer=csv.writer(f,dialect=my_dialect)

writer.writerow(('one','two','three'))

writer.writerow(('1','2','3'))

writer.writerow(('4','5','6'))

writer.writerow(('7','8','9'))

!cat '/opt/jupyter_file/dataset/数据获取与分析/mydata.csv'

#输出结果

one|two|three

1|2|3

4|5|6

7|8|9

1.5JSON格式的数据

obj=\

"""

{"姓名":"张三",

"住处":["天朝","挖煤国","万恶的资本主义日不落帝国"],

"宠物":null,

"兄弟":[{"姓名":"李四","年龄":"25","宠物":"汪星人"},

{"姓名":"王五","年龄":"23","宠物":"喵星人"}]

}

"""

import json

result=json.loads(obj)

result

#输出结果

{'姓名': '张三',

'住处': ['天朝', '挖煤国', '万恶的资本主义日不落帝国'],

'宠物': None,

'兄弟': [{'姓名': '李四', '年龄': '25', '宠物': '汪星人'},

{'姓名': '王五', '年龄': '23', '宠物': '喵星人'}]}

result["兄弟"][0]

#输出结果

{'姓名': '李四', '年龄': '25', '宠物': '汪星人'}

result["兄弟"][1]

#输出结果

{'姓名': '王五', '年龄': '23', '宠物': '喵星人'}

brothers=DataFrame(result["兄弟"],columns=['姓名','年龄'])

brothers

#输出结果

image.png

1.6 解析HTML

from lxml.html import parse#专门用于处理html的模块

import urllib.request#打开和浏览url中内容

parsed=parse(urllib.request.urlopen('https://ask.julyedu.com/explore/'))#解析url

doc=parsed.getroot()#获取根元素

doc

#输出结果

links=doc.findall('.//a')#正则表达式

links[15:20]

#输出结果

[,

,

,

,

]

lnk=links[19]

lnk

lnk.get('href')

print(lnk.text_content())#文本内容

#输出结果

全部问题

urls=[lnk.get('href') for lnk in doc.findall('.//a')]

urls[-10:]

#输出结果

['https://www.cnzz.com/stat/website.php?web_id=1259748782',

'https://www.julyedu.com',

'https://www.julyedu.com/help/index/about',

'https://www.julyedu.com/help/index/join',

'http://weibo.com/askjulyedu',

'javascript:',

'https://tianchi.aliyun.com',

'https://cloud.tencent.com/developer/edu',

'https://www.aidaxue.com/?ch=qyzx',

'https://www.epubit.com']

spans=doc.findall('.//span')

len(spans)

#输出结果

132

def _unpack(spans):

return [val.text_content() for val in spans]

contents=_unpack(spans)

for content in contents:

print(content)

questions=doc.findall('.//h4')#问题标签

len(questions)

#输出结果

50

contents=_unpack(questions)

for content in contents:

print(content)

1.7 解析XML

XML是一种结构化、层级化的数据格式,最适合体现XML的数据结构就是树

!cat '/opt/jupyter_file/dataset/数据获取与分析/Performance_MNR.xml'

from lxml import objectify#lxml.objectify主要用于处理以数据为中心的文档,可以根据叶子节点所含的内容自动推断数据类型。

path='/opt/jupyter_file/dataset/数据获取与分析/Performance_MNR.xml'

parsed=objectify.parse(open(path))

root=parsed.getroot()

data=[]

skip_fields=['PARENT_SEQ','INDICATOR_SEQ','DESIRED_CHANGE','DECIMAL_PLACES']

for elt in root.INDICATOR:#返回一个用于产生各个XML元素的生成器

el_data={}

for child in elt.getchildren():

if child.tag in skip_fields:

continue

el_data[child.tag]=child.pyval#pyval获取内容也可以用text

data.append(el_data)

perf=DataFrame(data)

perf

二、其他格式的数据

1、二进制格式的数据

#存储速度快、文件小

#pandas库pd.read_pickle操作读取pickle数据与.to_pickle()永久储存数据

frame=pd.read_csv('/opt/jupyter_file/dataset/数据获取与分析/data1.csv')

frame

frame.to_pickle('/opt/jupyter_file/dataset/数据获取与分析/frame_pickle')

pd.read_pickle('/opt/jupyter_file/dataset/数据获取与分析/frame_pickle')

2、使用HDF5格式

一个HDF5文件是一种存放两类对象的容器:dataset和group. Dataset是类似于数组的数据集,而group是类似文件夹一样的容器,存放dataset和其他group。在使用h5py的时候需要牢记一句话:groups类比词典,dataset类比Numpy中的数组。

store=pd.HDFStore('/opt/jupyter_file/dataset/数据获取与分析/mydata.h5')

store['obj1']=frame

store['obj1_col']=frame['a']

store

#输出结果

File path: /opt/jupyter_file/dataset/数据获取与分析/mydata.h5

store['obj1']

3、HTML与API交互

import requests

url='https://api.github.com/repos/pydata/pandas/milestones/28/labels'

resp=requests.get(url)

resp

#输出结果

data[:5]

issue_labels=DataFrame(data)

issue_labels

三、数据库相关操作

3.1 sqlite数据库

import sqlite3

query="""

CREATE TABLE test(a varchar(20),

b varchar(20),

c real,

d integer);

"""

con=sqlite3.connect(':memory:')#连接服务

con.execute(query)#确认执行

con.commit()#提交

data=[('zhangsan','China',1.25,6),

('lisi','America',2.6,3),

('wangwu','Japan',1.7,5)]

stmt="INSERT INTO test values(?,?,?,?)"

con.executemany(stmt,data)#执行多条记录

con.commit()

cursor=con.execute('select * from test')

rows=cursor.fetchall()#游标,fetchall查询所有

rows

#输出结果

[('zhangsan', 'China', 1.25, 6),

('lisi', 'America', 2.6, 3),

('wangwu', 'Japan', 1.7, 5)]

cursor.description

#输出结果

(('a', None, None, None, None, None, None),

('b', None, None, None, None, None, None),

('c', None, None, None, None, None, None),

('d', None, None, None, None, None, None))

DataFrame(rows,columns=list(zip(*cursor.description))[0])#为了方便看

import pandas.io.sql as sql

sql.read_sql('select * from test',con)

3.2 MYSQL数据库

#coding=utf-8

import pymysql

conn=pymysql.connect(host='localhost',

port=3306,

user='root',

passwd='123456',

db='test')

cur=conn.cursor()

#创建数据表

# cur.execute("create table student(id int,name varchar(20),class varchar(20),age varchar(10))")

#插入一条数据

# cur.execute("insert into student values('2','Tom','3 year 2 class ',13)")

#修改查询条件的数据

# cur.execute("update student set class='3 year 1 class' where name='Tom'")

#查询所有数据

cur.execute("select * from test.student")

#删除查询条件的数据

# cur.execute("delete from student where age='9'")

cur.close()

conn.commit()

conn.close()

不小心执行了三遍插入操作

关于python对数据的获取与处理就讲到这里,下一篇我们讲解一下数据的可视化!

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