Python:给定一组字符串将它们统一地分成k个桶,以便相同的字符串转到同一个桶

时间:2017-08-28 21:12:49

标签: python hash

我有一组(2000个)行,每行有很多元素。连续的一个元素是一个字符串(" name"),每组5行是常见的(唯一名称的总数是500)。 我希望行具有相同的"名称"最终进入同一个桶。因此,函数应始终为给定输入返回相同的值。

我想用它来进行k折交叉验证,所以我需要创建k个桶,其中元素数量尽可能均匀分布,+ / - 少数元素是好的,但超过10%不是。

对于k = 10,我应该有10个桶,每个桶有200个元素,190或210可以,但250和180不是。我试过this answer,但它没有给我一个非常统一的结果。这可能是由于数据集本身造成的,但每桶的元素数量有些平衡会很好。 K通常为5或10。

一个例子:

name1,date1_1,location1_1,number1_1

name1,date1_2,location1_2,number1_2 ...

name1,date1_5,location1_5,number1_5

name2,date2_1,location2_1,number2_1 ...

name2,date2_5,location2_5,number2_5 ...

name400,date400_1,location400_1,number400_1 ...

name400,date400_5,location400_5,number400_5

输出示例:

i,name1,date1_1,location1_1,number1_1

i,name1,date1_2,location1_2,number1_2 ...

i,name1,date1_5,location1_5,number1_5

j,name2,date2_1,location2_1,number2_1 ...

j,name2,date2_5,location2_5,number2_5 ...

k,name400,date400_1,location400_1,number400_1 ...

k,name400,date400_5,location400_5,number400_5

其中1 < i,j,k&lt; K(K = 5或K = 10)

2 个答案:

答案 0 :(得分:1)

在没有更多约束的情况下,你所要求的是不可行的。

想象一下,如果你的输入包含输入字符串&#34; A&#34; N次,N任意大,输入字符串&#34; B&#34;只有1次。想要输出什么?

在任何情况下,您要做的就是解决bin-packing优化问题。

答案 1 :(得分:1)

你想要的是一个哈希表,是吗?在这种情况下,只需创建一个大小为K的字典,并设计一个哈希函数,它将您的字符串作为输入并返回索引。在您提供的示例中,适当的示例可能是:

h = int(name.split(',')[0].strip("name")) % K

公平地说,这很天真并且没有考虑到你的名字的分布(例如你可以有很多name1而很少有name400但是如果它们或多或少相同,然后该方法应该运行得相当好。

如果您的姓名不方便,您可以创建一个只接受您的姓名并吐出数字的辅助表格。例如,假设你有名字:&#34; Bob&#34;,&#34; Sally&#34;,&#34; Larry&#34;,...

nameIndexMappings = {"Bob" : 0, "Sally" : 1, "Larry" : 2}
h = nameIndexMappings[name.split(',')[0]] % K

然后你可以设置另一个字典:

rowMapping = dict()
index = 0
for i in range(0, K):
    rowMapping[i] = list()
for row in rows:
    name = row.split(',')[0]
    if (name not in nameIndexMappings):
        nameIndexMappings[index] = name
        index += 1
    h = nameIndexMappings[name] % K
    rowMapping[h].append(row)

执行此操作后,rowMapping应包含K个列表,每个列表中包含大约相同数量的元素(当然,假设您的所有名称都或多或少地均匀分布)。