问题: 创建最有效的函数,将1d数组(group_id列)转换为另一个1d数组(输出列)。
条件是:
最多n
个组可以处于任何批次,在此示例中为n=2
。
每个批次必须包含相同大小的组。
测试条件:尽量减少批数。
该功能会将这些大小不同的组分配给具有唯一标识符的批次,条件是每个批次的大小都是固定的,并且每个批次仅包含相同大小的组。
data = {'group_size': [1,2,3,1,2,3,4,5,1,2,1,1,1],
'batch_id': [1,4,6,1,4,6,7,8,2,5,2,3,3]}
df = pd.DataFrame(data=data)
print(df)
group_size batch_id
0 1 1
1 2 4
2 3 6
3 1 1
4 2 4
5 3 6
6 4 7
7 5 8
8 1 2
9 2 5
10 1 2
11 1 3
12 1 3
我需要什么
some_function( data['group_size'] )
给我data['batch_id']
编辑:
我的笨拙功能
def generate_array():
out = 1
batch_size = 2
dictionary = {}
for i in range(df['group_size'].max()):
# get the mini df corresponding to the group size
sub_df = df[df['group_size'] == i+1 ]
# how many batches will we create?
no_of_new_batches = np.ceil ( sub_df.shape[0] / batch_size )
# create new array
a = np.repeat(np.arange(out, out+no_of_new_batches ), batch_size)
shift = len(a) - sub_df.shape[0]
# remove last elements from array to match the size
if len(a) != sub_df.shape[0]:
a = a[0:-shift]
# update batch id
out = out + no_of_new_batches
# create dictionary to store idx
indexes = sub_df.index.values
d = dict(zip(indexes, a))
dictionary.update(d)
array = [dictionary[i] for i in range(len(dictionary))]
return array
generate_array()
Out[78]:
[1.0, 4.0, 6.0, 1.0, 4.0, 6.0, 7.0, 8.0, 2.0, 5.0, 2.0, 3.0, 3.0]
答案 0 :(得分:2)
这是我的解决方案。我认为它提供的功能与您的功能不完全相同,但是它满足您的三个规则:
import numpy as np
def package(data, mxsz):
idx = data.argsort()
ds = data[idx]
chng = np.empty((ds.size + 1,), bool)
chng[0] = True
chng[-1] = True
chng[1:-1] = ds[1:] != ds[:-1]
szs = np.diff(*np.where(chng))
corr = (-szs) % mxsz
result = np.empty_like(idx)
result[idx] = (np.arange(idx.size) + corr.cumsum().repeat(szs)) // mxsz
return result
data = np.random.randint(0, 4, (20,))
result = package(data, 3)
print(f'group_size {data}')
print(f'batch_id {result}')
check = np.lexsort((data, result))
print('sorted:')
print(f'group_size {data[check]}')
print(f'batch_id {result[check]}')
以n = 3运行的样本,输出的后两行与前两行相同,仅进行排序以便于检查:
group_size [1 1 0 1 2 0 2 2 2 3 1 2 3 2 1 0 1 0 2 0]
batch_id [3 3 1 3 6 1 6 5 6 7 2 5 7 5 2 1 2 0 4 0]
sorted:
group_size [0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 2 3 3]
batch_id [0 0 1 1 1 2 2 2 3 3 3 4 5 5 5 6 6 6 7 7]
工作原理:
1)排序数据
2)检测排序后的数据在何处更改,以标识相等值的组(“组大小的组”)
3)确定各组大小的大小,并为每个大小计算n的整数倍的缺失
4)枚举排序的数据,同时每次切换到新的组大小组时,跳转到n的下一个整数倍;我们使用(3)以矢量化的方式完成
5)地板除以n以获取批次ID
6)改回原始顺序