【问题标题】:Three way cross matching csv and pulling/printing data in python三路交叉匹配csv和python中的拉/打印数据
【发布时间】:2013-10-09 14:27:12
【问题描述】:

我正在尝试进行三路交叉匹配,匹配文本文件和 CSV 之间的 3 个元素,作为每次匹配的结果,我们将调用/获取某些元素以附加到字符串...

文本文件项应该被两个新行分割/n/n

Textfile item line 1 应该最多匹配 CSV Element 2 中的一行 Textfile item line 2 应该最多匹配 CSV Element 1 中的一行

如果两个匹配都成功,则需要匹配学生姓名,在第一种情况下,“Tommy”与CSV Element 9

一旦所有三个变量都匹配,我们就知道我们在哪一行 CSV 行匹配,现在我们需要记录CSV Element 10,我们还需要从文本文件项中找到“数据 2”

对于接下来的几个名字,我们需要再次全部输入,在我们的第一个示例中是 Jim、Elz M 和 Ben

在运行脚本结束时,我应该能够执行以下操作:

print Match1[0], Match3[0], Match1[0], Data1[0], Data2[0]
print Match1[1], Match3[1], Match1[1], Data1[1]
print Match1[2], Match3[2], Match1[2], Data1[2]

哪个会输出:

DMATCH1 MData (N/A) Tommy 55 Data2 $10.40
DMATCH1 MData (N/A) Jim 52
DMATCH1 MData (N/A) Elz M 22

我的 CSV 看起来像:

MATCH1,MATCH2,TITLE,TITLE,TITLE,TITLE,TITLE,TITLE,MATCH3,DATA,TITLE,TITLE
DMATCH1,MData (N/A),data,data,data,data,data,data,Tommy,55,data,data
DMATCH1,MData (N/A),data,data,data,data,data,data,Ben,54,data,data
DMATCH1,MData (N/A),data,data,data,data,data,data,Jim,52,data,data
DMATCH1,MData (N/A),data,data,data,data,data,data,Elz M,22,data,data
DMATCH2,MData (B/B),data,data,data,data,data,data,James Smith,15,data,data
DMATCH2,MData (B/B),data,data,data,data,data,data,Jessica Long,224,data,data
DMATCH2,MData (B/B),data,data,data,data,data,data,Mike,62,data,data
DMATCH3,Mdata,data,data,data,data,data,data,Joe Reane,66,data,data
DMATCH3,Mdata,data,data,data,data,data,data,Peter Jones,256,data,data
DMATCH3,Mdata,data,data,data,data,data,data,Lesley Lope,5226,data,data

我的文本文件包括:

MData (N/A)
DMATCH1
3 Tommy 144512/23332
1 Jim 90000/222311
1 Elz M 90000/222311
1 Ben 90000/222311
Data $50.90
Data2 $10.40
Data3 $20.20


MData (B/B) 
DMATCH2
4 James Smith 2333/114441
4 Mike 90000/222311
4 Jessica Long 2333/114441
Data $50.90
Data2 $5.44


Mdata
DMATCH3
5 Joe Reane 0/0
5 Peter Jones 90000/222311
Data $10.91
Data2 $420.00
Data3 $210.00

如果它更容易,我可以修改文本文件,使其也是 csv 格式

例子:

MData (N/A),DMATCH1,3 Tommy 144512/23332,1 Jim 90000/222311,1 Elz M 90000/222311,   1 Ben 90000/222311,Data $50.90,Data2 $10.40,Data3 $20.20

【问题讨论】:

  • 最好将其作为单独的表导入 SQLite 并在那里执行连接。这在 Python 中尝试起来非常复杂和复杂。
  • @Makoto 我以为有人会提到使用 SQL 来做到这一点,但不幸的是我不能使用 SQL,除非 python 可以轻松控制并使用 SQLLite 来完全自动化它......

标签: python regex csv python-2.7 match


【解决方案1】:

这将是我的尝试:

from collections import defaultdict
import re

# Nested defaultdict for data structure
def make_map():
    def make_map_dict():
        return defaultdict(dict)
    return defaultdict(make_map_dict)

# Read in the data
with open('/path/to/your/txt_file.txt', 'r') as f:
    txt_data = [map(str.strip, x.split('\n')) for x in map(str.strip, f.read().split('\n\n')) if x]

with open('/path/to/your/csv_file.csv', 'r') as f:
    header = f.readline()
    csv_data = [map(str.strip, x.split(',')) for x in map(str.strip, f.read().split('\n')) if x]

# Generate a mapping dictionaries
txt_map = defaultdict(make_map)
csv_map = defaultdict(make_map)

# Regex matches
name_re = re.compile(r'^(\d+) +(\w+(?: \w+)*) +(\d+/\d+)$')
data_re = re.compile(r'^(Data(?:\d+)?) +(\$\d+(?:\.\d{2})?)$')

# Make txt mapping
for datapoint in txt_data:
    names = [name_re.match(x).group(2) for x in datapoint[2:] if name_re.match(x)]
    data = {data_re.match(x).group(1): data_re.match(x).group(2) for x in datapoint[2:] if data_re.match(x)}
    for name in names:
        txt_map[datapoint[1]][datapoint[0]][name] = data

# Make csv mapping
for datapoint in csv_data:
    csv_map[datapoint[0]][datapoint[1]][datapoint[8]] = [datapoint[9]]

# Merge maps
final_map = defaultdict(make_map)
for x in txt_map:
    for y in txt_map[x]:
        for z in txt_map[x][y]:
            if csv_map[x][y][z] is not None:
                final_map[x][y][z] = csv_map[x][y][z] + [txt_map[x][y][z]]

# You now have final_map to do with what you will

这为您留下了一个嵌套的数据结构。如果需要,您可以将其展平并zip。希望对您有所帮助!

【讨论】:

  • Traceback(最近一次调用最后):文件“C:\test.py”,第 13 行,在 txt_data = [map(str.strip, x.split('\n' )) for x in map(str.strip, f.readall().split('\n\n')) if x] AttributeError: 'file' object has no attribute 'readall' 有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-18
  • 1970-01-01
相关资源
最近更新 更多