2D bin (x, y) и вычислить среднее значение (c) 10 самых глубоких точек данных (z) - PullRequest
1 голос
/ 09 ноября 2019

Для набора данных, состоящего из:

  • координаты x, y
  • глубина z
  • определенное значение c

Я хотел бы сделать следующее более эффективным:

  1. bin, набор данных в 2D bin, основанный на координатах (x, y)
  2. , взять 10 самых глубоких точек данных (z)на бин
  3. рассчитать среднее значение c из этих 10 точек данных на бин

Наконец покажите 2-мерную тепловую карту с вычисленными средними значениями.

Я нашелрабочее решение, но это занимает слишком много времени для небольших контейнеров и / или больших наборов данных.

Есть ли более эффективный способ достижения того же результата?

Текущий рабочий пример

Пример кадра данных:

import numpy as np
from numpy.random import rand
import pandas as pd
import math
import matplotlib.pyplot as plt

n = 10000
df = pd.DataFrame({'x':rand(n), 'y':rand(n), 'z':rand(n), 'c':rand(n)})

Бин набора данных:

cell_size = 0.01

nx = math.ceil((max(df['x']) - min(df['x'])) / cell_size)
ny = math.ceil((max(df['y']) - min(df['y'])) / cell_size)

x_range = np.arange(0, nx)
y_range = np.arange(0, ny)

df['xbin'], x_edges = pd.cut(x=df['x'], bins=nx, labels=x_range, retbins=True)
df['ybin'], y_edges = pd.cut(x=df['y'], bins=ny, labels=y_range, retbins=True)

Код, который теперь занимает длинную позицию:

df = df.groupby(['xbin', 'ybin']).apply(
    lambda d: d.sort_values('z').head(10).mean())

Обновление пустого кадра данных дляБункеры без данных и показывают результат:

index = pd.MultiIndex.from_product([x_range, y_range],
    names=['xbin', 'ybin'])

tot_df = pd.DataFrame(index=index, columns=['z', 'c'])
tot_df.update(df)

zval = tot_df['c'].astype('float').values
zval = zval.reshape((nx, ny))
zval = zval.T
zval = np.flipud(zval)

extent = [min(x_edges), max(x_edges), min(y_edges), max(y_edges)]

plt.matshow(zval, aspect='auto', extent=extent)
plt.show()

1 Ответ

0 голосов
/ 09 ноября 2019

вы можете использовать np.searchsorted, чтобы связать строки по x и y, а затем использовать groupby, чтобы получить 10 глубоких значений и вычислить среднее. Поскольку groupby будет поддерживать порядок в каждой группе, вы можете сортировать значения перед применением бинов. groupby будет работать лучше без применения

df = pd.DataFrame({'x':rand(n), 'y':rand(n), 'z':rand(n), 'c':rand(n)})

df = df.sort_values("z", ascending=False)
bins = np.linspace(0, 1, 11)
df["bin_x"] = np.searchsorted(bins, df['x'].values) - 1
df["bin_y"] = np.searchsorted(bins, df['y'].values) - 1

result = df.groupby(["bin_x", "bin_y"]).head(10)
result.groupby(["bin_x", "bin_y"])["c"].mean()

Результат

bin_x  bin_y
0      0        0.369531
       1        0.601803
       2        0.554452
       3        0.575464
       4        0.455198
                  ...   
9      5        0.469838
       6        0.420772
       7        0.367549
       8        0.379200
       9        0.523083
Name: c, Length: 100, dtype: float64
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...