使用Python将列名称与CSV文件中的数据对齐

时间:2013-09-20 08:20:46

标签: python csv

这是我用来将数据写入.csv文件的代码。

with open('temp.csv', 'a') as fp:
        a = csv.writer(fp, delimiter='\t')
        data = [['faceXpos','faceYpos','faceHeight','faceWidth','imageViewHeight','imageViewWidth','tshirtXpos', 'tshirtYpos','tshirtWidth','tshirtHeight'],
                [faceXpos, faceYpos, faceHeight, faceWidth, imageViewHeight, imageViewWidth, tshirtXpos, tshirtYpos, tshirtWidth, tshirtHeight]]
        a.writerows(data)

输出如下:

faceXpos    faceYpos    faceHeight  faceWidth   imageViewHeight imageViewWidth  tshirtXpos  tshirtYpos  tshirtWidth tshirtHeight
118 432 84  84  568 320 13.0    136 294.0   346.0
faceXpos    faceYpos    faceHeight  faceWidth   imageViewHeight imageViewWidth  tshirtXpos  tshirtYpos  tshirtWidth tshirtHeight
117.4   433.81  82.35999    82.36   568 320 14.45   134.19  288.26  340.09

如何对齐它以使每列下的数据以更易于阅读的方式完美对齐?期望的输出:(即使数据位于列的中心也没问题)

  faceXpos  faceYpos    faceHeight  faceWidth   imageViewHeight imageViewWidth  tshirtXpos  tshirtYpos  tshirtWidth tshirtHeight
  118       432         84          84          568             320             13.0        136         294.0       346.0

3 个答案:

答案 0 :(得分:5)

首先,您需要的是“固定宽度文件”,而不是CSV。

有一个名为prettytable的模块可以帮助您:

from prettytable import PrettyTable

# Initialize the object passing the table headers
t = PrettyTable(['A', 'B', 'C'])

t.align='l'
t.border=False

t.add_row([111,222,333])
t.add_row([444,555,666])
t.add_row(['longer text',777,'even longer text here'])

print str(t)

输出:

 A            B    C
 111          222  333
 444          555  666
 longer text  777  even longer text here

答案 1 :(得分:2)

这有点棘手,因为CSV编写器不直接支持结构化和格式化输出。如果你编写自己的输出例程,这将是最简单的。 例如:

fp = open('temp.csv', 'a')
labelLine = list()
valueLine = list()
for label, value in zip(*data):  # unzips the list, so each elements (label and value) get extracted pairwise
    padding = max(len(str(label)), len(str(value)))  # what is longer, the label or the value?
    labelLine.append('{0:<{1}}'.format(label, padding))  # generate a string with the variable whitespace padding
    valueLine.append('{0:<{1}}'.format(value, padding))  # generate a string with the variable whitespace padding
# now write everything to the file:
fp.write('\t'.join(labelLine) + '\n')
fp.write('\t'.join(valueLine) + '\n')
fp.close()

这给出了以下输出:

faceXpos    faceYpos    faceHeight  faceWidth   imageViewHeight imageViewWidth  tshirtXpos  tshirtYpos  tshirtWidth tshirtHeight
118         432         84          84          568             320             13.0        136         294.0       346.0       

但是,您必须小心,因为现在您的数据仍未分离,但您的CSV阅读器必须剥离额外的空白。你可以用''.join替换'\ t'.join,如果你可以用普通的空白分隔。

我希望有帮助:) 最好的问候

答案 2 :(得分:1)

由于prettytable暂时没有更新,我想向tabulate添加一个点头。我个人非常喜欢这个,因为它与数据科学包numpypandas很好地配合,因此您可以根据需要构建数据并获得表格表示,而不用大惊小怪。

以下是numpy的示例:

data = numpy.array([[1.,2.,3.,4.],[5.,6.,7.,8.],"here's some loooooooooooooong text".split(' ')]).T
table = tabulate.tabulate(data, tablefmt='fancy_grid', floatfmt=['0.2E', '0.4e', ''])
print(table)

╒══════════╤════════════╤═══════════════════╕
│ 1.00E+00 │ 5.0000e+00 │ here's            │
├──────────┼────────────┼───────────────────┤
│ 2.00E+00 │ 6.0000e+00 │ some              │
├──────────┼────────────┼───────────────────┤
│ 3.00E+00 │ 7.0000e+00 │ loooooooooooooong │
├──────────┼────────────┼───────────────────┤
│ 4.00E+00 │ 8.0000e+00 │ text              │
╘══════════╧════════════╧═══════════════════╛

和一个pandas

dates = pandas.date_range('20180101', periods=4)
data = numpy.vstack([numpy.random.randn(4,4), numpy.array("here's some loooooooooooooong text".split(' '))]).T
df = pandas.DataFrame(data, index=dates, columns=list(' ABCD'))  # Blank first column for the index column
df.index = df.index.strftime('%Y-%m-%d')
df.index.name = 'dates'
df = df.reindex(['B', 'D', 'A', 'C'], axis=1)
# table = df.to_string()  # Default pandas string representation
table = tabulate.tabulate(df, tablefmt='presto', headers=[df.index.name] + df.columns.tolist(),
                          floatfmt=['', '0.4f', '', '', '0.2e'], numalign='right', stralign='center')
print(table)

   dates    |       B |         D         |                   A |         C
------------+---------+-------------------+---------------------+-----------
 2018-01-01 |  0.8080 |      here's       |  1.5430201221283801 |  8.81e-01
 2018-01-02 | -1.0354 |       some        | -1.0642628831039138 | -2.29e-01
 2018-01-03 |  1.6243 | loooooooooooooong | -0.8030183690980672 |  6.67e-01
 2018-01-04 |  0.4356 |       text        |  -1.957887025379132 | -1.37e+00

我还使用tablefmt='plain'关键字参数来获取空格分隔值(ssv)文件的固定宽度格式,以便在文本编辑器中查看。

另外值得注意的是astropy.io.ascii,但在许多方面,它并不像tabulate那样易于使用或可自定义。

astropy.io.ascii.write(astropy.io.ascii.read(df.to_csv(), format='csv', header_start=0), format='fixed_width', formats={'C': '0.2e', 'B': '0.4f'})

|      dates |       B |                 D |               A |         C |
| 2018-01-01 |  0.8080 |            here's |   1.54302012213 |  8.81e-01 |
| 2018-01-02 | -1.0354 |              some |   -1.0642628831 | -2.29e-01 |
| 2018-01-03 |  1.6243 | loooooooooooooong | -0.803018369098 |  6.67e-01 |
| 2018-01-04 |  0.4356 |              text |  -1.95788702538 | -1.37e+00 |