Skip to content

Data Wrangling

约 1529 个字 4 行代码 预计阅读时间 6 分钟

Data Wrangling 可译为数据清晰或数据整理,即将原始数据处理为更适合分析的形式。

正则表达式

正则表达式(Regular Expression,简称 regex 或 regexp)是一种用来描述字符串模式的工具。它可以用来搜索、匹配和操作文本数据。

  1. 普通字符

    如 a-z、A-Z、0-9、汉字等,直接匹配自身

  2. 元字符(特殊字符)

    元字符在正则表达式中具有特殊含义,如果需要匹配这些字符本身,就需要使用转义符 \ 进行转义

    • .:匹配除换行符外的任意单个字符
    • ^:匹配字符串的开头
    • $:匹配字符串的结尾
    • *:匹配前面的字符零次或多次
    • +:匹配前面的字符一次或多次
    • ?:匹配前面的字符零次或一次
    • {n}:匹配前面的字符恰好 n 次
    • {n,}:匹配前面的字符至少 n 次
    • {n,m}:匹配前面的字符至少 n 次,至多 m 次
    • []:匹配括号内的任意一个字符,例如 [abc] 匹配 'a'、'b' 或 'c'
    • |:表示“或”操作,例如 a|b 匹配 'a' 或 'b'
    • ():用于分组(捕获子表达式),例如 (abc) 匹配 'abc',
  3. 字符类(Character Class)

    字符类使用方括号 [] 来定义一组字符,匹配其中的任意一个字符

    • [abc]:匹配 'a'、'b' 或 'c'(等价于 a|b|c
    • [a-z]:匹配任意小写字母
    • [A-Z]:匹配任意大写字母
    • [0-9]:匹配任意数字
    • [^abc]:匹配除 'a'、'b'、'c' 之外的任意字符(^ 放在方括号内表示取反)
  4. 预定义字符类

    预定字符类相当于为一些常用字符类提供简写,大部分语言都支持这些预定义字符类(但是可能需要添加一些转义符或特殊选项)

    • \d:匹配任意数字字符,等价于 [0-9]
    • \D:匹配任意非数字字符,等价于 [^0-9]
    • \w:匹配任意字母、数字或下划线字符,等价于 [a-zA-Z0-9_]
    • \W:匹配任意非字母、数字或下划线字符,等价于 [^a-zA-Z0-9_]
    • \s:匹配任意空白字符(包括空格、制表符、换行符等),等价于 [ \t\n\r\f\v]
    • \S:匹配任意非空白字符,等价于 [^ \t\n\r\f\v]
    • \b:匹配单词边界,即单词的开头或结尾
    • \B:匹配非单词边界
  5. 模式修饰符

    可以通过通过修饰符调整匹配行为

    • i:忽略大小写匹配

      /abc/i 可以匹配 'abc'、'ABC'、'Abc' 等

    • g:全局匹配,找到所有匹配项,而不是只找到第一个

      /a/g 可以匹配字符串中的所有 'a'

    • m:多行匹配,使 ^$ 匹配每一行的开头和结尾,而不仅仅是整个字符串的开头和结尾

      /^abc/m 可以匹配每一个以 'abc' 开头的行

    • s:单行模式,使 . 可以匹配换行符

      /a.b/s 可以匹配 'a\nb'

    • x:忽略空白字符和注释,使正则表达式更易读

      /a b c/x 可以匹配 'abc'

    • u:启用 Unicode 支持,使正则表达式可以匹配 Unicode 字符

      /\u{1F600}/u 可以匹配表情符号 '😀'(也可以用于匹配汉字)

正则表达式的高级规则

  1. 分组与捕获

    • 使用圆括号 () 进行分组,可以将多个字符作为一个整体进行匹配和操作
    • 捕获组会保存匹配的内容,方便后续引用
    • 例如我们使用正则表达式 (\d{3})-(\d{4}) 来匹配电话号码 '123-4567',其中 (\d{3}) 捕获区号 '123',(\d{4}) 捕获号码 '4567'。
    • 我们可以通过 \1\2 来引用这些捕获的内容(或者 $1$2,具体取决于使用的工具或语言)
    • 在正则表达式内部引用的示例为 (\d{3})-(\d{4}) \1,它可以匹配 '123-4567 123'
  2. 贪婪匹配

    *+?{n,m} 等量词默认是贪婪的,即它们会尽可能多地匹配字符,在量词后增加 ? 可以使其变为非贪婪模式

    • 贪婪示例:a.*b 在字符串 'a123b456b' 中会匹配 'a123b456b'(从第一个 'a' 到最后一个 'b')
    • 非贪婪示例:a.*?b 在字符串 'a123b456b' 中会匹配 'a123b'(从第一个 'a' 到第一个 'b')

数据整理工具

sed

sed(stream editor)是一种用于处理和转换文本的流编辑器,常用于对文本进行批量替换、删除、插入等操作,它的核心特点是​​无需加载整个文件到内存​​(适合大文件处理),且通过简洁的脚本语法实现复杂操作。

常用命令:

  1. 替换

    sed 's/old/new/FLAG' input.txt > output.txt
    

    该命令将 input.txt 中的所有 'old' 替换为 'new',并将结果保存到 output.txt 中。FLAG 是标志位,用于控制替换行为

    • g:全局替换,替换行内所有匹配项(默认只替换每行的第一个匹配项)
    • i:忽略大小写匹配
    • p:打印替换后的行(通常与 -n 选项一起使用)
  2. 删除

    sed 'Nd' input.txt > output.txt
    

    该命令删除 input.txt 中的第 N 行,并将结果保存到 output.txt 中。如果要删除多行,可以使用逗号分隔行号范围,例如 2,5d 删除第 2 行到第 5 行

    或者 d 也可以用在标志位上:cat log.txt | sed '/error/d' 删除包含 'error' 的所有行

  3. 插入与追加

    • i:在指定行之前插入文本
    • a:在指定行之后追加文本
    sed 'Ni\New line' input.txt > output.txt  # 在第 N 行之前插入 'New line'
    sed 'Na\New line' input.txt > output.txt  # 在第 N 行之后追加 'New line'
    

Tip

因为 sed 较为古老,或许不支持一些比较现代的正则表达式语法(如 \d\w 等),建议使用更通用的字符类(如 [0-9][a-zA-Z0-9_] 等),或使用 -E 选项启用扩展正则表达式(Extended Regular Expressions)

sort & uniq

sort 用于对文本文件中的内容进行排序,uniq 用于过滤掉相邻的重复行,通常与 sort 结合使用以实现对整个文件的唯一化处理。

  • sort
    • -n:按数值排序
    • -r:按降序排序
    • -k N:按第 N 列排序(列以空格或制表符分隔),-k N,M 表示按第 N 列到第 M 列排序
  • uniq
    • -c:统计每行出现的次数
    • -d:只显示重复的行

Comments