Как найти медиану списков разных размеров - PullRequest
0 голосов
/ 15 декабря 2018

У меня есть список чисел, которые я хочу отсортировать по ячейкам и найти медиану каждой ячейки.Если бы у всех бункеров было одинаковое количество точек данных, это было бы легко сделать достаточно эффективно, используя массивы numpy:

import numpy as np    
indices=np.array([0,1,0,1,1,2,3,3,3,2,0,2])
length=np.max(indices)+1
data = np.arange(len(indices))
binned = np.array([data[indices == i] for i in range(length)])

Значения бин-данных (в массиве binned) равны

array([[ 0,  2, 10],
   [ 1,  3,  4],
   [ 5,  9, 11],
   [ 6,  7,  8]])

Медиана каждого бина:

np.median(binned, axis=1)

Результат:

array([2., 3., 9., 7.])

Однако, если список таков, что в каждом бине имеется разное количество точек (или нет точек в некоторых бинах), я не могу создать массив numpy или использовать np.median, и вместо этого я должен выполнить тяжелую работу в цикле for:

indices=np.array([0,1,1,1,3,1,1,0,0,0,3])
data = np.arange(len(indices))

Данные в бин-массивах

[data[indices == i] for i in range(length)]

[array([0, 7, 8, 9]),
 array([1, 2, 3, 5, 6]),
 array([], dtype=int64),
 array([ 4, 10])]

Но я не могу взять медиану из списка массивов.Вместо этого я могу сделать

[np.median(data[indices == i]) for i in range(length)]

и получить

[7.5, 3.0, nan, 7.0]

Но цикл for довольно медленный.(У меня есть несколько миллионов точек данных и десятки или сотни тысяч бинов в моих реальных данных.)

Есть ли способ сделать это, чтобы избежать сильной зависимости для циклов (или даже избавиться от циклов for)в целом)?

1 Ответ

0 голосов
/ 15 декабря 2018

Просто поместите ваши два столбца в pandas DataFrame, и вы можете легко вычислить медианы, сгруппировав их по «индексам».Давайте посмотрим на практике:

import numpy as np , pandas as pd

indices = [0,1,1,1,3,1,1,0,0,0,3]
data = np.arange(len(indices))

df = pd.DataFrame({"indices": indices, "data": data}) # Your DataFrame
df.head() # Take a look

    indices data
0   0   0
1   1   1
2   1   2
3   1   3
4   3   4
medians = df.groupby("indices").median()# median for each value of `indices`
medians  
        data
    indices 
    0   7.5
    1   3.0
    3   7.0

# Finding indices with no data point
desired_indices = pd.Series([0, 1, 10, -5, 2])
is_in_index = desired_indices.isin(medians.index)
has_no_data = desired_indices[~ is_in_index]
has_no_data
2    10
3    -5
4     2
dtype: int64
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...