一、读取文本格式数据
read_csv
将以逗号分隔的csv文件读入DataFrame中
1 2 3 4 5 6 7 8 In [9]: df = pd.read_csv('examples/ex1.csv') In [10]: df Out[10]: a b c d message 0 1 2 3 4 hello 1 5 6 7 8 world 2 9 10 11 12 foo
处理没有标题行的文件
1 2 3 1,2,3,4,hello 5,6,7,8,world 9,10,11,12,foo
分配默认的列名
1 2 3 4 5 6 In [13]: pd.read_csv('examples/ex2.csv', header=None) Out[13]: 0 1 2 3 4 0 1 2 3 4 hello 1 5 6 7 8 world 2 9 10 11 12 foo
自己定义列名
1 2 3 4 5 6 In [14]: pd.read_csv('examples/ex2.csv', names=['a', 'b', 'c', 'd', 'message']) Out[14]: a b c d message 0 1 2 3 4 hello 1 5 6 7 8 world 2 9 10 11 12 foo
将多个列做成一个层次化索引
1 2 3 4 5 6 7 8 9 key1,key2,value1,value2 one,a,1,2 one,b,3,4 one,c,5,6 one,d,7,8 two,a,9,10 two,b,11,12 two,c,13,14 two,d,15,16
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 In [18]: parsed = pd.read_csv('examples/csv_mindex.csv', ....: index_col=['key1', 'key2']) In [19]: parsed Out[19]: value1 value2 key1 key2 one a 1 2 b 3 4 c 5 6 d 7 8 two a 9 10 b 11 12 c 13 14 d 15 16
处理不固定分隔符
1 2 3 4 5 6 7 In [20]: list(open('examples/ex3.txt')) Out[20]: [' 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']
上面不是txt文档中不是像csv统一同逗号分隔,而是用不等长空格分隔,所以使用read_table方法
1 2 3 4 5 6 7 8 9 In [21]: result = pd.read_table('examples/ex3.txt', sep='\s+') In [22]: result Out[22]: 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
跳过指定行
1 2 3 4 5 6 7 # 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
1 2 3 4 5 6 In [24]: pd.read_csv('examples/ex4.csv', skiprows=[0, 2, 3]) Out[24]: a b c d message 0 1 2 3 4 hello 1 5 6 7 8 world 2 9 10 11 12 foo
缺失值处理
1 2 3 4 something,a,b,c,d,message one,1,2,3,4,NA two,5,6,,8,world three,9,10,11,12,foo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 In [26]: result = pd.read_csv('examples/ex5.csv') In [27]: result Out[27]: something a b c d message 0 one 1 2 3.0 4 NaN 1 two 5 6 NaN 8 world 2 three 9 10 11.0 12 foo In [28]: pd.isnull(result) Out[28]: something a b c d message 0 False False False False False True 1 False False False True False False 2 False False False False False False
用一个列表或集合的字符串表示缺失值,指定原来文件中特定的值是缺失值
1 2 3 4 5 6 7 sentials = {'something':['two'], 'message':['foo', 'NA']} result = pd.read_csv('examples/ex5.csv', na_values=sentials) result something a b c d message 0 one 1 2 3.0 4 NaN 1 NaN 5 6 NaN 8 world 2 three 9 10 11.0 12 NaN
其中'something':['two']表示针对something这一列,其中值为two的值替换成缺失值
逐块读取文本文件
读取文件中指定行数
通过nrows进行指定读取行数即可:
1 2 3 4 5 6 7 8 In [36]: pd.read_csv('examples/ex6.csv', nrows=5) Out[36]: one two three four key 0 0.467976 -0.038649 -0.295344 -1.824726 L 1 -0.358893 1.404453 0.704965 -0.200638 B 2 -0.501840 0.659254 -0.421691 -0.057688 G 3 0.204886 1.074134 1.388361 -0.982404 R 4 0.354628 -0.133116 0.283763 -0.837063 Q
逐块读取文件
可以指定chunksize(行数)
1 2 3 4 In [874]: chunker = pd.read_csv('ch06/ex6.csv', chunksize=1000) In [875]: chunker Out[875]: <pandas.io.parsers.TextParser at 0x8398150>
逐块迭代文件
比如说,我们可以迭代处理ex6.csv,将值计数聚合到"key"列中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 chunker = pd.read_csv('examples/ex6.csv', chunksize=1000) tot = pd.Series([]) for piece in chunker: tot = tot.add(piece['key'].value_counts(), fill_value=0) tot = tot.sort_values(ascending=False) In [40]: tot[:10] Out[40]: E 368.0 X 364.0 L 346.0 O 343.0 Q 340.0 M 338.0 J 337.0 F 335.0 K 334.0 H 330.0 dtype: float64
将数据写出到文本格式
to_csv
1 2 3 4 5 6 7 In [43]: data.to_csv('examples/out.csv') In [44]: !cat examples/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
使用其他分隔符
1 2 3 4 5 6 7 In [45]: import sys In [46]: 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
禁用行和列的标签
1 2 3 4 In [48]: data.to_csv(sys.stdout, index=False, header=False) one,1,2,3.0,4, two,5,6,,8,world three,9,10,11.0,12,foo
操作指定列
1 2 3 4 5 In [49]: data.to_csv(sys.stdout, index=False, columns=['a', 'b', 'c']) a,b,c 1,2,3.0 5,6, 9,10,11.0
处理分隔符格式
对于任何单字符分隔符文件,可以直接使用Python内置的csv模块。将任意已打开的文件或文件型的对象传给csv.reader:
1 2 3 4 import csv f = open('examples/ex7.csv' ) reader = csv.reader(f)
对这个reader进行迭代将会为每行产生一个元组(并移除了所有的引号):
1 2 3 4 5 In [56]: for line in reader: ....: print (line) ['a' , 'b' , 'c' ] ['1' , '2' , '3' ] ['1' , '2' , '3' ]
创建数据列的字典
首先解释zip的作用:
zip()
函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
举例1:
a = [1,2,3]
b = [4,5,6]
c = [4,5,6,7,8]
ipped = zip(a,b) # 打包为元组的列表
输出:[(1, 4), (2, 5), (3, 6)]
举例2:
zip(*values)
的作用是将values
列表中的元素解压缩为多个独立的元组,然后将这些元组组合在一起成为一个迭代器。
具体来说,假设values
列表是一个包含多个元组的列表,例如[(v1_1, v2_1, ...), (v1_2, v2_2, ...), ...]
,zip(*values)
会将这些元组解压缩并重新组合,将它们的第一个元素组成一个元组,第二个元素组成一个元组,依此类推
具体使用:
首先,读取文件到一个多行的列表中:
1 2 In [57]: with open('examples/ex7.csv') as f: ....: lines = list(csv.reader(f))
然后,我们将这些行分为标题行和数据行
1 In [58]: header, values = lines[0], lines[1:]
接着,我们可以用字典构造式和zip(*values),后者将行转置为列,创建数据列的字典
1 2 3 4 In [59]: data_dict = {h: v for h, v in zip(header, zip(*values))} In [60]: data_dict Out[60]: {'a': ('1', '1'), 'b': ('2', '2'), 'c': ('3', '3')}
定义新格式的csv文件
1 2 3 4 5 6 class my_dialect(csv.Dialect): lineterminator = '\n' delimiter = ';' quotechar = '"' quoting = csv.QUOTE_MINIMAL reader = csv.reader(f, dialect=my_dialect)
lineterminator = '\n'
:定义行终止符为换行符
\n
。
delimiter = ';'
:定义字段之间的分隔符为分号
;
。
quotechar = '"'
:定义引号字符为双引号
"
,用于包围包含特殊字符的字段。
quoting = csv.QUOTE_MINIMAL
:定义引用约定为最小引用,表示只在必要时才使用引号。
JSON数据
1 2 3 4 5 6 7 8 9 obj = """ {"name": "Wes", "places_lived": ["United States", "Spain", "Germany"], "pet": null, "siblings": [{"name": "Scott", "age": 30, "pets": ["Zeus", "Zuko"]}, {"name": "Katie", "age": 38, "pets": ["Sixes", "Stache", "Cisco"]}] } """
json.loads
1 2 3 4 5 6 7 8 9 10 11 In [62]: import json In [63]: result = json.loads(obj) In [64]: result Out[64]: {'name': 'Wes', 'pet': None, 'places_lived': ['United States', 'Spain', 'Germany'], 'siblings': [{'age': 30, 'name': 'Scott', 'pets': ['Zeus', 'Zuko']}, {'age': 38, 'name': 'Katie', 'pets': ['Sixes', 'Stache', 'Cisco']}]}
json.dumps
1 In [65]: asjson = json.dumps(result)
将json转换为DataFrame
最简单方便的方式是:向DataFrame构造器传入一个字典的列表(就是原先的JSON对象),并选取数据字段的子集:
1 2 3 4 5 6 7 In [66]: siblings = pd.DataFrame(result['siblings'], columns=['name', 'age']) In [67]: siblings Out[67]: name age 0 Scott 30 1 Katie 38
read_json
特别格式的JSON数据集
1 2 3 4 [{"a":1, "b":2, "c":3},//里面字典,字典之间用“,”分割 {} {} {}]//外边整体列表
自动将特别格式的JSON数据集转换为Series或DataFrame
1 2 3 4 5 6 7 8 In [69]: data = pd.read_json('examples/example.json') In [70]: data Out[70]: a b c 0 1 2 3 1 4 5 6 2 7 8 9
to_json
将数据从pandas输出到JSON
1 2 3 4 5 In [71]: print(data.to_json()) {"a":{"0":1,"1":4,"2":7},"b":{"0":2,"1":5,"2":8},"c":{"0":3,"1":6,"2":9}} In [72]: print(data.to_json(orient='records')) [{"a":1,"b":2,"c":3},{"a":4,"b":5,"c":6},{"a":7,"b":8,"c":9}]
二、二进制数据格式
实现数据的高效二进制格式存储最简单的办法之一是使用Python内置的pickle序列化。pandas对象都有一个用于将数据以pickle格式保存到磁盘上的to_pickle方法:
to_pickle:
1 2 3 4 5 6 7 8 9 10 In [87]: frame = pd.read_csv('examples/ex1.csv') In [88]: frame Out[88]: a b c d message 0 1 2 3 4 hello 1 5 6 7 8 world 2 9 10 11 12 foo In [89]: frame.to_pickle('examples/frame_pickle')
read_pickle
1 2 3 4 5 6 In [90]: pd.read_pickle('examples/frame_pickle') Out[90]: a b c d message 0 1 2 3 4 hello 1 5 6 7 8 world 2 9 10 11 12 foo
使用HDF5格式
准备数据集
1 frame = pd.DataFrame({'a': np.random.randn(100)})
创建了一个名为frame
的Pandas
DataFrame对象,其中包含一个名为a
的列,该列包含了随机生成的100个标准正态分布(均值为0,标准差为1)的随机数值
创建
1 store = pd.HDFStore('mydata.h5')
创建了一个名为store
的Pandas
HDFStore对象,并打开了一个名为mydata.h5
的HDF5文件。
像python中键值对一样存取
1 2 store['obj1'] = frame store['obj1_col'] = frame['a']
table存储方式
obj2表示存储的键,frame表示存储的值,format定义存储形式,用table形式存储好处在于可以用特殊语法查询
read_hdf和to_hdf
1 frame.to_hdf('mydata.h5', 'obj3', format='table')
将frame中内容保存在mydata.h5的hdf5文件中,对应的键是obj3,形式是table
1 2 3 4 5 6 7 8 In [102]: pd.read_hdf('mydata.h5', 'obj3', where=['index < 5']) Out[102]: a 0 -0.204708 1 0.478943 2 -0.519439 3 -0.555730 4 1.965781
读写Microsoft Excel文件
读取excel文件
创建实例
1 In [104]: xlsx = pd.ExcelFile('examples/ex1.xlsx')
通过read_excel读取到DataFrame
1 2 3 4 5 6 In [105]: pd.read_excel(xlsx, 'Sheet1') Out[105]: a b c d message 0 1 2 3 4 hello 1 5 6 7 8 world 2 9 10 11 12 foo
根据表单(sheet)读取
1 2 3 4 5 6 7 8 In [106]: frame = pd.read_excel('examples/ex1.xlsx', 'Sheet1') In [107]: frame Out[107]: a b c d message 0 1 2 3 4 hello 1 5 6 7 8 world 2 9 10 11 12 foo
写入excel文件
创建实例
1 writer = pd.ExcelWriter('examples/ex2.xlsx')
写入
1 frame.to_excel(writer, 'Sheet1')
保存
Web APIs交互
发送HTTP GET请求
1 2 3 4 5 6 7 8 In [113]: import requests In [114]: url = 'https://api.github.com/repos/pandas-dev/pandas/issues' In [115]: resp = requests.get(url) In [116]: resp Out[116]: <Response [200]>
将相应返回的json字典加载到python对象中
1 2 3 4 In [117]: data = resp.json() In [118]: data[0]['title'] Out[118]: 'Period does not round down for frequencies less that 1 hour'
通过DataFrame提取感兴趣字段
1 2 issues = pd.DataFrame(data, columns=['number', 'title', 'labels', 'state']) issues
0
58019
CLN/PERF: Simplify argmin/argmax
[{'id': 2822342, 'node_id':
'MDU6TGFiZWwyODIyM...
open
1
58018
PERF: Allow Index.to_frame to return
RangeInde...
[{'id': 8935311, 'node_id':
'MDU6TGFiZWw4OTM1M...
open
2
58017
Docs: Add note about exception for
integer sli...
[]
open
3
58016
PERF: Allow np.integer Series/Index to
convert...
[{'id': 8935311, 'node_id':
'MDU6TGFiZWw4OTM1M...
open
4
58015
BUG: Behaviour of sum/mean on sparse
boolean a...
[{'id': 76811, 'node_id':
'MDU6TGFiZWw3NjgxMQ=...
open
5
58013
Potential regression induced by "CLN:
Enforce ...
[{'id': 2822342, 'node_id':
'MDU6TGFiZWwyODIyM...
open
6
58012
Add tests for transform sum with
series
[{'id': 127685, 'node_id':
'MDU6TGFiZWwxMjc2OD...
open
7
58011
DEPR: enforce deprecation of non-standard
argu...
[{'id': 211029535, 'node_id':
'MDU6TGFiZWwyMTE...
open
8
58008
Backport PR #57553 on branch 2.2.x (API:
avoid...
[]
open
9
58007
API: Make Series.array
a
read-only NumpyExte...
[{'id': 2085877452, 'node_id':
'MDU6TGFiZWwyMD...
open
10
58006
CLN: remove unnecessary check
needs_i8_conver... | [{'id': 1218227310, 'node_id': 'MDU6TGFiZWwxMj... | open | | 11 | 58001 | BUG: Implement
fillna(...,
limit=x)for EAs | [{'id': 76811, 'node_id': 'MDU6TGFiZWw3NjgxMQ=... | open | | 12 | 57999 | DEPR: Enforce datetimelike deprecations | [{'id': 211029535, 'node_id': 'MDU6TGFiZWwyMTE... | open | | 13 | 57995 | FIX #57645: Cannot use numpy FLS as indicies s... | [] | open | | 14 | 57994 | DOC: DataFrame.reset_index names param can't b... | [{'id': 134699, 'node_id': 'MDU6TGFiZWwxMzQ2OT... | open | | 15 | 57993 | BUG: Nones in pd.concat MultiIndex keys are no... | [{'id': 76811, 'node_id': 'MDU6TGFiZWw3NjgxMQ=... | open | | 16 | 57990 | DOC: ecosystem.md: add pygwalker, add seaborn ... | [{'id': 134699, 'node_id': 'MDU6TGFiZWwxMzQ2OT... | open | | 17 | 57989 | BUG: CONTAINS_OP run on pd.NA results in pd.N... | [{'id': 76811, 'node_id': 'MDU6TGFiZWw3NjgxMQ=... | open | | 18 | 57988 | PERF: (partial) fix for np_datetime.c performa... | [{'id': 8935311, 'node_id': 'MDU6TGFiZWw4OTM1M... | open | | 19 | 57987 | DEPR: 'epoch' date format in to_json | [{'id': 49379259, 'node_id': 'MDU6TGFiZWw0OTM3... | open | | 20 | 57986 | CLN: enforce deprecation of frequencies deprec... | [{'id': 53181044, 'node_id': 'MDU6TGFiZWw1MzE4... | open | | 21 | 57985 | BUG: Fix error for
boxplotwhen using a pre-... | [] | open | | 22 | 57984 | Fix
to_timedelta
np.int32`
casting bug with...
[]
open
23
57980
BUG: Unexpected Styler.format
behavior
[{'id': 1728592794, 'node_id':
'MDU6TGFiZWwxNz...
open
24
57979
ENH: Add leftsemi merge
[{'id': 76812, 'node_id':
'MDU6TGFiZWw3NjgxMg=...
open
25
57976
ENH: set module for
objects in pandas Scal...
[{'id': 13101118, 'node_id':
'MDU6TGFiZWwxMzEw...
open
26
57974
BUG: Fixed ADBC to_sql creation of table
when ...
[{'id': 76811, 'node_id':
'MDU6TGFiZWw3NjgxMQ=...
open
27
57972
BUG: Wrong kurtosis outcome due to
inadequate ...
[{'id': 76811, 'node_id':
'MDU6TGFiZWw3NjgxMQ=...
open
28
57968
BUG: #57954 encoding ignored for
filelike
[{'id': 42670965, 'node_id':
'MDU6TGFiZWw0MjY3...
open
29
57967
BUG: 7023 allow style when using error
bars
[]
open
数据库交互
将数据从SQL加载到DataFrame
创建表
1 2 3 4 5 6 query = """ CREATE TABLE test (a VARCHAR(20), b VARCHAR(20), c REAL, d INTEGER ); """
一个SQL查询语句,用于创建一个名为test
的表。该表包含了四个列,分别是a
、b
、c
和d
,对应的数据类型分别为VARCHAR(20)、VARCHAR(20)、REAL和INTEGER。
创建到数据库的连接
1 con = sqlite3.connect('mydata.sqlite')
执行在sql中创建表
将修改提交到数据库
创建用于插入的数据
1 2 3 data = [('Atlanta', 'Georgia', 1.25, 6), ('Tallahassee', 'Florida', 2.6, 3), ('Sacramento', 'California', 1.7, 5)]
SQL 插入语句的模板
使用了参数化查询的形式,其中 ?
是占位符,表示待插入的值将在执行查询时动态地填充到相应的位置上。这种参数化查询的方式可以防止
SQL 注入攻击,并且使得查询更加灵活和可维护。
1 stmt = "INSERT INTO test VALUES(?, ?, ?, ?)"
SQL插入操作
1 con.executemany(stmt, data)
SQL 查询
创建了一个游标对象 cursor
,并使用 execute
方法执行了一个 SQL 查询操作,从 test
表中选择所有的行和列。执行这个操作后,游标 cursor
将会指向查询结果的第一行。
1 cursor = con.execute('select * from test')
获取查询结果
1 2 rows = cursor.fetchall() rows
调用了游标对象 cursor
的 fetchall()
方法,用于获取执行 SQL
查询后返回的所有结果行。这将返回一个包含所有结果行的列表
rows
。
返回描述列的元祖项的集合
返回一个包含查询结果的元数据的元组,其中每个元组项描述了结果集中的一个列。每个元组项通常包含列的名称、数据类型、宽度、精度