【问题标题】:Matching three variables from textfile to csv and writing variables to the csv on matched rows将文本文件中的三个变量匹配到 csv 并将变量写入匹配行的 csv
【发布时间】:2013-10-04 04:55:35
【问题描述】:

我正在寻找一些帮助,循环遍历我的文本文件中的每个组,并将三个变量与我的 csv 匹配,如果匹配成功,它将向 csv 文件写入一些新变量:

在文本文件第 1 行匹配 csv 元素 1 在文本文件第 2 行匹配 csv 元素 0

每个学生将分为三个部分: 3Tommy144512/23332 和第 1 部分和第 3 部分将分别写入元素 12 和 13。第 2 部分将用于第三次匹配,匹配 csv 元素 8 这是找出写入哪一行。

“数据”将被写入元素 14(第 15 列) “misc3”将被写入元素 15(第 16 列) "bla3" 将被写入元素 16(第 17 列)

注释文本文件:

     Textfile Item 1 (Will loop/cycle/run 4 times, because there are 4 students)
           |
           v

MData (N/A)                <-- Match Line 1 (matches to csv element 1)
DMATCH1                    <-- Match Line 2 (matches to csv element 0)
3 Tommy 144512/23332       <-- Match Line 3 (matches to csv element 8) (Loop 1)                 
1 Jim 90000/222311     <-- Match Line 3 (matches to csv element 8) (Loop 2)
1 Elz M 90000/222311       <-- Match Line 3 (matches to csv element 8) (Loop 3)
1 Ben 90000/222311         <-- Match Line 3 (matches to csv element 8) (Loop 4)
Data $50.90                <-- If "Data" Exists then filewrite to csv element 14 (Loop 1)   
misc2 $10.40               <-- If "misc2" Exists then filewrite to csv element 15 (Loop 1)
bla3 $20.20               <-- If "bla3" Exists then filewrite to csv element 16 (Loop 1)


     Textfile Item 2 (Will loop/cycle/run 2 times, because there are 3 students)
           |
           v

MData (B/B)                <-- Match Line 1 (matches to csv element 1)
DMATCH2                    <-- Match Line 2 (matches to csv element 0)
4 James Smith 2333/114441  <-- Match Line 3 (matches to csv element 8) (Loop 1)
4 Mike 90000/222311        <-- Match Line 3 (matches to csv element 8) (Loop 2)
4 Jessica Long 2333/114441 <-- Match Line 3 (matches to csv element 8) (Loop 3)
Data $50.90                <-- If "Data" Exists then filewrite to csv element 14 (Loop 1)   
bla3 $5.44                <-- If "bla3" Exists then filewrite to csv element 16 (Loop 1)


     Textfile Item 3 (Will loop/cycle/run 2 times, because there are 2 students)
           |
           v

Mdata                      <-- Match Line 1 (matches to csv element 1)
DMATCH3                    <-- Match Line 2 (matches to csv element 0)
5 Joe Reane 0/0            <-- Match Line 3 (matches to csv element 8) (Loop 1)
5 Peter Jones 90000/222311 <-- Match Line 3 (matches to csv element 8) (Loop 2)
misc2 $420.00              <-- If "misc2" Exists then filewrite to csv element 15 (Loop 1)
bla3 $210.00               <-- If "bla3" Exists then filewrite to csv element 16 (Loop 1)

