python - 将变量分成几部分并将每个部分的总和相加
问题描述
我的数据集有 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) 排序时间)。通过对它进行排序,您已经知道自己在哪个 bin 中,只需处理该特定 bin 的总和,然后将总和应用于该 bin 以及每个 bin 下的所有 bin 一次。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])
编辑:这里可能存在一些问题,具体取决于您希望上限或下限是包容性的还是独占性的。我把细节留给你。
推荐阅读
- ios - iOS - superView 的相对顶部空间
- json - 使用哪种结构来解析 JSON 中的数据?
- javascript - 如何在 Angular 中调整 mat-header-cell 宽度?
- node.js - 我如何在 Laravel (5.*) 中使用普通的 SQL 查询?或者我应该学习 ORM 吗?
- elasticsearch - 7.x 版本中的 Elasticsearch 日期解析错误
- javascript - 如何输入文件,然后对其进行过滤并将结果输出到文本区域?
- excel - 如何在excel中获取用户输入的序列号
- c++ - c++ 中的 Potency-function 丢弃了令人困惑的结果
- r - 因子水平的抖动箱线图加上组合水平的箱线图
- java - 是否可以通过 Apache POI 将 XSSFPivotTable 连接到外部 DataSheet(位于外部工作簿)?