CDF累积分布函数错误
我正在尝试为一个多列数据文件中的某一列绘制累积分布函数(CDF)。当数据文件中只有一列时,绘图效果很好。但是,当我试图从数据中提取特定列时,就出现了错误。我也尝试使用循环来读取特定列,读取是没问题的。如果我把绘图的代码放在循环外面,图表只显示了该列的最后一个值;而如果把绘图的代码放在循环里面,就会出现错误。这个问题不是出在读取文件或特定列上,也不是缩进的问题。我该如何解决这个问题呢?
带有循环的代码
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
没有循环的代码:
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.
输入文件:我只对计算第3列(col[2])的CDF感兴趣
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
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.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列的行,那就用其他分隔符,比如 ,
。这样,
4814,2464,27,0.000627707861971,,117923.0
显然包含了6列。
3 - 加载有效数据
我所说的有效数据是指一致的数据,也就是每行数据的列数总是相同。
你应该使用 numpy.loadtxt
或 numpy.genfromtxt
(后者用于处理缺失数据)。注意,你可以为这两个函数指定分隔符,使用 delimiter
参数。
data = numpy.loadtxt("valid_input.txt")
col = data[:,2]
或者你也可以使用 usecols
参数和 unpack
参数一起使用。
4 - 加载无效数据
对于你的数据,使用 usecols
方法是有效的,只要你选择第三列(在 Python 中是第2列),前面没有其他错误。
你可以手动处理,这就引出了另一个问题:
5 - 你第一次实现的问题
在这里,你只是用一个单一的值替换了变量 data(即 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 - 你自己的问题
首先,不要生气:我说这些是为了帮助你进步。我并不是在评判你,只是在告诉你面对这种错误时应该怎么做,无论是简单的还是复杂的。
- 阅读错误信息。
- 尝试理解发生了什么。
- 在网上查找这些错误。
- 问别人。
问题在于你似乎只是复制粘贴了错误信息,而没有真正去看它们,也没有尝试去理解(但我可能错了,我不知道你的想法 :))。
但可以肯定的是,你没有把这些错误信息放到你喜欢的搜索引擎里,因为网上有很多答案。同样,我可能错了。也许你确实这样做了,但没有看到这些答案如何适用于你的情况。不过,谷歌上关于
ValueError: x and y must have same first dimension
的第一个答案是非常明确的。你甚至不需要提到这是 matplotlib
或 Python。然后你就会发现 sorted_data
的长度和 cdf
不一样。再多花点时间,你就会明白我之前说的关于你实现的内容。
8 - 证明我错了
正如你所看到的,我没有给出一个“标准答案”,也不会给出,因为我认为你没有尽到自己的责任。但你仍然可以做到:我给了你所有需要的工具来回答你自己的问题。这并不意味着你要独自一人在一个孤岛上完成:我几乎给出了完整的答案(真的),文档也能帮到你,谷歌也是 :)。你所要做的就是稍微搜索一下。一旦你有了可用的东西,编辑你的问题(或者回答你自己的问题)。