查看原文
其他

数据治理 | 超大.csv文件怎么处理?我们有独门武器!(免费赠送自制csv切分工具)

快点关注→ 数据Seminar 2022-12-31
目录

一、前言

二、问题背景

三、使用 CSV 切分工具

四、Stata 解决方案

  1. 获取数据量

  2. (1)查看变量(字段)

    (2)获取观测数

  3. 分批统计信息

五、Python 解决方案

  1. 获取数据量

  2. (1)获取数据行数

    (2)查看数据字段

  3. 处理数据

六、总结

我们贴心地为大家准备了团队自制的CSV切分工具,关注本公众号,后台回复“20220520”即可免费获取自制 CSV 切分工具

Part1前言

作为数据使用者,我们清理、分析数据的常用工具有 Stata、Python 等。当我们操作计算机并使用这些工具来处理数据时,不可避免地需要将数据导入到这些工具中。无论是 Stata 还是 Python,导入数据本质上都是将数据导入到计算机内存中。我们使用的计算机内存一般是 8GB 或 16GB,这种规格的内存在面对较大的数据集时尚能得心应手,但面对海量数据(几千万行,甚至更多)时,如果将数据整个导入内存,会出现导入失败,或者导致内存负载过大。表现为计算机异常卡顿,或者内存报错。如此一来,处理数据自然就无从下手。
注意:1GB 的数据被读入内存后,可能会占用超过 2GB 的内存空间
面对这种情况,我们应当如何另辟蹊径,“曲线救国”呢?本文为您出谋划策!

Part2问题背景

学生小李收到导师发来的一份 .csv 文件,导师告诉小李这是一份关于专利的数据集,希望小李帮忙统计一些地区的专利数量。
小李收到后发现这份数据竟然占用 3.7GB 存储空间,无法使用 Excel 等工具直接打开。小李尝试将数据导入 Stata 软件,结果 Stata 直接“沉默”。不死心的小李又尝试使用 Python 读取数据,结果因数据量过大导致电脑非常卡顿(已经在死机边缘徘徊),最终也没能成功读取数据。到此为止,小李甚至不知道数据量(多少行,有哪些字段)是多少。无奈,小李只能求助朋友,朋友了解情况后,给出了使用 CSV 切分工具、Stata 和 Python 这三种工具的解决方案。

Part3使用 CSV 切分工具

可以使用随本文赠送的 csv 切分工具,此工具可以在 Windows 系统中运行。其主要功能包括获取 .csv 文件的行数、将一个 .csv 文件切分为若干个小  .csv 文件等。每个小数据的行数可以由用户输入决定,切分后所有小数据被保存在大数据所在目录。小工具使用方法如下:

第 ① 步

双击打开 CSV 切分工具,等待出现下图所示交互界面:

第 ② 步

点击右侧【浏览】按钮选择一个本地 “UTF-8” 编码.csv 文件,随后点击下方【打开】选项。
选择数据后,程序开始获取数据的行数和占用存储空间的大小,并推荐一个较为合适的切分行数。当然,你也可以不接受推荐,手动输入你希望的切分行数。如下图所示:
获取到这个 .csv 文件的行数是 2850001(包含表头),并推荐切分行数为 200000;我们手动设置切分行数为 300000,这样就可以把数据拆分为 10 个小数据:

第 ③ 步

输入切分行数后,点击【开始切分】按钮,程序就开始切分数据了。切分完成后如下图所示:

文件切分完成后我们就可以使用其他工具分批处理切分后的小数据集了。

💡 这个工具是我们团队自制的,目前还有改进的空间,我们制定了初步的改进计划:

1.  数据文件导入后,显示字段名;
2.  根据某个字段的取值,分类切分。比如按照性别或省份对数据进行切分。

