【问题标题】:CDF Cumulative Distribution Function ErrorCDF 累积分布函数误差
【发布时间】:2014-09-11 15:36:18
【问题描述】:

我正在尝试为多列数据文件中的一列绘制 CDF。当数据文件中只有一列时,它绘制得很好。当我尝试从数据中获取特定列时,它给了我错误。我还尝试使用 for 循环来读取它读得很好的特定列。如果我在 for 循环之外给出绘图语句,则仅显示该列的最后一个值,并且如果我将绘图语句保留在循环内,则会给出错误。这不是读取文件或特定列的问题,甚至不是缩进问题。我该如何解决?

带有for循环的代码

import numpy as np
import matplotlib.pyplot as plt
from pylab import*
import math
from matplotlib.ticker import LogLocator

with open('input.txt', 'r') as f:
    for rows in f:
        cols = rows.split()
        data = cols[2]
        sorted_data = np.sort(data)
        cdf = np.arange(len(data))/float(len(data))
        plt.plot(sorted_data, cdf, '-bs')

plt.show()
#print data

错误

Traceback (most recent call last):
  File "cdf_plot.py", line 13, in <module>
    plt.plot(sorted_data, cdf, '-bs')
  File "/usr/lib/pymodules/python2.7/matplotlib/pyplot.py", line 2467, in plot
    ret = ax.plot(*args, **kwargs)
  File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 3893, in plot
    for line in self._get_lines(*args, **kwargs):
  File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 322, in _grab_next_args
    for seg in self._plot_args(remaining, kwargs):
  File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 300, in _plot_args
    x, y = self._xy_from_xy(x, y)
  File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 240, in _xy_from_xy
    raise ValueError("x and y must have same first dimension")
ValueError: x and y must have same first dimension

没有for循环的代码:

import numpy as np
import matplotlib.pyplot as plt
from pylab import*
import math
from matplotlib.ticker import LogLocator

data = np.loadtxt('input.txt')
data_one = [row[2] for row in data]
sorted_data = np.sort(data)
cdf = np.arange(len(data_one))/float(len(data_one))
#cumulative = np.cumsum(data)
#ccdf = 1 - cdf

#plt.plot(data, sorted_data, 'r-*')
plt.plot(sorted_data, cdf, '-bs')

#plt.xlim([0,0.5])
plt.gca().set_xscale("log")
plt.gca().set_yscale("log")
plt.show()

错误:

Traceback (most recent call last):
  File "cum_graph.py", line 7, in <module>
    data = np.loadtxt('e_p_USC_30_days.txt')
  File "/usr/lib/python2.7/dist-packages/numpy/lib/npyio.py", line 804, in loadtxt
    X = np.array(X, dtype)
ValueError: setting an array element with a sequence.

输入文件:我有兴趣计算 col[2] 的 CDF,即仅第 3 列

4814  2464  27  0.000627707861971  117923.0
4211  736  2  4.64968786645  05  2576.0
2075  1339  30  0.000697453179968  499822.0
2441  2381  3  6.97453179968  05  1968.0
4694  1738  1  2.32484393323  05  5702.0
4406  3008  12  0.000278981271987  8483.0
3622  1396  3  6.97453179968  05  2564.0
5425  478  1  2.32484393323  05  428.0
4489  1715  6  0.000139490635994  19045.0
3695  3387  2  4.64968786645  05  16195.0

【问题讨论】:

  • 您在每个循环中都覆盖了datacdf。考虑使用numpy.loadtxt
  • @darthbith 第二个代码是numpy.loadtxt 也有错误。
  • 那为什么不使用切片语法呢? data_one = data[:,2] PS:问得好,+1
  • 哦,现在我看到错误出现在 loadtxt... 您是否尝试在谷歌上搜索您收到的错误消息?原因是您在某些行中有额外的数据(或者在其他行中没有足够的数据,这取决于您如何看待它:-))。见:numpy-discussion.10968.n7.nabble.com/…

标签: python file numpy matplotlib plot


【解决方案1】:

这里确实有很多问题。

1 - 您的数据存在问题

仔细观察它们:

4814  2464  27  0.000627707861971  117923.0
4211  736  2  4.64968786645  05  2576.0
2075  1339  30  0.000697453179968  499822.0
2441  2381  3  6.97453179968  05  1968.0
4694  1738  1  2.32484393323  05  5702.0
4406  3008  12  0.000278981271987  8483.0
3622  1396  3  6.97453179968  05  2564.0
5425  478  1  2.32484393323  05  428.0
4489  1715  6  0.000139490635994  19045.0
3695  3387  2  4.64968786645  05  16195.0

有时你会得到 6 列,如下所示:

4211  736  2  4.64968786645  05  2576.0

有时你只得到 5 个:

4814  2464  27  0.000627707861971  117923.0

所以首先要学会正确的写入数据。

2 - 正确写入数据

