我有一个var entryPoint = (from U in Users
join ud in UserDistricts on U.UserID equal ud.UserID
join d in Districts on d.DistrictID equals ud.DistrictID
where ud.UserID == U.UserID
select new {
DistrictId = ud.DistrictId,
DistrictName= d.DistrictName,
UserID= U.UserID
}).ToList();
来保存一些操作的结果。数据显示在text file
(如表格)中。如何解析此数据,以便我可以使用此数据形成human-readable format
等数据结构?
dictionaries
的示例如下所示。
unstructured data
以上示例中显示的数据不是===============================================================
Title
===============================================================
Header Header Header Header Header Header
1 2 3 4 5 6
---------------------------------------------------------------
1 Yes No 6 0001 0002 True
2 No Yes 7 0003 0004 False
3 Yes No 6 0001 0001 True
4 Yes No 6 0001 0004 False
4 No No 4 0004 0004 True
5 Yes No 2 0001 0001 True
6 Yes No 1 0001 0001 False
7 No No 2 0004 0004 True
或tab-separated
。它始终具有comma separated
,并且相应地可能/可能不具有header
外观的值。
我尝试使用基本的解析技术,例如column-like
和regex
,但我需要一种更健壮的方法来解析这些数据,因为上面显示的示例并不是数据呈现的唯一格式。
更新1 :除了显示的示例之外还有很多情况,例如添加更多列,单个单元格有多个实例(但在下一行可视化显示,而它属于上一个行)。
是否有conditional checks
库来解决此问题?
python
技术可以在没有解析的情况下帮助解决这个问题吗?如果是,那将是什么类型的问题(分类,回归,聚类)?
machine learning
Update 2 :另一个例子,它可能看起来像一个单元格有多个实例(但在下一行可视化,但它属于前一行)。
答案 0 :(得分:3)
假设你的例子是'sample.txt'。
import pandas as pd
df = pd.read_table('sample.txt', skiprows=[0, 1, 2, 3, 5], delimiter='\s\s+')
print(df)
print(df.shape)
1 2 3 4 5 6
0 1 Yes No 6 0001 0002 True
1 2 No Yes 7 0003 0004 False
2 3 Yes No 6 0001 0001 True
3 4 Yes No 6 0001 0004 False
4 4 No No 4 0004 0004 True
5 5 Yes No 2 0001 0001 True
6 6 Yes No 1 0001 0001 False
7 7 No No 2 0004 0004 True
(8, 6)
您可以更改当然的数据类型。请检查pd.read_table()
params的吨数。此外,xlsx,csv,html,sql,json,hdf甚至剪贴板等都有method。
欢迎来到pandas ...
答案 1 :(得分:0)
我不知道你想对标题做什么,所以我会继续跳过所有6行......空间不一致所以你需要先让记录之间的空间保持一致,否则很难阅读它逐行。 你可以做这样的事情
import re
def read_file():
with open('unstructured-data.txt', 'r') as f:
for line in f.readlines()[6:]:
line = re.sub(" +", " ", line)
print(line)
record = line.split(" ")
print(record)
read_file()
会给你这样的东西
1 Yes No 6 0001 0002 True
['1', 'Yes', 'No', '6', '0001', '0002', 'True', '\n']
2 No Yes 7 0003 0004 False
['2', 'No', 'Yes', '7', '0003', '0004', 'False', '\n']
3 Yes No 6 0001 0001 True
['3', 'Yes', 'No', '6', '0001', '0001', 'True', '\n']
4 Yes No 6 0001 0004 False
['4', 'Yes', 'No', '6', '0001', '0004', 'False', '\n']
4 No No 4 0004 0004 True
['4', 'No', 'No', '4', '0004', '0004', 'True', '\n']
5 Yes No 2 0001 0001 True
['5', 'Yes', 'No', '2', '0001', '0001', 'True', '\n']
6 Yes No 1 0001 0001 False
['6', 'Yes', 'No', '1', '0001', '0001', 'False', '\n']
7 No No 2 0004 0004 True
['7', 'No', 'No', '2', '0004', '0004', 'True\n']
答案 2 :(得分:0)
试试这个,它应该完全处理多行单元格:
import re
def splitLine(line, delimiters):
output = []
for start, end in delimiters:
output.append(line[start:end].strip())
return output
with open("path/to/the/file.ext", "r") as f:
_ = f.readline()
_ = f.readline()
_ = f.readline()
headers = [f.readline()]
next = f.readline()
while(next[0] != "-"):
headers.append(next)
next = f.readline()
starts = []
columnNames = set(headers[0].split())
for each in columnNames:
starts.extend([i for i in re.finditer(each, headers[0])])
starts.sort()
delimiters = list(zip(starts, starts[1:] + [-1]))
if (len(columnNames) - 1):
rowsPerEntry = len(headers)
else:
rowsPerEntry = 1
headers = [splitLine(header, delimiters) for header in headers]
keys = []
for i in range(len(starts)):
if ("Header" == headers[0][i]):
keys.append(headers[1][i])
else:
keys.append([])
for header in headers:
keys[-1].append(header[i])
entries = []
rows = []
for line in f:
rows.append(splitLine(line, delimiters))
if (rowsPerEntry == len(rows)):
if (1 == rowsPerEntry):
entries.append(dict(zip(keys, rows[0])))
else:
entries.append({})
for i, key in enumerate(keys):
if (str == type(key)):
entries[-1][key] = rows[0][i]
else:
k = "Column " + str(i+1)
entries[-1][k] = dict.fromkeys(key)
for j, subkey in enumerate(key):
entries[-1][k][subkey] = rows[j][i]
rows = []
我们使用re
模块来查找第4列中的“Header”外观。
splitLine(line, delimiters)
辅助函数返回由delimiters参数定义的列拆分的行数组。此参数是2项元组的列表,其中第一项表示起始位置,第二项表示结束位置。