参考: csvkit docs , jq manual , introducing json , data science in cmd, YAML Ain’t Markup Language
json (JavaScript Object Notation) 是一种文本格式,容易读,便于写;json采用了类似于C语言家族的数据格式,多种语言(C, C++, C#, Java, JavaScript, Perl, Python等)都可以方便地解析和生成这种格式,因此,json作为一种理想的数据交换格式得到广泛应用。
json 基于两种数据结构:
对象:在不同的语言中,它可以是对象(object), 记录(record), 结构(struct), 字典(dictionary), 哈希表(hash table), 有键列表(keyed list), 或者关联数组 (associative array),本文统称之为对象(object),记录格式为{"string1":"value1", "string2":"value2"}
。
数组:在其它语言中通常就是数组(array),记录格式为[value1, value2]
。
对象和数组的value
可以是字符串、数值、true、false、null,也可以是对象、数组,也就是说这两种结构之间可以相互嵌套。
字符串需要使用双引号""
扩起来,可以包含任意长度的unicode字符,以下字符需要转义处理:\"
("
),\\
(\
),\/
(/
),\b
(退格),\f
(换页),\n
(换行),\r
(回车),\t
(制表符),\u
(后接4位十六进制数字)。
json 是一种灵活的格式,虽然没有官方标准,但IETF(Internet Engineering Task Force)的RFC 4627已经被广泛接受。
此外,还有一种常用于存储数据的文件格式:yaml,yaml的实现比json复杂,可读性和扩展性更好一些,表达能力更强,但是兼容性要差一点,不同编程语言之间的数据流转,yaml的解析成本比json高。
csv (Comma-Separated Values) 也是一种文本格式,由任意数目的记录组成,记录间以换行符分隔;每条记录由字段组成,字段多以逗号或制表符分隔。通常,所有记录都有完全相同的字段序列。
csv 格式比json更早,应用更广泛,但也没有形成统一的标准,只有一些简单的规则,如:
每一条记录自成一行,不跨行,不留空行;
可设列名,列名要写在文件第一行;
即使某条记录中有字段为空,也要用分隔符指定其位置;
不支持特殊字符,"
和,
要转义。
详细用法可参考IETF RFC 4180。
在数据处理领域,目前仍以csv为主要传输和交换格式,其它格式的数据文件通常需要首先转换为csv格式,因此,本文主要介绍基于csv的数据处理工具。
[TOP]
数据的获取渠道很多,可以直接从数据库中调取,通过web API导出,使用爬虫工具或网络机器人从互联网抓取,甚至还可以散发调研问卷收集第一手数据。这些数据的形式多样,为了处理方便,我们首先考虑将其转换为csv格式。
数据库主要包括MySQL、PostgreSQL、SQLite等,csvkit套件提供了sql2csv
命令,可以直接将这类数据库中的数据导出为csv格式,支持MySQL、Oracle、PostgreSQL、SQLite、微软SQL Server和Sybase。
$ sql2csv --db 'sqlite:///data/user.db' --query 'SELECT * FROM user' > 'WHERE age > 30'
常用的选项还有:-l
,标记列号;-H
,忽略表头;-v
,显示详细的错误信息。
web API导出的数据一般都是json格式,而爬虫抓取到的数据和人工输入的数据更加灵活,可以直接存为csv、SQL、json,也可以是办公领域常见的xls和xlsx,csvkit提供了in2csv
,可以将这些数据转换为csv格式。
$ in2csv -e gbk -f json file.json > file.csv
常用的选项有:-f FORMAT
,指定输入文件的格式,包括csv、dbf、fixed、geojson、ndjson、xls、xlsx;-s
,对于定宽格式数据,需要指定一个模式文件,该文件中包含了每一列的起始位置和宽度;--sheet
,指定xlsx文件的sheet名;-e ENCODING
,指定编码。
也有些数据存储在html和xml格式的网络文件中,这些数据可以使用scrape
、xml2json
进行转换,但实际用起来发现,这两个工具的通用性并不理想,往往需要对转换后的文件做进一步处理,因此,这种情况下,建议直接使用grep
、sed
、awk
等工具有针对性地提取所需要的数据。
另外,生产环境中还会用到hdf等格式,本文暂时不涉及此类数据。
[TOP]
准备好的数据可能是一个文件,也可能是多个文件;这些文件虽然同为csv格式,但可能因存储形式略有差异而互不兼容。因此,需要对收集的数据进行过滤、置换、合并,这里主要针对csv格式的数据处理,介绍csvkit套件中的几个常用工具。
csv数据的可读性较差,因此下文将频繁使用csvlook
将csv数据格式化为更加直观的表格形式。
使用csvcut
可以实现对列的提取和重排,如:
$ cat uid.csv | csvcut -c uid,name | csvlook
-c
,指定提取的列及其排列顺序;-C
,指定不提取的列;-x
,删除全空的行。
行的过滤可使用csvgrep
,如:
$ cat uid.csv | csvgrep -c agree -i -r "0" | csvcut -c uid,name,agree | csvlook
-c
,指定需要处理的列;-i
,输出不匹配的记录项;-r
,指定正则表达式;-m
,指定需要匹配的字符串。
csv 文件的垂直拼接可以使用csvstack
,如:
$ csvstack uid-*.csv -n item -g u1,u2 | csvlook
-n
,创建一个新列,标记来自不同文件的记录;-g
,为来自不同文件的记录指定组名并填充到新创建的列中,需要和-n
配合使用,也可以将文件名作为组名,使用--filenames
;
paste
可实现csv文件的水平拼接,如:
$ paste -d, {uidA, uidB, uidC}.csv | csvlook
-d
用于指定分隔符。
数据的融合使用csvjoin
,如:
$ csvjoin -c gender uid1.csv uid2.csv | sed -n '1p;8,15p' | csvlook
-c
,指定融合时所依据的列。
csvsql
也可以进行数据的融合,如:
$ csvsql --query 'SELECT i.uid, i.name, i.gender, i.agree FROM uid1 i JOIN uid2 j ON (i.gender = j.gender)' uid1.csv uid2.csv | csvlook
csvsql
是一个强大的工具,借助于SQL的语法,可以实现上述所有数据整理工作。关于SQL语法,查看这里。
[TOP]
数据整理为csv格式后,可以使用excel、origin、matlab、mathematica、R等等进行分析,这些方法各有各的优势,NumPy、SciPy和Matplotlib在处理大数据集方面比较灵活,同时学习成本也不高。
[TOP]
上文中的很多csv工具都来自csvkit,csvkit 是用python编写的套件,官方手册可以看这里 https://csvkit.readthedocs.org 。
in2csv |
将json、xls、xlsx等格式转为csv格式 |
sql2csv |
导出SQL数据为csv格式 |
csvclean |
检查csv文件中的语法错误 |
csvcut |
截取csv文件中特定的列 |
csvgrep |
截取csv文件中特定的行 |
csvjoin |
合并两个或多个csv文件 |
csvsort |
对csv记录排序 |
csvstack |
垂直合并两个或多个csv文件 |
csvformat |
|
csvjson |
|
csvlook |
将csv数据格式化为表格形式输出 |
csvpy |
|
csvsql |
在csv数据上执行SQL查询,或将csv插入到数据库中 |
csvstat |
打印csv文件中所有列的描述性统计信息 |
jq
是用C编写的json文件处理工具,参见 http://stedolan.github.io/jq/ 。
$ curl https://api.douban.com/v2/book/1220562 | jq '.'
格式化输出json文件的全部内容。
$ curl https://api.douban.com/v2/book/1220562 | jq '.title'
输出json文件中’title’的值。
$ curl https://api.douban.com/v2/event/list?loc=beijing | jq '.events[].owner.name'
输出json文件中’events[]’中所有’owner’下’name’的值。
[TOP]