python - 在不加载完整内容的情况下找出 csv 中行数的最佳方法
问题描述
过去几天我在工作中处理了很多 4-5 Gb 的 csv 文件,因此我知道它们通过读/写取得了多少进展,我在 pandas 的方法之上编写了几个包装函数。这一切似乎工作得很好,有点开销,但方便超过了大多数问题。
同时,在读取 csv 时,为了让进度条显示正确的百分比,我需要提前知道行数,因为这决定了会有多少块。我想出的最简单的解决方案是在开始加载其余部分并获取其大小之前简单地加载 csv 的第 0 列。但是,当您拥有数百万行大小的文件时,这确实需要一些时间。
此外,读取单列占用的总时间比例高得不合理:读取具有 125 列、几百万行的 csv 中的单列大约需要 24 秒,读取整个文件需要 63 秒。
这是我用来读取 csvs 的函数:
def read_csv_with_progressbar(filename: str,
chunksize: int = 50000) -> pd.DataFrame:
length = pd.read_csv(filename, usecols=[0])
length = length.values.shape[0]
total = length//chunksize
chunk_list = []
chunks = pd.read_csv(filename, chunksize=chunksize)
with tqdm(total=total, file=sys.stdout) as pbar:
for chunk in chunks:
chunk_list.append(chunk)
pbar.set_description('Reading source csv file')
pbar.update(1)
df = pd.concat([i for i in chunk_list], axis=0)
return df
有什么方法可以比使用我有缺陷的方法更快地获取 csv 中的行数?
解决方案
假设您的 CSV 文件中没有带引号的字符串(其中包含换行符)或其他恶作剧,一个准确(但很老套)的解决方案是甚至不解析文件,而只是计算文件中换行符的数量:
chunk = 1024*1024 # Process 1 MB at a time.
f = np.memmap("test.csv")
num_newlines = sum(np.sum(f[i:i+chunk] == ord('\n'))
for i in range(0, len(f), chunk))
del f
推荐阅读
- docker - 使用 Docker 在 Bamboo 上运行 Selenium Grid
- git - 如何通过 ssh 获取托管在 Azure DevOps Repo 中的 Terraform 模块
- xamarin.forms - Xamarin SkiaSharp:在不同的屏幕分辨率上绘图
- reactjs - Highcharts-react(堆积图)未正确更新系列
- android - 在片段之间导航后,Android Recycleview Selection 停止正常工作
- eclipse - 为什么放弃对 Eclipse Yocto 插件的支持
- node.js - 在 nginx 高山映像上安装节点 15
- javascript - 如何将js函数变量传递给ajax
- reactjs - 为什么我的号码在 React 中似乎是一个对象?
- excel - 如何使用excel中结构化引用表的特定连续列在vba中设置范围?