【问题标题】:Awkward CSV to 2D/3D list in PythonPython中尴尬的CSV到2D/3D列表
【发布时间】:2017-10-11 23:46:09
【问题描述】:

我在 CSV 中有一些数据,如下所示。我试图把它变成一个合理的形式,所以我可以用'A'绘制公共 x 轴 [1, 2, 3] 与 y 轴 [18, 22, 24] 和 [58, 68, 55]和“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,22 对应于第 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()

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

【问题讨论】:

  • 如果可能的话,我建议您编辑您的原始数据。目前,行在标签和数据之间交替。这里只有 6 个真实数据点。然后是索引 (1, 2, 3) 和标题 ("A", "B")。
  • 感谢您的回复。不幸的是,我被格式卡住了,这令人沮丧。将它们逐行转储到一个列表中,然后从那里进行操作会更好吗?目前的方法使用 Excel VBA,非常缓慢且繁琐。

标签: python


【解决方案1】:

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

图例在第一行,因此您可以阅读并完成它。然后每两行读取一次以提取 x 和 label 数据,然后每两行再次读取一次,偏移量为 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:]

【讨论】:

  • 效果很好,谢谢!我将如何从脚本中的函数外部访问 xi 和 yi 列表?我想对这些值进行一些数据分析。再次感谢。 :)
  • @PythonicRitual 你可以再次运行类似的循环,因为xiyi 暂时存在。它们只不过是xy[column] 的元素。如果您的意思是一般意义上的xy,您可以像这样简单地存储函数的结果,x, y, legends, labels = load_data(file)。为了简洁起见,我只是嵌套了这两个函数。
猜你喜欢
  • 2012-09-05
  • 2022-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-19
  • 1970-01-01
相关资源
最近更新 更多