python - 有效地将具有反向字典的文件读取到DataFrame
问题描述
我有一堆具有这种结构的 20MB 文本文件:
{'col-1': ['data-11', 'data-12'], 'col-2': [1, 2], 'col-n': [1, 2]}
{'col-1': ['data-21', 'data-22'], 'col-2': [1, 2], 'col-n': [1, 2]}
{'col-1': ['data-31', 'data-32', 'data-33'], 'col-2': [1, 2, 3], 'col-n': [1, 2, 3]}
...
每行中的许多记录行各不相同。
我想读为:
col-1 col-2 col-n
0 data-11 1 1
1 data-12 2 2
2 data-21 1 1
3 data-22 2 2
4 data-31 1 1
5 data-32 2 2
6 data-33 3 3
我已经准备了这样的代码,它工作得很好:
import ast
import pandas as pd
import itertools
def _eval(line: str):
''' Turns: {'col-1': ['data-11', 'data-12'], 'col-2': [1, 2], 'col-n': [1, 2]}
Into: [{'col-1': 'data-11', 'col-2': 1, 'col-n': 1}, {'col-1': 'data-12', 'col-2': 2, 'col-n': 2}]
'''
try:
v = ast.literal_eval(line.rstrip()) # Reads line to dict
v = [{k: v[k][i] for k in v} for i in range(len(v['col-n']))] # Revers dict, by splitting them and rejoin
return v
# In case of file structure error
except Exception as e:
print('err', e)
return []
def read_structure(fp):
with open(fp) as fh:
return pd.DataFrame(itertools.chain(*list(map(_eval, fh.readlines()))))
但必须有更好的方法。使用 itertools 和 map 我已经不到 5 秒了。
我想要:
A)优化循环时刻v = [{k: v[k][i] for k in v} for i in range(len(v['col-n']))]
B)知道是否已经有可以读取这种结构的pandas方法(我已经搜索并尝试了所有具有不同参数的read_dict和records方法)
C) 优化它。
该函数已经在线程中运行,因此多线程/处理不是一个最佳主意。
解决方案
首先,我会尽量避免readlines
将整个文件作为行列表加载到内存中。然后我会尝试为 Dataframe 构造函数提供一个列表字典:
def read_structure(fp):
cols = 'col-1', 'col-2', 'col-n' # declare the column names
data = {col: [] for col in cols} # initialize the data structure
with open(fp) as fh:
for i, line in enumerate(io.StringIO(t), 1):
try:
row = ast.literal_eval(line)
for k, v in row.items():
data[k].extend(v)
except Exception as e:
print('Error line', i, line, e)
raise # unsure that we can continue after an error
return pd.DataFrame(data)
不确定它是否很快,但至少它很简单
推荐阅读
- python - 在 MacOs Mojave 上创建 OpenGL 窗口后尝试使用 tk.Tk() 时 Python 崩溃
- r - R tidyverse,统一后整理
- yii2 - Yii2. 如何构建子表达式
- python-3.x - 从两列中识别 txt 中的字符串
- unity3d - 确定 Quad Sphere Face 边缘的 Quad Tree 邻居的有效方法?
- html - 将 XML 转换为 HTML
- java - Selenium - Java - ChromeDriver:打开空白“数据”;在某些情况下,在打开另一个运行实际测试的 chrome 窗口之前?
- css - Chrome中的剪辑路径水平白线
- javascript - 用于 Angular 测试的 JS 堆内存不足
- javascript - 如果不在焦点上,Google 自动完成输入不起作用