使用 python 透视 CSV 字符串,而无需使用 pandas 或任何类似的库



你可能会认为这个问题是另一个多余的问题,但我试图通过所有类似的问题,到目前为止没有运气。在我的特定用例中,我不能使用 pandas 或任何其他类似的库进行此操作。

这是我的输入的样子

AttributeName,Value
Name,John
Gender,M
PlaceofBirth,Texas
Name,Alexa
Gender,F
SurName,Garden

这是我的预期输出

Name,Gender,Surname,PlaceofBirth
John,M,,Texas
Alexa,F,Garden,

到目前为止,我已经尝试将我的输入存储到字典中,然后尝试将其写入 csv 字符串。但是,它失败了,因为我不确定如何合并缺少的列值条件。这是我到目前为止的代码

  reader = csv.reader(csvstring.split('n'), delimiter=',')
  csvdata = {}
  csvfile = ''
  for row in reader:
    if row[0] != '' and row[0] in csvdata and row[1] != '':
      csvdata[row[0]].append(row[1])
    elif row[0] != '' and row[0] in csvdata and row[1] == '':
      csvdata[row[0]].append(' ')
    elif row[0] != '' and row[1] != '':
      csvdata[row[0]] = [row[1]]
    elif row[0] != '' and row[1] == '':
      csvdata[row[0]] = [' ']
    
  for key, value in csvdata.items():
    if value == ' ':
      csvdata[key] = []
  csvfile += ','.join(csvdata.keys()) + 'n'
  for row in zip(*csvdata.values()):
    csvfile += ','.join(row) + 'n'

对于上面的代码,我在这里也得到了一些帮助。提前感谢您的任何建议/建议。

编辑#1:更新代码以暗示我正在对csv字符串而不是csv文件进行处理。

你需要的是

这样的东西:

import csv
with open("in.csv") as infile:
    buffer = []
    item = {}
    lines = csv.reader(infile)
    for line in lines:
        if line[0] == 'Name':
            buffer.append(item.copy())
            item = {'Name':line[1]}
        else:
            item[line[0]] = line[1]
    buffer.append(item.copy())
for item in buffer[1:]:
    print item

如果没有一个属性是强制性的,我认为@framontb解决方案需要重新排列,以便在没有给出Name字段时也能工作。
这是一个免进口的解决方案,它不是超级优雅。

我假设您已经有这种形式的行,其中包含此列:

lines = [
    "Name,John",
    "Gender,M",
    "PlaceofBirth,Texas",
    "Gender,F",
    "Name,Alexa",
    "Surname,Garden"  # modified typo here: SurName -> Surname
]
cols = ["Name", "Gender", "Surname", "PlaceofBirth"]

我们需要区分一条记录和另一条记录,如果没有必填字段,我能做的最好的事情就是在已经看到属性时开始考虑新记录。
为此,我使用了一个临时属性列表tempcols从中删除元素,直到引发错误,即新记录。

法典:

csvdata = {k:[] for k in cols}
tempcols = list(cols)
for line in lines:
    attr, value = line.split(",")
    try:
        csvdata[attr].append(value)
        tempcols.remove(attr)
    except ValueError:
        for c in tempcols:  # now tempcols has only "missing" attributes 
            csvdata[c].append("")
        tempcols = [c for c in cols if c != attr]
for c in tempcols:
    csvdata[c].append("")
# write csv string with the code you provided
csvfile = ""
csvfile += ",".join(csvdata.keys()) + "n"
for row in zip(*csvdata.values()):
    csvfile += ",".join(row) + "n"
>>> print(csvfile)
Name,PlaceofBirth,Surname,Gender
John,Texas,,M
Alexa,,Garden,F

同时,如果要根据所需的输出对列进行排序:

csvfile = ""
csvfile += ",".join(cols) + "n"
for row in zip(*[csvdata[k] for k in cols]):
    csvfile += ",".join(row) + "n"
>>> print(csvfile)
Name,Gender,Surname,PlaceofBirth
John,M,,Texas
Alexa,F,Garden,

这对我有用:

with open("in.csv") as infile, open("out.csv", "w") as outfile:
    incsv, outcsv = csv.reader(infile), csv.writer(outfile)
    incsv.__next__()  # Skip 1st row
    outcsv.writerows(zip(*incsv))

更新:对于字符串形式的输入和输出:

import csv, io
with io.StringIO(indata) as infile, io.StringIO() as outfile:
    incsv, outcsv = csv.reader(infile), csv.writer(outfile)
    incsv.__next__()  # Skip 1st row
    outcsv.writerows(zip(*incsv))
    print(outfile.getvalue())

相关内容

最新更新