векторизованный способ получения pandas значений индекса из условия суммы - PullRequest
0 голосов
/ 13 февраля 2020

Я работаю с фреймом данных с 800k записями и хочу создать более быстрый способ получения значений индекса между условием суммы по сравнению с моей текущей рабочей версией, выполняющей df.iterrows (). У меня есть столбец, который я хочу суммировать до значения, а затем сбросить начальные позиции индекса суммы, чтобы начать цикл заново.

Простым примером будет любое суммированное значение больше 1000.

series = [193, 371, 163, 287, 627, 323, 382, 263, 361, 501, 282, 411, 335, 528,  396, 465, 309, 243, 348, 387, 416, 446, 464, 227, 301]

series = pd.Series(series)
target_value = 1000
start = 0
end = 0
sum_values = series[start:end+1].sum()
index_values = []
for indx, val in series.iteritems():
    if sum_values >= target_value:
        index_values.append([start, end])
        sum_values = series[end+1]
        start = end
        end += 1
    else:
        sum_values = series[start:end+1].sum()
        end += 1

index_values:
[[0, 4], [4, 7], [7, 10], [10, 13], [13, 16], [16, 20], [20, 23]]

Я не могу понять, как я могу сделать это с numpy, где функция с возвратом после превышения значения .

Любая помощь в направлении будет высоко ценится.

1 Ответ

0 голосов
/ 13 февраля 2020

единственное, что я вижу, что вы можете сделать, - это ускорить этот процесс, чтобы лучше угадать размер вашего интервала и выполнить несколько мультипроцессоров.

Вы можете использовать np.split, чтобы сделать правильное начальное предположение, например:

import numpy as np
interval_size = 10
values = np.random.rand(1000)*10
np.array(np.split(values,interval_size)).sum(axis=0)

out:

array([4630.79410889, 5251.52550577, 4810.02960764, 5215.12946275,
       4962.31855639, 4725.5437016 , 4710.573337  , 4990.37905624,
       5324.98906685, 5105.86335981])

и выполнять итерации, пока не найдете оптимальные начальные значения, например:

interval = []
cost = []
for i in range(10,100,1):
    try:
        values = np.random.rand(1000)*10
        bigger = np.array(np.split(values,i)).sum(axis=0)>100
        smaller = np.array(np.split(values,i)).sum(axis=0)<200
        cost.append(sum(bigger*smaller)/len(smaller))
        interval.append(i)
    except: pass
cost
Out[73]: [0.0, 0.5, 1.0, 0.32, 0.0]

interval
Out[74]: [10, 20, 25, 40, 50]

, в данном случае 25 - наилучшее начальное предположение для размера интервала

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...