首页 > 解决方案 > 返回 bin 坐标 python

问题描述

我有一个scatter plot被分类为bins. 有 4 个 bin,中间用一条线隔开的两条弧线。它逐行排序到列表列表中。例如,如果每个 bin 中有一个散点,则导出为:

x[0],y[0] = [(x,y)],[(x,y)],[(x,y)],[(x,y)]

问题是我必须手动导出每一行。因此,如果我想导出散点图的第二行,我将更改为x[1],y[1]并将其添加到第一行。如果我有多行,这不是很有效。

如果我使用x,y我得到一个值错误:ValueError: operands could not be broadcast together with shapes (70,) (10,)

有没有一种方法可以逐行导出整个数据集,或者使用相同的代码并循环遍历每一行。

import math
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np

x = np.random.randint(80, size=(400, 10))
y = np.random.randint(80, size=(400, 10)) 

fig, ax = plt.subplots()
ax.grid(False)

plt.scatter(x[0],y[0])

#Creating the arcs
BIN_23_X = 50 
ang1 = 0, 50
ang2 = 100, 50
angle = math.degrees(math.acos(5.5/9.15))

#Adding the arcs and halfway line
Halfway = mpl.lines.Line2D((BIN_23_X,BIN_23_X), (0,100), c = 'black', lw = 2.5, alpha = 0.8, zorder = 1)
arc1 = mpl.patches.Arc(ang1, 65, 100, angle = 0, theta2 = angle, theta1 = 360-angle, lw = 2)
arc2 = mpl.patches.Arc(ang2, 65, 100, angle = 0, theta2 = 180+angle, theta1 = 180-angle, lw = 2)

ax.add_line(Halfway)
ax.add_patch(arc1)
ax.add_patch(arc2)

#Sorting the coordinates into bins   
def get_nearest_arc_vert(x, y, arc_vertices):
    err = (arc_vertices[:,0] - x)**2 + (arc_vertices[:,1] - y)**2
    nearest = (arc_vertices[err == min(err)])[0]
    return nearest

arc1v = ax.transData.inverted().transform(arc1.get_verts())
arc2v = ax.transData.inverted().transform(arc2.get_verts())

def classify_pointset(vx, vy):
    bins = {(k+1):[] for k in range(4)}
    for (x,y) in zip(vx, vy):
        nx1, ny1 = get_nearest_arc_vert(x, y, arc1v)
        nx2, ny2 = get_nearest_arc_vert(x, y, arc2v)

        if x < nx1:                         
            bins[1].append((x,y))
        elif x > nx2:                      
            bins[4].append((x,y))
        else:
            if x < BIN_23_X:               
                bins[2].append((x,y))
            else:                          
                bins[3].append((x,y))
    return bins

#Bins Output
bins_red  = classify_pointset(x[0], y[0])

all_points = [None] * 5
for bin_key in [1,2,3,4]:
    all_points[bin_key] = bins_red[bin_key] 

print(all_points) 

我要分类到垃圾箱的行是:

bins = classify_pointset(x[0], y[0])

我可以更改bins = classify_pointset(x[0], y[0])或添加循环以遍历每一行吗?

我希望完成的示例

如果我们使用数据的第一行来返回我会使用的分箱坐标:

bins = classify_pointset(x[0], y[0])

输出:

[None, [(17, 20), (20, 36), (23, 30), (0, 65), (15, 35)], [(44, 57), (45, 3), (43, 0)], [(61, 21)], [(78, 23)]]

在此处输入图像描述

如您所见,第一个 bin 中有 5 个坐标[(17, 20), (20, 36), (23, 30), (0, 65), (15, 35)]。第 2 个 3 个[(44, 57), (45, 3), (43, 0)], 第 3 个 bin [(61, 21)]1 个 , 第 4 个 bin 1 个[(78, 23)]

要返回第二行分箱坐标,我会更改:

bins = classify_pointset(x[0], y[0])bins = classify_pointset(x[1], y[1]).

然后,我会将第二行附加到第一行以创建它:

0 = [(x,y)],[(x,y)],[(x,y)],[(x,y)]
1 = [(x,y)],[(x,y)],[(x,y)],[(x,y)]

这个问题是我必须继续手动更改行并追加。例如

返回bins = classify_pointset(x[2], y[2])然后追加:

输出:

2 = [(x,y)],[(x,y)],[(x,y)],[(x,y)]

附加:

0 = [(x,y)],[(x,y)],[(x,y)],[(x,y)]
1 = [(x,y)],[(x,y)],[(x,y)],[(x,y)]
2 = [(x,y)],[(x,y)],[(x,y)],[(x,y)]

我需要将整个 xy 数据集以逐行格式返回到它们各自的 bin 中的东西。而不是一次导出一行然后追加。

这有意义吗?

标签: pythonpandasloopsnumpyappend

解决方案


好的,这是我的尝试。有几件事我不确定你为什么选择这样做,所以我改变了它们。如果他们需要那样做,请随时告诉我,我可以把它们改回来。

首先,我不确定为什么您在分类点集中使用字典而不是列表作为您的垃圾箱。我已将其更改为使用列表,现在它是零索引的。

def classify_pointset(vx, vy):                                                                       
    bins = [[] for k in range(4)]                                                                    
    for (x,y) in zip(vx, vy):                                                                        
        nx1, ny1 = get_nearest_arc_vert(x, y, arc1v)                                                 
        nx2, ny2 = get_nearest_arc_vert(x, y, arc2v)                                                 

        if x < nx1:                                                                                  
            bins[0].append((x,y))                                                                    
        elif x > nx2:                                                                                
            bins[3].append((x,y))                                                                    
        else:                                                                                        
            if x < BIN_23_X:                                                                         
                bins[1].append((x,y))                                                                
            else:                                                                                    
                bins[2].append((x,y))                                                                

    return bins

接下来,我不确定您为什么要将您确实拥有的字典变成列表。我在上面所做的更改实现了这一点。

现在为了自动遍历每个 bin,我们可以只使用 range 函数和数组的形状。我正在手动计算第一个 bin,以便我们可以将它与最终 bin 进行比较并确保它匹配。

first_bin = classify_pointset(x[0],y[0])                                                             

#Bins Output                                                                                         
all_points = []                                                                                      

for i in range(x.shape[0]):                                                                          
    bins = classify_pointset(x[i],y[i])                                                              
    all_points.append(bins)                                                                          

print first_bin                                                                                      
print all_points[0] 

上面没有收听的任何代码都保持原样。让我知道是否有任何问题或不清楚。


推荐阅读