将python元组装箱。由于空箱子而导致错误

将python元组装箱。由于空箱子而导致错误,python,list,numpy,binning,Python,List,Numpy,Binning,我无法将列表项排序到垃圾箱。我有两个列表,X和Y,以及相应的X和Y值(显然,这也可能是一个元组列表)。接下来,我需要将X范围划分为10个相等的单元,并将X值和相应的Y值排序到这些单元,以便我知道哪些Y值属于哪个X单元(即每个Y值的X值落在哪个单元中),然后取每个单元中所有Y值的中值。这给了我十双。在下面的代码中,我还计算了每个箱子的X中心,这在原则上运行良好 bins = np.linspace(max(X), min(X), 10) digitized = np.digitiz

我无法将列表项排序到垃圾箱。我有两个列表,X和Y,以及相应的X和Y值(显然,这也可能是一个元组列表)。接下来,我需要将X范围划分为10个相等的单元,并将X值和相应的Y值排序到这些单元,以便我知道哪些Y值属于哪个X单元(即每个Y值的X值落在哪个单元中),然后取每个单元中所有Y值的中值。这给了我十双。在下面的代码中,我还计算了每个箱子的X中心,这在原则上运行良好

    bins = np.linspace(max(X), min(X), 10)
    digitized = np.digitize(X, bins)
    bin_centers = []
    for j in range(len(bins) - 1):
        bin_centers.append((bins[j] + bins[j + 1]) / 2.)
    bin_means = [np.median(np.asarray(Y)[digitized == j])
                 for j in range(1, len(bins))]
现在的问题是,有时箱子是空的,因为这个箱子里没有X值。在这种情况下,该行

    bin_means = [np.median(np.asarray(Y)[digitized == j])
                 for j in range(1, len(bins))]
引起错误

/usr/lib64/python2.6/site-packages/numpy/core/_methods.py:55: RuntimeWarning: Mean of empty slice.
FloatingPointError: invalid value encountered in double_scalars
因为空箱子。我怎样才能解决这个问题?我还在
numpy.digitalize
中尝试了
right=True/False
,但运气不好。我认为最好先删除三个列表
bin_centers
、数字化
bin
中的条目,然后再进行计算中值的列表理解。但我不知道如何做到这一点,如何找出哪些垃圾箱是空的,然后从这些列表中删除什么,以及如何删除。
有什么想法吗?谢谢

我不太明白这个问题,但这里有一些东西可以让你开始:

In [3]: X = [1,2,3,4,5,6,7,8,9,10]

In [4]: Y = [chr(96+x) for x in X]

In [8]: Z = zip(X, Y)    # Create a pairing - this can be done after a sort if they're not in whatever 'order' you want for your correspondence

In [9]: Z
Out[9]:
[(1, 'a'),
 (2, 'b'),
 (3, 'c'),
 (4, 'd'),
 (5, 'e'),
 (6, 'f'),
 (7, 'g'),
 (8, 'h'),
 (9, 'i'),
 (10, 'j')]
此时,您可以执行排序(Z,key=lambda el:-ord(el[1]))
之类的操作,或者根据您的条件进行排序。显然,这比这个例子更有意义

最后,我想你可能也希望把它们分成等长的部分,看看下面的例子


如果这不是你想要的,道歉

如果您有Scipy,您可以拨打:

屈服

[ 15.  90.  50.  55.  40.  60.]
[15.0, 90.0, 50.0, 55.0, nan, 40.0, nan, nan, nan, 60.0]

如果没有SciPy,我想你需要一个列表。 正如您所建议的,您可以通过过滤掉那些空的容器来避免RuntimeWarning。您可以在列表中使用
if条件

masks = [(digitized == j) for j in range(1, len(bins))]
bin_medians = [np.median(Y[mask]) for mask in masks if mask.any()]
还要注意,您看到的错误消息是警告,而不是异常。您可以(或者)使用以下命令抑制错误消息:

import warnings
warnings.filterwarnings("ignore", 'Mean of empty slice.')
warnings.filterwarnings("ignore", 'invalid value encountered in double_scalar')

有一种方法可以更快地计算bin_中心:

bin_centers = []
for j in range(len(bins) - 1):
    bin_centers.append((bins[j] + bins[j + 1]) / 2.)
可以简化为

bin_centers = bins[:-1] + (bins[1]-bins[0])/2

那么比如说,

import numpy as np
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings("ignore", 'Mean of empty slice.')
warnings.filterwarnings("ignore", 'invalid value encountered in double_scalar')

np.random.seed(123)

X = np.random.random(10)
bins = np.linspace(min(X), max(X), 10)
digitized = np.digitize(X, bins)-1
bin_centers = bins + (bins[1]-bins[0])/2

Y = range(0, 100, 10)
Y = np.asarray(Y, dtype='float')
bin_medians = [np.median(Y[digitized == j]) for j in range(len(bins))]
print(bin_medians)

plt.scatter(bin_centers, bin_medians)
plt.show()
屈服

[ 15.  90.  50.  55.  40.  60.]
[15.0, 90.0, 50.0, 55.0, nan, 40.0, nan, nan, nan, 60.0]

如果您的目的只是绘制散点图,则无需删除NAN,因为
matplotlib
将忽略它们

如果您真的想删除NAN,那么可以使用

no_nans = np.isfinite(bin_medians)
bin_medians = bin_medians[no_nans]
bin_centers = bin_centers[no_nans]

在上面的例子中,我选择使用
warnings.filterwarnings
来抑制警告。如果您不希望抑制警告,而是希望从
bin_中位数
bin_中心
的相应位置过滤NAN,则:

bin_centers = bins + (bins[1]-bins[0])/2
masks = [(digitized == j) for j in range(len(bins))]
bin_centers, bin_medians = zip(*[(center, np.median(Y[mask]))
                                 for center, mask in zip(bin_centers, masks)
                                 if mask.any()])

这是怎么回事?什么是
X
Y
持有?在什么意义上,
X
中的值与
Y
中的值相对应?它们包含的数字基本上是任意的,只要每个数字X都属于一个值Y,那么就存在对(x1,y1),(x2,y2),等等。在我的例子中,X包含震级,Y包含每个X值的震级偏差。绘制一个X/Y散点图。谢谢,这可能就是我要找的!关于这一点有两个问题:我还需要去掉与空箱子相对应的箱子中心条目,因为我需要绘制散点图(箱子中心、箱子中间)。有没有比在for循环中(
for i in range(len(masks)):如果不是mask.any():del_index.append(i)
然后
bin_centers=[m for n,m in enumerate(bin_centers),如果n不在del_index中]
?还有,为什么你的列表中有六个元素使用scipy,而只有五个元素使用numpy?我不明白其中的区别。我知道如果不是masks[I],那么它必须是
。any()
,对不起;)或者更确切地说是any(masks[I]),因为它不是numpy数组。如果你的最终目的是用matplotlib制作散点图,那么就没有必要移除NAN
plt.scatter
将简单地忽略它们。关于第二个问题:“为什么
binned_statistic
显示6个中间点”:
bin
表示bin边缘<代码>最小值(X)
最大值(X)
正好落在箱子边缘<代码>np。数字化
最小值(X)
放置在箱子1中,将
最大值(X)
放置在箱子10中。由于
min(X)
X
中的最小值,任何东西都不会落在存储单元0中,而存储单元10中只有一个值,
max(X)
在循环
范围(1,len(存储单元))
时被忽略。因此,这是一个“一个接一个”的错误。我将发布一些代码,说明避免这种情况的一种方法。