欢迎广大读者向我们提出新的需求或想法,如若条件允许我们将会进一步更新!(扫描下方二维码添加小编

Part4Stata 解决方案

使用 Stata 处理大数据集的主要方案是分批处理数据,每次处理一小部分,循环处理所有数据。

1获取数据量

(1)查看变量(字段)

查看数据字段不需要一次性将全部数据导入 Stata,只需要导入 .csv 文件的前几行即可,代码如下:
// csv 文件路径
local csv_path = "C:\data.csv"
// rowrange(1:5):导入前五行数据(含表头)
import delimited `csv_path', varnames(1) encoding(UTF-8) rowrange(1:5)
  

(2)获取观测数

由于 Stata 不能直接导入全部数据来查看观测数,我们可以分批读取数据,每次读取后记录观测数,然后累加每一批数据的观测数即可获取总观测数,我们以获取一个较小的数据观测数为例,代码如下:
clear

// 数据路径
local csv_path = "C:\data.csv"

// 初始行
local startline = 1

// 每次读取的行数
local read_lines = 1000
local step = `read_lines' - 1

// 终止行
local endline = 0

// 统计总行数
local lines = 0 

while 2 > 1 {
    local startline = `endline' + 1
    local endline = `startline' + `step'
    import delimited `csv_path', varnames(nonames) encoding(UTF-8) rowrange(`startline':`endline')
    // 统计总行数
    local lines = `lines' + _N
    if `step' > _N {
        clear
        continue,break
    }
    clear
}
// 输出数据总行数(含表头)
di "当前 csv 文件总行数(含表头)为:" `lines'
运行结果如下图所示:

2分批统计信息

我们还可以在 Stata 软件中采取编程方式来分批导入数据,每次处理或统计一部分数据,然后累计所有处理(统计)结果即可。已知小李的专利数据集中有一个字段为“省份”,我们就可以使用下面这段代码来统计这份数据中“省份”字段一共出现多少次“浙江省”,即“浙江省”专利数量有多少。代码如下:
clear

// file
local csv_path = "C:\data.csv"

// 初始行
local startline = 1

// 读取行数
local read_lines = 10000
local step = `read_lines' - 1

// 终止行
local endline = 0

// 统计 "浙江省" 专利数量
local zhejiang_lines = 0 

while 2 > 1 {

    local startline = `endline' + 1
    local endline = `startline' + `step'
    import delimited `csv_path', varnames(1) encoding(UTF-8) rowrange(`startline':`endline')
    local now_lines = _N

     // 统计浙江
     keep if regexm(省份, "浙江省") == 1
     local zhejiang_lines = `zhejiang_lines' + _N

     if `step' > `now_lines' {
            clear
            continue,break
        }
        clear
}

