【问题标题】:Place x,y coordinates into bins将 x,y 坐标放入 bin
【发布时间】:2017-05-08 06:54:21
【问题描述】:

我有一个 Pandas 数据框,其中两列包含我绘制的 x,y 坐标,如下所示:

plt.figure(figsize=(10,5))
plt.scatter(df.x, df.y, s=1, marker = ".")
plt.xlim(-1.5, 1.5)
plt.ylim(0, 2)
plt.xticks(np.arange(-1.5, 1.6, 0.1))
plt.yticks(np.arange(0, 2.1, 0.1))
plt.grid(True)
plt.show()

我想将 x 轴和 y 轴每 0.1 个单位拆分一次,以提供 600 个箱 (30x20)。然后我想知道每个 bin 中有多少点以及这些点的索引,以便我可以在我的数据框中查找它们。我基本上想为每个 bin 创建 600 个新数据帧。

这是我迄今为止尝试过的:

df[(df.x >= -0.1) & (df.x < 0) & (df.y >= 0.7) & (df.y < 0.8)]

这将为我提供包含在正方形 (-0.1 ≤ x

【问题讨论】:

  • 所以如果我理解正确的话,这实际上与 matplotlib 没有任何关系?你只想要数据结构,而不是不同的情节?
  • 是的,没错。
  • counts, x, y = np.histogram2d(df.x, df.y, [xbins, ybins]) 在二维中进行分箱,其中xbinsybins 是定义分箱的数组。同样np.digitize 在一维中进行分箱,类似于@Ted Petrou 下面的pd.cut 解决方案。

标签: python python-2.7 pandas numpy


【解决方案1】:

许多方法之一。

bins = (df // .1 * .1).round(1).stack().groupby(level=0).apply(tuple)

dict_of_df = {name: group for name, group in df.groupby(bins)}

你可以得到计数的数据框

df.groupby(bins).size().unstack()

【讨论】:

  • 要从 'dict_of_df' 字典中调用特定数据帧,表示法是:dict_of_df['i', 'j']。此数据框是否包含正方形内的点:(i ≤ x
  • 例如,要找到正方形内的所有点 (-0.1 ≤ x
  • 您确定 bin 之间不会有重叠吗?如果我这样做:len(df[(df.x >= -0.1) & (df.x = 0.7) & (df.y
  • 当我使用'{:0.1f}' 时,它会围绕边缘进行四舍五入。那不好。对于那个很抱歉。我已经更新了帖子。
【解决方案2】:

我会使用cut 函数来创建垃圾箱,然后按它们分组并计数

#create fake data with bounds for x and y
df = pd.DataFrame({'x':np.random.rand(1000) * 3 - 1.5,
                   'y':np.random.rand(1000) * 2})

# bin the data into equally spaced groups
x_cut = pd.cut(df.x, np.linspace(-1.5, 1.5, 31), right=False)
y_cut = pd.cut(df.y, np.linspace(0, 2, 21), right=False)

# group and count
df.groupby([x_cut, y_cut]).count()

输出

                           x    y
x            y                   
[-1.5, -1.4) [0, 0.1)    3.0  3.0
             [0.1, 0.2)  1.0  1.0
             [0.2, 0.3)  3.0  3.0
             [0.3, 0.4)  NaN  NaN
             [0.4, 0.5)  1.0  1.0
             [0.5, 0.6)  3.0  3.0
             [0.6, 0.7)  1.0  1.0
             [0.7, 0.8)  2.0  2.0
             [0.8, 0.9)  2.0  2.0
             [0.9, 1)    1.0  1.0
             [1, 1.1)    2.0  2.0
             [1.1, 1.2)  1.0  1.0
             [1.2, 1.3)  2.0  2.0
             [1.3, 1.4)  3.0  3.0
             [1.4, 1.5)  2.0  2.0
             [1.5, 1.6)  3.0  3.0
             [1.6, 1.7)  3.0  3.0
             [1.7, 1.8)  1.0  1.0
             [1.8, 1.9)  1.0  1.0
             [1.9, 2)    1.0  1.0
[-1.4, -1.3) [0, 0.1)    NaN  NaN
             [0.1, 0.2)  NaN  NaN
             [0.2, 0.3)  2.0  2.0

并完全回答您的问题。您可以将类别作为列添加到原始数据框中,然后像这样从那里进行搜索。

# add new columns
df['x_cut'] = x_cut
df['y_cut'] = y_cut
print(df.head(15)

            x         y         x_cut       y_cut
0    1.239743  1.348838    [1.2, 1.3)  [1.3, 1.4)
1   -0.539468  0.349576  [-0.6, -0.5)  [0.3, 0.4)
2    0.406346  1.922738    [0.4, 0.5)    [1.9, 2)
3   -0.779597  0.104891  [-0.8, -0.7)  [0.1, 0.2)
4    1.379920  0.317418    [1.3, 1.4)  [0.3, 0.4)
5    0.075020  0.748397      [0, 0.1)  [0.7, 0.8)
6   -1.227913  0.735301  [-1.3, -1.2)  [0.7, 0.8)
7   -0.866753  0.386308  [-0.9, -0.8)  [0.3, 0.4)
8   -1.004893  1.120654    [-1.1, -1)  [1.1, 1.2)
9    0.007665  0.865248      [0, 0.1)  [0.8, 0.9)
10  -1.072368  0.155731    [-1.1, -1)  [0.1, 0.2)
11   0.819917  1.528905    [0.8, 0.9)  [1.5, 1.6)
12   0.628310  1.022167    [0.6, 0.7)    [1, 1.1)
13   1.002999  0.122493      [1, 1.1)  [0.1, 0.2)
14   0.032624  0.426623      [0, 0.1)  [0.4, 0.5)

然后要获得您上面描述的组合:df[(x &gt;= -0.1) &amp; (df.x &lt; 0) &amp; (df.y &gt;= 0.7) &amp; (df.y &lt; 0.8)],您可以将索引设置为 x_cut 和 y_cut 并进行一些分层索引选择。

df = df.set_index(['x_cut', 'y_cut'])
df.loc[[('[-0.1, 0)', '[0.7, 0.8)')]]

输出

                             x         y
x_cut     y_cut                         
[-0.1, 0) [0.7, 0.8) -0.043397  0.702029
          [0.7, 0.8) -0.032508  0.799284
          [0.7, 0.8) -0.036608  0.709394
          [0.7, 0.8) -0.025254  0.741085

【讨论】:

    【解决方案3】:

    您可以将您的单位转换为它们各自的索引 0 - 19 和 0 - 29 并增加一个零矩阵..

    import numpy as np
    
    shape = [30,20]
    bins = np.zeros(shape, dtype=int)
    
    xmin = np.min(df.x)
    xmax = np.max(df.x)
    xwidth = xmax - xmin
    
    xind = int(((df.x - xmin) / xwidth) * shape[0])
    
    #ymin
    #ymax
    #ywidth
    
    #yind
    
    for ind in zip(xind, yind):
        bins[ind] += 1

    【讨论】:

      猜你喜欢
      • 2016-08-04
      • 2019-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-05
      • 2022-01-16
      相关资源
      最近更新 更多