Pythonic方式访问数组的某些部分

时间:2013-05-07 13:44:59

标签: python arrays numpy

我有一个2D numpy数组,包含绘图的x(data [:,0])和y(data [:,1])信息。

我想为数据拟合曲线,但仅使用数据的某些部分来确定拟合参数(例如,使用范围x = x1 - > x2和x3 - > x4的数据) 。我这样做的计划是创建一个新的numpy数组,只包含我打算传递给SciPy CurveFitting例程的数据。

index_range1 = np.where((data[:,0] > x1) and (data[:,0] < x2)
index_range2 = np.where((data[:,0] > x3) and (data[:,0] < x4)

然后我会使用这些索引范围将感兴趣的数据拉入一个新的数组,我可以传递给CurveFit。

首先,鉴于Python可以处理复杂的数组,这似乎是一种非常不同于pythonic的方法。其次,在运行我的脚本时,我得到一个错误,说我需要在我的表达式中为index_range 1和2使用.any()或.all()。

因此,我想知道是否有人建议采用改进的,更加pythonic的方法来解决这个问题。

谢谢!

2 个答案:

答案 0 :(得分:2)

要从另外两个中获取布尔数组,请使用&进行元素比较:

index_range1 = np.where((data[:,0] > x1) & (data[:,0] < x2))
index_range2 = np.where((data[:,0] > x3) & (data[:,0] < x4))

使用boolean arrays索引数组可能更“pythonic”。您无需查找(使用where)并保存索引,您可以直接从阵列访问数据:

range1 = data[(data[:,0] > x1) & (data[:,0] < x2)]
range2 = data[(data[:,0] > x3) & (data[:,0] < x4)]

您可以通过以下方式缩短/使其更具可读性:

x, y = data.T
range1 = data[(x > x1) & (x < x2)]
range2 = data[(x > x3) & (x < x4)]

注意:xy观看次数,因此修改xy修改data,并且没有复制所以它不应该减慢代码速度。但range副本,因为fancy indexing会制作副本,因此修改它们不会影响xy或{{ 1}}。

答案 1 :(得分:2)

在这种情况下,您要使用numpy.logical_and

>>> import numpy as np
>>> data = np.arange(100)
>>> data[np.logical_and(50 <= data,data <= 70)]
array([50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
       67, 68, 69, 70])

原因是对于常规and,python会查看左侧数组并说“这是真的吗?”。但是,数组没有“真实”的概念(他们拒绝猜测“真正的”数组会是什么样子),所以它们引发了你看到的异常(暗示你可能想要使用{{ 1}}或all方法。)