Python 将一个变量分成几个部分,并将每个部分的总数相加

Python 将一个变量分成几个部分,并将每个部分的总数相加,python,pandas,Python,Pandas,我的数据集有200万个观察值。我想根据变量“rv”的值将其分为200个类别。例如,假设我有0-1000、1000-2000、2000-3000、3000-4000、4000-5000个类别,我想将一个观察值拆分为4500,如下所示:前4个类别各1000个,最后一个类别500个。我有以下代码,它可以工作,但速度非常慢: # create random data set import pandas as pd import numpy as np data = np.random.randint(0

我的数据集有200万个观察值。我想根据变量“rv”的值将其分为200个类别。例如,假设我有0-1000、1000-2000、2000-3000、3000-4000、4000-5000个类别,我想将一个观察值拆分为4500,如下所示:前4个类别各1000个,最后一个类别500个。我有以下代码,它可以工作,但速度非常慢:

# create random data set
import pandas as pd
import numpy as np
data = np.random.randint(0, 5000, size=2000)
df = pd.DataFrame({'rv': data})

#%% slice
sizes = [0, 1000, 2000, 3000, 4000, 5000]
size_names = ['{:.0f} to {:.0f}'.format(lower, upper) for lower, upper in zip(sizes[0:-1], sizes[1:])]

for lower, upper, name in zip(sizes[0:-1], sizes[1:], size_names):
    df[name] = df['rv'].apply(lambda x: max(0, (min(x, upper) - lower)))

# summary table
df_slice = df[size_names].sum()

有没有更好的方法来做到这一点,更好的方法意味着更快?有200万个观察值和200个类别,这需要相当长的时间(不确定我在代码完成之前停止了多长时间)。

我编写了一个算法,预先对数据进行排序,将数据从一个O(n*m)循环(在数据和类别上)带到一个O(n)循环(在数据上,尽管有一个O(n log n)是时候整理一下了)。通过对它进行排序,您已经知道您在哪个箱子中,只需处理特定箱子的总和,然后将总和应用于该箱子以及每个箱子下面的所有箱子一次。在200个类别的200万个数据点上,大约需要1.2秒。希望有帮助:

from time import time
from random import randint

data = [randint(0, 4999) for i in range(2000000)]
sizes = range(0, 5001, 25)
bound_pairs = [[sizes[i], sizes[i + 1]] for i in range(len(sizes) - 1)]
results = [0 for i in range(len(sizes) - 1)]

data.sort()

curr_bin = 0
curr_bin_count = 0
curr_bin_sum = 0
for d in data:
    if d >= bound_pairs[curr_bin][1]:
        results[curr_bin] += curr_bin_sum
        for i in range(curr_bin):
            results[i] += curr_bin_count * (bound_pairs[i][1] - bound_pairs[i][0])
        curr_bin_count = 0
        curr_bin_sum = 0

        while d >= bound_pairs[curr_bin][1]:
            curr_bin += 1

    curr_bin_count += 1
    curr_bin_sum += d - bound_pairs[curr_bin][0]

results[curr_bin] += curr_bin_sum
for i in range(curr_bin):
    results[i] += curr_bin_count * (bound_pairs[i][1] - bound_pairs[i][0])

编辑:这里可能会有一些问题,这取决于您希望上限或下限是包含的还是独占的。我将详细信息留给您。

您是否能够在处理之前对数据进行排序?是的,我可以对数据进行排序。那会加速吗?