想象一下,你所有的数据都在一个名为data的二维numpy数组中。

你可以打电话:

numpy.savetxt("input.txt", data)

或者,为了更好地控制格式化:

numpy.savetxt("input.txt", data, fmt="%d %d %d %.6f %d %.1f")

fmt= 参数是一种告诉 numpy 你想如何保存数据的方法(%d 表示将其写为整数,%f 表示将其写为浮点数,%.5f 表示将其写为浮点数只有 5 位小数)。

如果你想自己写,你可以这样做:

fmt = "%d %d %d %.6f %d %.1f"
with open("input.txt", "w") as f:
    for row in data:
        f.write(fmt%row+"\n")

如果你真正想要写的是 5 列而不是 6 列的行,那么请使用另一个分隔符,例如 ,。这样,

4814,2464,27,0.000627707861971,,117923.0

显然包含 6 列。

3 - 加载有效数据

我所说的有效数据是一致的数据,总是包含相同数量的列的数据。

您真的应该使用numpy.loadtxtnumpy.genfromtxt(如果数据丢失,则使用后者)。请注意,您可以使用 delimiter 参数为它们指定一个分隔符。

data = numpy.loadtxt("valid_input.txt")
col = data[:,2]

或者等效地,您可以将 usecols 参数与 unpack 参数一起使用。

4 - 加载无效数据

对于您的数据,使用usecols 的方法是,如果您在其他地方的第 2 列之前没有任何其他错误,则仅选择第三列(Python lingua 中的第 2 列)。

你可以用手来做,这会给我们带来另一个错误:

5 - 第一次实现的问题

在那里,您只需将变量数据替换为单个值(cols[2] 中的那个):

with open('input.txt', 'r') as f:
    for rows in f:
        cols = rows.split()
        data = cols[2]

您尝试对单个值进行排序:

        sorted_data = np.sort(data)

你想获取单个值的长度:

        cdf = np.arange(len(data))/float(len(data))
        plt.plot(sorted_data, cdf, '-bs')

plt.show()

我真的很惊讶numpy 没有抱怨。

您一次只获得一行:您需要将这些值存储在某处(例如在列表中),然后对其进行处理。

6 - 你的第二个实现的问题

numpy.loadtxt 无法加载您的数据(默认情况下它会尝试加载所有内容),因为它无法根据行推断您想要对 6 列或 5 列执行什么操作。所以它唯一能做的就是失败。

7 - 你的问题

首先,不要生气:我要说的是帮助您改进。我不会以任何方式评判你,只是告诉你在这种错误面前你应该如何反应,无论是否微不足道。

  1. 读取错误。
  2. 尝试了解正在发生的事情。
  3. 在 Internet 上查找这些错误。
  4. 问问别人。

问题是您似乎只是复制粘贴了错误而没有实际查看它们,因此没有尝试理解它们(但我可能错了,我不在你的脑海中:))。

但可以肯定的是,您没有将它们复制粘贴到您最喜欢的搜索引擎中,因为答案很多。再说一次,我可能错了。也许您这样做了,但没有看到这些答案如何适用于您的案例。不过,Google 上的第一个回答是关于

ValueError: x and y must have same first dimension

非常明确。您甚至不必提及这是 matplotlib 或 Python。然后您会发现sorted_data 的长度与cdf 的长度不同。再多做一点工作,你就会明白我之前所说的关于你的实现的内容。

8 - 证明我错了

正如您所见,我没有给出“规范的答案”,我也不会,因为我认为您没有完成您的工作。但是您仍然可以做到:我已经为您提供了回答您自己的问题所需的所有工具。这并不意味着你必须在一个偏远的岛屿上独自完成这一切:我几乎已经给出了一个完整的答案(真的),文档可以提供帮助,谷歌也可以:)。您所要做的就是稍微搜索一下。一旦你有一些工作,编辑你的问题(或回答你自己的问题)。

【讨论】:

  • 我同意我确实有一些疑问。感谢您清除它们。我还应该提到,数据是按原样提供给我的。我没有生成这些数据。
  • 这似乎不是问题:前 3 列似乎没问题。只需一行 Python 代码即可加载您的数据。您不需要一行完成,但绝对有可能很容易地得到您想要的:您只需要花一些时间尝试。一个成功的方法是使用尽可能多的print 函数,以准确了解逐行发生的情况。错误也非常有用:回溯会为您提供错误发生的行,以便将注意力集中在正确的事情上。
  • 好吧,我确实尝试了您解释的内容,但似乎没有用,但 np.loadtxt 仍然存在问题错误:Traceback (most recent call last): File "multi_plot.py", line 5, in &lt;module&gt; data = np.loadtxt(fname) File "/usr/lib/python2.7/dist-packages/numpy/lib/npyio.py", line 690, in loadtxt fh = iter(open(fname, 'U')) IOError: [Errno 2] No such file or directory: 'input.txt'