di "浙江省专利数量为:" `zhejiang_lines' 
clear
运行结果如下图所示:
老实来说, 这种方式存在不小的局限性,比如当需要使用数据来做回归分析时,我们依然难以实现。

Part5Python 解决方案

与使用 Stata 一样,由于数据量太大,所以处理它的要点在于,完成处理或统计需求的同时避免将数据全部读入内存。

1获取数据量

(1)获取数据行数

 .csv 文件是一种使用特定符号(一般是英文逗号)分隔不同字段的文本数据。所以我们可以使用 Python 自带的文件读取方法 open 即可在不将数据读入内存的前提下获取 csv 的行数,代码如下:
Path = '专利数据.csv' # 数据路径
for count, line in enumerate(open(Path, "rU")):
    # count 表示数据处于csv的第几行,line 是这一行的数据值
    pass         # 每次只读一行数据,但不做任何操作
print(count)     # 输出最终获取到的数据行数(不含表头)
使用以上代码得到小李的数据集行数为 36996264 行,代码运行时间约为 26 秒,效率尚可。最主要的是这种方法几乎不占用内存。

(2)查看数据字段

获取数据字段较为简单的方法就是使用 Pandas 读取前几行数据,这样只需占用极小的内存就可以预览数据字段,代码如下:
import pandas as pd

# 大 csv 数据的存储路径
Path = r'专利数据.csv'
# nrows=5 表示只读取 csv前 5行数据
pd.read_csv(Path, nrows=5)
  
这样就可以看到这个大 .csv 文件的字段内容了。

2处理数据

Pandas 在处理大数据集的问题上有先天优势,在使用 pd.read_csv() 读取数据时传入参数 chunksize 来生成一个 TextFileReader 对象,该对象把一个大数据集分割为若干个小数据块。每个数据块的数据行数就是我们传入的 chunksize 参数值。我们循环读取所有数据块(每次只读取其中一个小数据块到内存中),并统计这个小数据块的数据信息。这样就解决了问题,最后我们累计所有的统计结果就可以完成统计任务了。
统计信息的代码如下:
# 为了节省内存,我们可以只读取需要的字段
# chunksize=100000 表示每次只读 100000 行数据
path = r'专利数据.csv'
DATA = pd.read_csv(path, usecols=['省份'], chunksize=100000)

Counts = dict()  # 创建一个空字典,用于存储各省份专利数量

for data in tqdm(DATA):
    '''从DATA中每次获取一个小数据集'''
    # 每个小数据集分别统计省份专利分布
    counts_dict = data['省份'].value_counts().to_dict()
    for name, num in counts_dict.items():
        if name in Counts.keys():
            Counts[name] += num
        else:
            Counts[name] = num
# 累加得到统计值的总和,可以验证是否统计了全部数据
# 若结果等于大数据集的行数,说明已经统计了全部数据的专利分布
print(sum(list(Counts.values())))  # 输出:36996264
此时所得结果 Counts 是一个字典:
我们将它转化为 DataFrame,代码如下:
array = [[k,v] for k,v in Counts.items()]
Target = pd.DataFrame(array, columns=['省份''专利数量'])
# 根据专利数量排序,由大到小
Target = Target.sort_values(by='专利数量', ascending=False)
Target.head(8)
  
顺便绘制一个专利分布柱状图:
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['KaiTi']  # 设置字体为楷体
plt.rcParams['figure.figsize'] = (10, 5) # 调整生成的图表最大尺寸
plt.rcParams['figure.dpi'] = 500   # 每英寸点数

# 设置横轴标签
xticks_labels = ['\n'.join(N)  for N in Target['省份']]
xticks(np.linspace(0,34,34,endpoint=False), xticks_labels)
# 设置纵轴标签
yticks_labels = ['{}百万'.format(i) if i > 0 else '0' for i in range(0,7)]
yticks(np.linspace(0,6000000,7,endpoint=True), yticks_labels)
# 绘制柱状图
plt.bar(Target['省份'],Target['专利数量']) 
# 设置图标题
plt.title('全国专利分布')
plt.show()
  
PS:Windows 用户可以在任务管理器中,依次点击 左下角【详细信息】—【性能】—【内存】来查看计算机内存的使用率,空间变化等,如下图所示:

Part6总结

处理一个超大的  .csv 文件时,无论是使用 Stata 还是 Python,都需要分批处理,但是使用 Python 应对这种问题会更加轻松,运行速度也会更快。总的来说,Stata 简单易用,Python 功能更全。选择正确的工具可以让我们的工作和学习事半功倍。

我们贴心地为大家准备了团队自制的CSV切分工具,关注本公众号,后台回复“20220520”即可免费获取自制 CSV 切分工具

我们将在数据治理板块中推出一系列原创推文,帮助读者搭建一个完整的社科研究数据治理软硬件体系。该板块将涉及以下几个模块(点击标题即可跳转至相应合集):
  1. 计算机基础知识
  2. 编程基础
  3. 数据采集
  4. 数据存储
  5. 数据清洗
  6. 数据实验室搭建
  7. 数据治理特别篇




星标⭐我们不迷路!想要文章及时到,文末“在看”少不了!

点击搜索你感兴趣的内容吧


往期推荐


基本无害 | 因果识别的比照基准——理想实验(2)

数据治理 | 老生常谈的Pandas绘图还能这么玩?

数据治理 | 随心所欲的Pandas绘图!

基本无害 | 因果识别的比照基准——理想实验(1)

基本无害 | 实证研究中必须要“自问自答”的四个问题

基本无害 | 前言:关于计量的基本观点与本书主要特点

数据治理 | 实操性强的Pandas数据匹配教程!





数据Seminar




这里是大数据、分析技术与学术研究的三叉路口


文 | 《社科领域大数据治理实务手册》


    欢迎扫描👇二维码添加关注    

点击下方“阅读全文”了解更多

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存