在Python中使用尴尬的CSV到2D / 3D列表

时间:2017-10-11 23:46:10

标签: python

我在CSV中有一些数据,如下图所示。我试图将它变成一种合理的形式,所以我可以用#轴[18,22,24]和[58,68,55]绘制共同的x轴[1,2,3]和#39 ; A'和' B'作为传说。

我目前的想法是,尽管我重复了x轴,但以下结构最简单。

[['A',[1,'A1',18],[2,'A2',22],[3,'A3',24]],
 ['B',[1,'B4',58],[2,'B4',68],[3,'B6',55]]]

这是丑陋的数据。你可能会说,A和B是标题。 18对应于点1处的A1,2点对应于点2处的A2,等等。我尝试检查空单元'并插入到当前阵列中,但是它变得非常混乱,我不得不尝试扩展它以便它可以应对50多列和20多行。

,A,B
1,A1,B4
,18,58
2,A2,B5
,22,68
3,A3,B6
,24,55

建议here很有帮助,但我无法应用于我的情况。以下代码适用于一列,但需要进一步操作,并在我向CSV文件添加其他列后发生故障。

import csv

arr = []

datafile = open('datafile1.csv', 'r', newline='')
reader = csv.reader(datafile)
for row in reader:
    if row[0] != "":
        #print(row)
        arr.append(row)
    elif row[1] != "":
        arr[-1].insert(len(arr),row[1])

datafile.close()

提前感谢您提供的任何帮助!

1 个答案:

答案 0 :(得分:0)

如果您想绘制数据,最佳格式是x列表和y列表。当然,还有标签列表。

传说在第一行,所以你可以阅读并完成它。然后读取每两行以提取x和标签数据,然后再次读取每两行,偏移量为1,以读取所有y数据。一些zip()和解包魔法,你已经完成了。

import csv

import matplotlib.pyplot as plt

def load_data(file):
    reader = csv.reader(open(file, 'r', newline=''))
    lines = tuple(reader)

    legends = lines[0][1:]
    x, *labels = zip(*lines[1::2])
    _, *y = zip(*lines[2::2])
    # must convert the data from strings to integers
    # if floats are allowed in the data, use `float` instead
    x = tuple(map(int, x))
    y = tuple(tuple(map(int, column)) for column in y)

    return x, y, legends, labels

def plot_columns(x, y, legends, labels):
    for k in range(len(y)):
        plt.plot(x, y[k])
        for xi, yi, ilabel in zip(x, y[k], labels[k]):
            plt.annotate(ilabel, xy=(xi, yi), textcoords='data')
    plt.legend(legends)
    plt.show()

plot_columns(*load_data('datafiel1.csv'))

如果您使用的是Python 2,则不允许在x, *labels = zip(*lines[1::2])中解压缩。相反,按步骤

执行
# for x and labels
temp = zip(*lines[1::2])
x, labels = temp[0], temp[1:]
# for y
y = zip(*lines[2::2])[1:]