【问题标题】:Plot parametric mean in Python在 Python 中绘制参数均值
【发布时间】:2013-10-08 22:19:43
【问题描述】:

我有一个名为 r 的大型实际一维数据集。我想要情节:

mean(log(1+a*r)) vs a, with a > -1 . 

这是我的代码:

   rr=pd.read_csv('goog.csv')
   dd=rr['Close']
   series=pd.Series(dd)
   seriespct=series.pct_change()
   seriespct[0]=seriespct.mean()

   dum1 =[0]*len(dd)

   a=1.
   a_max = 1.
   a_step = 0.01

   a = scipy.arange(-3.+a_step, a_max, a_step)
   n = len(a)
   dum2 =[0]*n
   m=len(dd)

   for j in range(n):
      for i in range(m):
         dum1[i]=math.log(1+a[j]*seriespct[i])

   dum2[j]=scipy.mean(dum1)


   plt.plot(a,dum2)
   plt.show()

我怎样才能以更优雅的方式做到这一点?

【问题讨论】:

  • 均值是单个值。你如何将它与 a 相结合?
  • 反对不同的a值。
  • 但是你已经尝试了什么?
  • 我是 python 新手。我有一个在 R 中做的代码。现在我想学习 python 进行统计分析,但我不知道如何做这样的事情。
  • 编辑后不应关闭。

标签: python numpy matplotlib pandas scipy


【解决方案1】:

我会推荐这个:

plt.plot(a, np.log(1 + r*a[:,None]).mean(1))

这具有很大的速度优势,因为它避免了 for 循环,并且在您的数据集很大的情况下,在 numpy 中完成的循环明显更快。

In [49]: a = np.arange(a_step-.3, a_max, a_step)

In [50]: r = np.random.random(100)

In [51]: timeit [scipy.mean(log(1+a[i]*r)) for i in range(len(a))]
100 loops, best of 3: 5.47 ms per loop

In [52]: timeit np.log(1 + r*a[:,None]).mean(1)
1000 loops, best of 3: 384 µs per loop

它由broadcasting 工作,因此a 沿一个轴变化,r 沿另一个轴变化,然后您可以沿r 变化的轴取平均值,因此您仍然有一个变化的数组与a(和a具有相同的形状):

import numpy as np
import matplotlib.pyplot as plt

r = np.random.random(100)

a = 1.
a_max = 1.
a_step = 0.01
a = np.arange(a_step-.3, a_max, a_step)
a.shape
#(129,)
a = a[:,None] #adds a new axis, making this a column vector, same as: a = a.reshape(-1,1)
a.shape
#(129, 1)
(a*r).shape
#(129, 100)
loga = np.log(1 + a*r)
loga.shape
#(129,100)
mloga = loga.mean(axis=1) #take the mean along the 2nd axis where `a` varies
mloga.shape
#(129,)

plt.plot(a, mloga)
plt.show()

附录:

为了避免对广播的依赖,可以使用np.outer

plt.plot(a, np.log(1 + np.outer(a,r)).mean(1))

无需重塑a(跳过a = a[:,None]这一步)

这是一个更简单的例子,你可以看看发生了什么:

r = np.exp(np.arange(1,5))
a = np.arange(5)

In [33]: r
Out[33]: array([  2.71828183,   7.3890561 ,  20.08553692,  54.59815003])

In [34]: a
Out[34]: array([0, 1, 2, 3, 4])

In [39]: r*a[:,None]
Out[39]: 
# this is  2.7...         7.3...        20.08...       54.5...         # times:
array([[   0.        ,    0.        ,    0.        ,    0.        ],   # 0
       [   2.71828183,    7.3890561 ,   20.08553692,   54.59815003],   # 1
       [   5.43656366,   14.7781122 ,   40.17107385,  109.19630007],   # 2
       [   8.15484549,   22.1671683 ,   60.25661077,  163.7944501 ],   # 3
       [  10.87312731,   29.5562244 ,   80.34214769,  218.39260013]])  # 4

In [40]: np.outer(a,r)
Out[40]: 
array([[   0.        ,    0.        ,    0.        ,    0.        ],
       [   2.71828183,    7.3890561 ,   20.08553692,   54.59815003],
       [   5.43656366,   14.7781122 ,   40.17107385,  109.19630007],
       [   8.15484549,   22.1671683 ,   60.25661077,  163.7944501 ],
       [  10.87312731,   29.5562244 ,   80.34214769,  218.39260013]])

# this is the mean of each column:
In [41]: (np.outer(a,r)).mean(1)
Out[41]: array([  0.        ,  21.19775622,  42.39551244,  63.59326866,  84.79102488])

# and the log of 1 + the above is:
In [42]: np.log(1+(np.outer(a,r)).mean(1))
Out[42]: array([ 0.        ,  3.09999121,  3.77035604,  4.16811021,  4.4519144 ])

【讨论】:

  • (a*r).shape;例外:数据必须是一维的。有什么问题?
  • r 是一维的(即r.shape 是什么)? type(r) 是一个 numpy 数组(numpy.ndarray)吗?我知道a 是因为您将其构建为np.arange
  • rr=pd.read_csv('goog.csv'); dd=rr['关闭'];series=pd.Series(dd);seriespct=series.pct_change()
  • 哦,也许熊猫对象不支持广播?我从来没有用过熊猫。您可以将r*a[:,None] 替换为np.outer(a,r)。也就是不要重塑a,让它保持正则1d,然后用外层函数代替正则乘法。
【解决方案2】:

你可以用scipy做手段。

您可以使用 matplotlib 进行绘图。

import scipy
from matplotlib import pyplot

#convert r from a python list to an 1-D array
r = scipy.array(r)

#edit these
a_max = 100
a_step = 0.1

a = scipy.arange(-1+a_step, a_max, a_step)
n = len(a)

pyplot.plot(a, [scipy.mean(log(1+a[i]*r)) for i in range(n)], 'b-')
pyplot.show()

【讨论】:

  • TypeError: 只有长度为 1 的数组可以转换为 Python 标量。
  • 我做了一个可能有帮助的编辑(将列表 r 转换为一个数组),但您需要发布更多代码。
  • 如果您的数据中有nans,这将不会产生预期的结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-04
  • 2014-11-02
  • 1970-01-01
  • 2019-12-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多