未注释的真实文本文件:

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


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


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

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

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,3,144512/23332,Data $50.90,misc2 $10.40,bla3 $20.20
DMATCH1,MData (N/A),data,data,data,data,data,data,Ben,54,data,data,1,90000/222311,,,
DMATCH1,MData (N/A),data,data,data,data,data,data,Jim,52,data,data,1,90000/222311,,,
DMATCH1,MData (N/A),data,data,data,data,data,data,Elz M,22,data,data,1,90000/222311,,,
DMATCH2,MData (B/B),data,data,data,data,data,data,James Smith,15,data,data,4,2333/114441,Data $50.90,,bla3 $5.44
DMATCH2,MData (B/B),data,data,data,data,data,data,Jessica Long,224,data,data,4,2333/114441,,,
DMATCH2,MData (B/B),data,data,data,data,data,data,Mike,62,data,data,4,90000/222311,,,
DMATCH3,Mdata,data,data,data,data,data,data,Joe Reane,66,data,data,5,0/0,,misc2 $420.00,bla3 $210.00
DMATCH3,Mdata,data,data,data,data,data,data,Peter Jones,256,data,data,5,90000/222311,,,
DMATCH3,Mdata,data,data,data,data,data,data,Lesley Lope,5226,data,data,,,,,

有人知道如何实现吗?

任何帮助将不胜感激!

【问题讨论】:

    标签: python csv


    【解决方案1】:

    这个问题实际上有几个子问题。首先我们必须阅读格式有趣的文本文件:

    读取匹配器文本文件

    # each block in the text file will be one element of this list
    matchers = [[]]
    i = 0 
    with open('test.txt') as infile:
        for line in infile:
            line = line.strip()
            # Blocks are seperated by blank lines
            if len(line) == 0:
                i += 1
                matchers.append([])
                # assume there are always two blank lines between items 
                # and just skip to the lext line
                infile.next()
                continue
            matchers[i].append(line)
    

    此时我们有一个列表列表,每个块一个元素,每一行包含一个元素。然后我们必须转换成更像表格的东西

    转换成表格格式

    import re
    
    # This regular expression matches the variable number of students in each block
    studentlike = re.compile('(\d+) (.+) (\d+/\d+)')
    # We will build a table containing a list of elements for each student
    table = []
    for matcher in matchers:
        # We use an iterator over the block lines to make indexing simpler
        it = iter(matcher)
        # The first two elements are match values
        m1, m2 = it.next(), it.next()
        # then there are a number of students
        students = []
        for possiblestudent in it:
            m = studentlike.match(possiblestudent)
            if m:
                students.append(list(m.groups()))
            else:
                break
        # After the students come the data elements, which we read into a dictionary
        # We also add in the last possible student line as that didn't match the student re
        dataitems = dict(item.split() for item in [possiblestudent] + list(it))
        datanames = dataitems.keys()
        # Finally we construct the table
        for student in students:
            # We use the dictionary .get() method to return blanks for the missing fields
            table.append([m1, m2] + student + [dataitems.get(d, '') for d in datanames])
    print table
    

    加入熊猫

    现在,我们可以合并数据了。我在这里使用过 Pandas,因为它非常适合这种加入:

    import pandas
    csvdata = pandas.read_csv('test.csv')
    textdata = pandas.DataFrame(table, columns=['MATCH2', 'MATCH1', 'TITLE01', 'MATCH3', 'TITLE02', 'Data', 'misc2', 'bla3'])
    mergeddata = pandas.merge(csvdata, textdata, how='left', on=['MATCH1', 'MATCH2', 'MATCH3'], sort=False)
    mergeddata.to_csv('output.csv', index=False)
    

    【讨论】:

    • 效果惊人,请问您是否可以评论一下,因为有很多部分我不明白他们是如何做他们正在做的事情......
    • 我添加了 cmets。如果还有其他东西你还没有得到,请随时直接询问。
    • 谢谢你,它工作得很好但是我遇到了一个问题,例如带有美元或其他符号的字符串:Data £1.00 将显示为:Data £1.00 如何绕过/绕过这个?
    • 这是一个编码问题。您将必须找出您使用的编码。 This table 对此很有用。看起来好像您的数据是在 Windows 1252 中编码的,但 Python 将其读取为 UTF-8。修复基本文件中的编码,问题应该会消失。
    • 如果我运行两次(往返于同一个文件)覆盖/更新任何旧值而不是写入新列,是否知道如何使它匹配同一列?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-27
    • 2013-11-03
    • 1970-01-01
    • 2015-08-08
    • 2023-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多