【问题标题】:Is there a function to concatenate two header rows into one?是否有将两个标题行连接为一个的功能?
【发布时间】:2019-10-22 09:32:53
【问题描述】:

考虑以下文本文件摘录

Distance,Velocity,Time
(m),(m/s),(s)
1,1,1
2,1,2
3,1,3

我希望它变成这样:

Distance(m),Velocity(m/s),Time(s)
1,1,1
2,1,2
3,1,3

换句话说,我想连接包含文本的行,并且我希望它们按列连接。

我最初是在处理从软件生成的文本文件。我已成功地将其转换为 csv 格式的数字列及其标题。但我每列都有多个标题。而且我需要每个标题行中的所有信息,因为列属性因文件而异。我怎样才能在 python 中以一种聪明的方式做到这一点?

edit:谢谢你的建议,对我帮助很大。我使用了 Daweos 解决方案,并添加了动态行数,因为标题行的数量可能从 2 到 7 不等,具体取决于生成的输出。这是我最终得到的代码 sn-p。

# Get column headers
a = 0
header_rows= 0
with open(full,"r") as input: 
    Lines= ""

    for line in input:
        l = line
        g = re.sub(' +',' ',l)
        y = re.sub('\t',',',g)
        numlines += 1
        if len(l.encode('ANSI')) > 250:
            # finds header start row
            a += 1               
        if a>0:
            # finds header end row
            if "---" in line:
                header_rows = numlines - (numlines-a+1)
                break
            else:
          #     Lines is my headers string
                Lines = Lines + "%s" % (y) + ' '
    output.close()

# Create concatenated column headers 
rows = [i.split(',') for i in Lines.rstrip().split('\n')]
cols = [list(c) for c in zip(*rows)]
for i in (cols):
    for j in (rows):
        newcolz = [list(c) for c in zip(*rows)]
print(newcolz)

【问题讨论】:

  • 到目前为止你尝试了什么?
  • 您好,请查看已编辑的帖子。

标签: python string csv concatenation


【解决方案1】:

我会这样做:

txt = " Distance,Velocity,Time \n (m),(m/s),(s) \n 1,1,1 \n 2,1,2 \n 3,1,3 \n "
rows = [i.split(',') for i in txt.rstrip().split('\n')]
cols = [list(c) for c in zip(*rows)]
newcols = [[i[0]+i[1],*i[2:]] for i in cols]
newrows = [','.join(i) for i in zip(*newcols)]
print(newtxt)

输出:

 Distance (m),Velocity(m/s),Time (s)
 1,1,1
 2,1,2
 3,1,3

这里的关键是使用zip 转置您的数据,因此我可以处理列而不是行。 [[i[0]+i[1],*i[2:]] for i in cols] 负责实际的连接,所以如果你的标题跨越 3 行,你可以做 [[i[0]+i[1]+i[2],*i[3:]] for i in cols] 等等。

【讨论】:

    【解决方案2】:

    我不知道有什么可以做到这一点,所以你可以编写一个自定义函数。在下面的示例中,该函数采用字符串以及默认为, 的分隔符。

    它将每个字符串拆分为一个列表,然后使用 zip 使用列表推导来配对列表。然后加入对。

    最后它会用分隔符再次加入合并的标题。

    def concat_headers(header1, header2, seperator=","):
        headers1 = header1.split(seperator)
        headers2 = header2.split(seperator)
        consolidated_headers = ["".join(values) for values in zip(headers1, headers2)]
        return seperator.join(consolidated_headers)
    
    
    data = """Distance,Velocity,Time\n(m),(m/s),(s)\n1,1,1\n2,1,2\n3,1,3\n"""
    header1, header2, *lines = data.splitlines()
    consolidated_headers = concat_headers(header1, header2)
    print(consolidated_headers)
    print("\n".join(lines))
    

    输出

    Distance(m),Velocity(m/s),Time(s)
    1,1,1
    2,1,2
    3,1,3
    

    【讨论】:

    • 太好了,谢谢。我添加了一个基本上是您的解决方案的解决方案。
    【解决方案3】:

    您实际上并不需要一个函数来完成它,因为它可以使用 csv 模块来完成:

    import csv
    
    data_filename = 'position_data.csv'
    new_filename = 'new_position_data.csv'
    
    with open(data_filename, 'r', newline='') as inp, \
         open(new_filename, 'w', newline='') as outp:
        reader, writer = csv.reader(inp), csv.writer(outp)
        row1, row2 = next(reader), next(reader)
        new_header = [a+b for a,b in zip(row1, row2)]
        writer.writerow(new_header)
        # Copy the rest of the input file.
        for row in reader:
            writer.writerow(row)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-13
      • 2018-12-24
      相关资源
      最近更新 更多