2016-12-22 2 views
2

у меня есть панды dataframe с двумя столбцов, содержащих х, у координаты, которые я сюжет, как показано ниже:Место х, у координаты в бункера

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() 

enter image description here

Я хочу, чтобы разделить й и y каждые 0,1 единицы, чтобы получить 600 бункеров (30x20). Затем я хочу знать, сколько из моих очков в каждом ящике и индексы этих точек, поэтому я могу найти их в своем фреймворке. Я в основном хочу создать 600 новых фреймов данных для каждого бина.

Это то, что я пытался до сих пор:

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

Это даст мне часть dataframe, содержащейся внутри квадрата (-0,1 ≤ х < 0) & (0,7 ≤ у < 0,8). Я хочу создать 600 из них.

+0

Так что, если я правильно это понять, это на самом деле не имеет ничего общего с Matplotlib? Вам просто нужна структура данных, а не другой сюжет? – whrrgarbl

+0

Да, это правильно. – Imran

+0

'counts, x, y = np.histogram2d (df.x, df.y, [xbins, ybins])' делает бининг в двух измерениях, где 'xbins' и' ybins' - ваши массивы, определяющие ячейки. Кроме того, 'np.digitize' делает binning в одномерном виде, аналогично решению @Ted Petrou ниже с' pd.cut'. –

ответ

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)} 

Вы можете получить dataframe подсчетов с

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

Для вызова определенного фрейма данных из словаря 'dict_of_df' обозначается: dict_of_df ['i', 'j']. Будет ли этот информационный кадр содержать точки внутри квадрата: (i ≤ x Imran

+0

@TimmyK Да! Это верно. – piRSquared

+0

Например, чтобы найти все точки внутри квадрата (-0.1 ≤ x <0) & (0,7 ≤ y <0,8), я бы назвал dict_of_df ['- 0,1', '0,7']? – Imran

0

вы можете преобразовать свои единицы в соответствующие индексы 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
3

Я бы использовал функцию 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 >= -0.1) & (df.x < 0) & (df.y >= 0.7) & (df.y < 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 
Смежные вопросы