《利用Python 进行数据分析》 - 笔记(4)----json

时间:2021-09-19 14:47:43

解决方案:

读写文本格式的数据:

  • pandas 提供了一些用于将表格型数据读取为DataFrame对象的函数
  • pandas 中的解析函数
《利用Python 进行数据分析》 - 笔记(4)----json
  • 函数的选项可以划分为以下几个大类
  1. 索引:将一个或多个列当做返回的DataFrame处理,以及是否从文件、用户获取列名
  2. 类型推断和数据转换:包括用户定义值的转换、缺失值标记列表等。
  3. 日期解析:包括组合功能,比如 将分散在多个列的日期信息组合成结果中的单个列
  4. 迭代:支持对大文件进行逐块迭代
  5. 不规整数据问题:跳过一些行、页脚、注释或其他一些不重要的东西
  • 类型推断:
  • 你不需要指定列的类型到底是数值、整数、布尔值、还是字符串。
  • 日期和其他自定义类型的处理需要花点功夫才行。
  • 分别用read_csv() 和 read_table() 读取文件
  1. In [17]: !cat ex1.csv
  2. a,b,c,d,message
  3. 1,2,3,4,hello
  4. 5,6,7,8,world
  5. 9,10,11,12,foo
  6. In [18]: import pandas as pd
  7. In [19]: df = pd.read_csv('ex1.csv')
  8. In [20]: df
  9. Out[20]:
  10. a   b   c   d message
  11. 0  1   2   3   4   hello
  12. 1  5   6   7   8   world
  13. 2  9  10  11  12     foo
  14. In [21]: pd.read_table('ex1.csv', sep=',')
  15. Out[21]:
  16. a   b   c   d message
  17. 0  1   2   3   4   hello
  18. 1  5   6   7   8   world
  19. 2  9  10  11  12     foo
  • 对于没有标题行的文件
  1. In [25]: !cat ex2.csv
  2. 1,2,3,4,hello
  3. 5,6,7,8,world
  4. 9,10,11,12,foo
  5. In [26]: pd.read_csv('ex2.csv', header = None)
  6. Out[26]:
  7. 0   1   2   3      4
  8. 0  1   2   3   4  hello
  9. 1  5   6   7   8  world
  10. 2  9  10  11  12    foo
  11. In [27]: pd.read_csv('ex2.csv', names = ['a','b','c','d','message'])
  12. Out[27]:
  13. a   b   c   d message
  14. 0  1   2   3   4   hello
  15. 1  5   6   7   8   world
  16. 2  9  10  11  12     foo
  • 如果希望将message 列做成DataFrame 的索引
  1. 明确表示要将该列放到索引4的位置上
  2. 通过index_col 参数指定
  1. In [28]: names = ['a','b','c','d','message']
  2. In [29]: pd.read_csv('ex2.csv', names = names, index_col='message')
  3. Out[29]:
  4. a   b   c   d
  5. message
  6. hello    1   2   3   4
  7. world    5   6   7   8
  8. foo      9  10  11  12
  • 如果你希望做成层次化索引,只需要传入由列编号或列名组成的列表即可
  1. In [31]: parsed = pd.read_csv('csv_mindex.csv', index_col = ['key1','key2'])
  2. In [32]: parsed
  3. Out[32]:
  4. value1  value2
  5. key1 key2
  6. one  a          1       2
  7. b          3       4
  8. c          5       6
  9. d          7       8
  10. two  a          9      10
  11. b         11      12
  12. c         13      14
  13. d         15      16
  • 有些表格可能不是用固定的分隔符去分隔字段,对于这种情况我们要用正则表达来作为read_table 的分隔符
  1. In [8]: !cat ex3.txt
  2. A         B         C
  3. aaa -0.264438 -1.026059 -0.619500
  4. bbb  0.927272  0.302904 -0.032399
  5. ccc -0.264273 -0.386314 -0.217601
  6. ddd -0.871858 -0.348382  1.100491
  7. In [10]: result = pd.read_table('ex3.txt', sep='\s+')
  8. In [11]: result
  9. Out[11]:
  10. A         B         C
  11. aaa -0.264438 -1.026059 -0.619500
  12. bbb  0.927272  0.302904 -0.032399
  13. ccc -0.264273 -0.386314 -0.217601
  14. ddd -0.871858 -0.348382  1.100491
  • 缺失值处理是文件解析任务中的一个重要的组成部分
  1. 缺失数据是一个空串(什么都没有)
  2. 用一个标记值来标记(NA,-1.#IND,NULL)
  3. na_values 参数规定什么样的值是NA 值
  1. In [22]: result = pd.read_csv('ex5.csv')
  2. In [23]: result
  3. Out[23]:
  4. something  a   b   c   d message
  5. 0       one  1   2   3   4     NaN
  6. 1       two  5   6 NaN   8   world
  7. 2     three  9  10  11  12     foo
  8. In [24]: result = pd.read_csv('ex5.csv', na_values=['10','11','12'])
  9. In [25]: result
  10. Out[25]:
  11. something  a   b   c   d message
  12. 0       one  1   2   3   4     NaN
  13. 1       two  5   6 NaN   8   world
  14. 2     three  9 NaN NaN NaN     foo
  • read_csv/read_table 函数的参数
《利用Python 进行数据分析》 - 笔记(4)----json《利用Python 进行数据分析》 - 笔记(4)----json

1.逐块读取文本文件

  • read_csv 所返回的是个TextParser(文本解析器对象)使你可以根据chunksize 对文件进行逐块迭代
  1. In [27]: chunker = pd.read_csv('ex6.csv', chunksize=1000)
  2. In [28]: chunker
  3. Out[28]: <pandas.io.parsers.TextFileReader at 0x7f4a0c369e90>
  • 我们可以迭代处理这个ex6.csv 将值计数聚合到”key“列中
  • ex6.py
  1. #!/usr/bin/env python
  2. # coding=utf-8
  3. import pandas as pd
  4. chunker = pd.read_csv('ex6.csv', chunksize=1000)
  5. result = pd.Series([])
  6. for piece in chunker:
  7. result = result.add(piece['key'].value_counts(),fill_value=0)
  8. result = result.order(ascending = False)
  1. In [37]: pd.read_csv('ex6.csv',nrows=5)
  2. Out[37]:
  3. one       two     three      four key
  4. 0  0.467976 -0.038649 -0.295344 -1.824726   L
  5. 1 -0.358893  1.404453  0.704965 -0.200638   B
  6. 2 -0.501840  0.659254 -0.421691 -0.057688   G
  7. 3  0.204886  1.074134  1.388361 -0.982404   R
  8. 4  0.354628 -0.133116  0.283763 -0.837063   Q
  9. In [38]: run ex6.py
  10. In [39]: result[:10]
  11. Out[39]:
  12. E    368
  13. X    364
  14. L    346
  15. O    343
  16. Q    340
  17. M    338
  18. J    337
  19. F    335
  20. K    334
  21. H    330
  22. dtype: float64

2.将数据写出到文本格式

  • DataFrame 的 to_csv方法
  1. 可以将数据写到文件中(.txt/.csv/...)
  2. 默认分隔符为‘,’
  3. 我们可以使用sep 参数控制分隔符
  4. na_rep 参数处理缺失值
  1. In [20]: data = pd.read_csv('ex5.csv')
  2. In [21]: data
  3. Out[21]:
  4. something  a   b   c   d message
  5. 0       one  1   2   3   4     NaN
  6. 1       two  5   6 NaN   8   world
  7. 2     three  9  10  11  12     foo
  8. In [22]: data.to_csv('out.csv')
  9. In [23]: !cat out.csv
  10. ,something,a,b,c,d,message
  11. 0,one,1,2,3.0,4,
  12. 1,two,5,6,,8,world
  13. 2,three,9,10,11.0,12,foo
  14. In [24]: data.to_csv('out.csv',sep='|')
  15. In [25]: !cat out.csv
  16. |something|a|b|c|d|message
  17. 0|one|1|2|3.0|4|
  18. 1|two|5|6||8|world
  19. 2|three|9|10|11.0|12|foo
  20. In [27]: data.to_csv('out.csv',sep='|',na_rep='null')
  21. In [28]: !cat out.csv
  22. |something|a|b|c|d|message
  23. 0|one|1|2|3.0|4|null
  24. 1|two|5|6|null|8|world
  25. 2|three|9|10|11.0|12|foo

  1. 如果没有其他选项,则会写出行和列的标签
  2. 我们也可以只写出一部分的列,并以我们指定的顺序排列
  1. In [38]: data.to_csv('out.csv',index = False, cols = ['a','b','c'],na_rep = 'null')
  2. In [39]: !cat out.csv
  3. a,b,c
  4. 1,2,3.0
  5. 5,6,null
  6. 9,10,11.0
  • Series 的 to_csv 方法
  1. In [44]: dates = pd.date_range('1/1/2000',periods=10)
  2. In [45]: dates
  3. Out[45]:
  4. <class 'pandas.tseries.index.DatetimeIndex'>
  5. [2000-01-01, ..., 2000-01-10]
  6. Length: 10, Freq: D, Timezone: None
  7. In [47]: ts = pd.Series(np.arange(10),index=dates)
  8. In [48]: ts.to_csv('tseries.csv')
  9. In [49]: !cat tseries.csv
  10. 2000-01-01,0
  11. 2000-01-02,1
  12. 2000-01-03,2
  13. 2000-01-04,3
  14. 2000-01-05,4
  15. 2000-01-06,5
  16. 2000-01-07,6
  17. 2000-01-08,7
  18. 2000-01-09,8
  19. 2000-01-10,9
  • Series 的 from_csv 方法
  1. In [50]: data = pd.read_csv('tseries.csv')
  2. In [51]: data
  3. Out[51]:
  4. 2000-01-01  0
  5. 0  2000-01-02  1
  6. 1  2000-01-03  2
  7. 2  2000-01-04  3
  8. 3  2000-01-05  4
  9. 4  2000-01-06  5
  10. 5  2000-01-07  6
  11. 6  2000-01-08  7
  12. 7  2000-01-09  8
  13. 8  2000-01-10  9
  14. In [52]: data = pd.Series.from_csv('tseries.csv')
  15. In [53]: data
  16. Out[53]:
  17. 2000-01-01    0
  18. 2000-01-02    1
  19. 2000-01-03    2
  20. 2000-01-04    3
  21. 2000-01-05    4
  22. 2000-01-06    5
  23. 2000-01-07    6
  24. 2000-01-08    7
  25. 2000-01-09    8
  26. 2000-01-10    9
  27. dtype: int64

3.JSON数据

  1. json:一种数据传输的标准格式(http请求在web浏览器和各个应用程序之间)
  2. pandas 团队正在致力于添加原生的高效的json导出(to_json) 和解码(from_json)功能
  3. 我们可以通过json.loads 将json 字符串转换成python形式
  4. 相反,json.dumps则将python对象转换成json格式
  5. 也可以向DataFrame 构造器传入一组Json 对象,并选取数据字段的子集
  1. In [54]: obj = """
  2. ....: { "programmers": [
  3. ....:
  4. ....: { "firstName": "Brett", "lastName":"McLaughlin", "email": "aaaa" },
  5. ....:
  6. ....: { "firstName": "Jason", "lastName":"Hunter", "email": "bbbb" },
  7. ....:
  8. ....: { "firstName": "Elliotte", "lastName":"Harold", "email": "cccc" }
  9. ....:
  10. ....: ],
  11. ....:
  12. ....: "authors": [
  13. ....:
  14. ....: { "firstName": "Isaac", "lastName": "Asimov", "genre": "science fiction" },
  15. ....:
  16. ....: { "firstName": "Tad", "lastName": "Williams", "genre": "fantasy" },
  17. ....:
  18. ....: { "firstName": "Frank", "lastName": "Peretti", "genre": "christian fiction" }
  19. ....:
  20. ....: ],
  21. ....:
  22. ....: "musicians": [
  23. ....:
  24. ....: { "firstName": "Eric", "lastName": "Clapton", "instrument": "guitar" },   ....:
  25. ....: { "firstName": "Sergei", "lastName": "Rachmaninoff", "instrument": "piano" }
  26. ....:
  27. ....: ] }
  28. ....: """
  29. In [55]: import json
  30. In [56]: result = json.loads(obj)
  31. In [57]: result
  32. Out[57]:
  33. {u'authors': [{u'firstName': u'Isaac',
  34. u'genre': u'science fiction',
  35. u'lastName': u'Asimov'},
  36. {u'firstName': u'Tad', u'genre': u'fantasy', u'lastName': u'Williams'},
  37. {u'firstName': u'Frank',
  38. u'genre': u'christian fiction',
  39. u'lastName': u'Peretti'}],
  40. u'musicians': [{u'firstName': u'Eric',
  41. u'instrument': u'guitar',
  42. u'lastName': u'Clapton'},
  43. {u'firstName': u'Sergei',
  44. u'instrument': u'piano',
  45. u'lastName': u'Rachmaninoff'}],
  46. u'programmers': [{u'email': u'aaaa',
  47. u'firstName': u'Brett',
  48. u'lastName': u'McLaughlin'},
  49. {u'email': u'bbbb', u'firstName': u'Jason', u'lastName': u'Hunter'},
  50. {u'email': u'cccc', u'firstName': u'Elliotte', u'lastName': u'Harold'}]}
  51. In [58]: asjson = json.dumps(result)
  52. In [59]: musicians = pd.DataFrame(result['musicians'],columns=['firstName','lastName'])
  53. In [60]: musicians
  54. Out[60]:
  55. firstName      lastName
  56. 0      Eric       Clapton
  57. 1    Sergei  Rachmaninoff

4.xml和html:web信息收集

  • 从html中提取 超链接
  1. In [62]: from lxml.html import parse
  2. In [63]: from urllib2 import urlopen
  3. In [64]: parsed = parse(urlopen('http://finance.yahoo.com/q/op?s=AAPL+Options'))
  4. In [65]: doc = parsed.getroot()
  5. In [66]: links = doc.findall('.//a')
  6. In [67]: links[10:20]
  7. Out[67]:
  8. [<Element a at 0x7fac8955c3c0>,
  9. <Element a at 0x7fac8955c418>,
  10. <Element a at 0x7fac8955c470>,
  11. <Element a at 0x7fac8955c4c8>,
  12. <Element a at 0x7fac8955c520>,
  13. <Element a at 0x7fac8955c578>,
  14. <Element a at 0x7fac8955c5d0>,
  15. <Element a at 0x7fac8955c628>,
  16. <Element a at 0x7fac8955c680>,
  17. <Element a at 0x7fac8955c6d8>]
  18. In [68]: lnk = links[28]
  19. In [69]: lnk
  20. Out[69]: <Element a at 0x7fac8955c9f0>
  21. In [70]: lnk.get('href')
  22. Out[70]: 'https://help.yahoo.com/l/us/yahoo/finance/'
  23. In [71]: lnk.text_content()
  24. Out[71]: 'Help'
  25. In [72]: urls = [lnk.get('href') for lnk in doc.findall('.//a')]
  26. In [73]: urls[-10:]
  27. Out[73]:
  28. ['/q/cf?s=AAPL+Cash+Flow',
  29. 'https://mobile.yahoo.com/finance/?src=gta',
  30. '/q/op?s=AAPL&date=1463529600',
  31. '/q/op?s=AAPL&straddle=true&date=1463529600',
  32. None,
  33. None,
  34. None,
  35. None,
  36. '/q/op?s=AAPL&strike=20.00',
  37. '/q?s=BVZ160518P00020000']

二进制数据格式:

  • HDF5

PyTables和h5py这两个Python项目可以将NumPy的数组数据存储为高效且可压缩的HDF5格式(层次化数据格式)。你可以安全地将好几百GB甚至TB的数据存储为HDF5格式。

PyTables提供了一些用于结构化数组的高级查询功能,而且还能添加列索引以提升查询速度,这跟关系型数据库所提供的表索引功能非常类似。

  • 读取 Microsoft Excel 文件
  1. 创建一个ExcelFile 文件的实例:pd.ExcelFile('filepath')
  2. 通过parse 传入到DataFrame中:xls_file.parse('Sheet1')

使用HTML和web API:

  • 安装requests 包
  1. peerslee@peerslee-ubuntu:~$ sudo apt-get install python-requests
  2. [sudo] peerslee 的密码:
  3. 正在读取软件包列表... 完成
  4. 正在分析软件包的依赖关系树
  5. 正在读取状态信息... 完成
  6. 将会安装下列额外的软件包:
  7. python-ndg-httpsclient python-urllib3
  8. 建议安装的软件包:
  9. python-ntlm
  10. 下列【新】软件包将被安装:
  11. python-ndg-httpsclient python-requests python-urllib3
  12. 升级了 0 个软件包,新安装了 3 个软件包,要卸载 0 个软件包,有 4 个软件包未被升级。
  13. 需要下载 135 kB 的软件包。
  14. 解压缩后会消耗掉 648 kB 的额外空间。
  15. 您希望继续执行吗? [Y/n] Y
  16. 获取:1 http://mirrors.hust.edu.cn/ubuntu/ wily/main python-ndg-httpsclient all 0.4.0-1 [24.9 kB]
  17. 获取:2 http://mirrors.hust.edu.cn/ubuntu/ wily/main python-urllib3 all 1.11-1 [56.2 kB]
  18. 获取:3 http://mirrors.hust.edu.cn/ubuntu/ wily/main python-requests all 2.7.0-3 [53.8 kB]
  19. 下载 135 kB,耗时 2秒 (46.3 kB/s)
  20. 正在选中未选择的软件包 python-ndg-httpsclient。
  21. (正在读取数据库 ... 系统当前共安装有 223563 个文件和目录。)
  22. 正准备解包 .../python-ndg-httpsclient_0.4.0-1_all.deb  ...
  23. 正在解包 python-ndg-httpsclient (0.4.0-1) ...
  24. 正在选中未选择的软件包 python-urllib3。
  25. 正准备解包 .../python-urllib3_1.11-1_all.deb  ...
  26. 正在解包 python-urllib3 (1.11-1) ...
  27. 正在选中未选择的软件包 python-requests。
  28. 正准备解包 .../python-requests_2.7.0-3_all.deb  ...
  29. 正在解包 python-requests (2.7.0-3) ...
  30. 正在处理用于 man-db (2.7.4-1) 的触发器 ...
  31. 正在设置 python-ndg-httpsclient (0.4.0-1) ...
  32. 正在设置 python-urllib3 (1.11-1) ...
  33. 正在设置 python-requests (2.7.0-3) ...

  • 发送一个http get请求
《利用Python 进行数据分析》 - 笔记(4)----json
  • 将GET请求返回的内容加载到一个python 对象中
《利用Python 进行数据分析》 - 笔记(4)----json
  • 响应的结果中有一组python字典
《利用Python 进行数据分析》 - 笔记(4)----json
  • 截取字段,然后创建DataFrame
《利用Python 进行数据分析》 - 笔记(4)----json
  • 该DataFrame 中每一行字都是一条来自tweet的数据
《利用Python 进行数据分析》 - 笔记(4)----json