我希望每个字母至少有4个样品。但是,应该按id选择样本,以便首先使用匹配度最高的样本。(行级别的最大值)。
我已经尝试将总和拖动到行水平,然后从最高值到最低值采样。然而,这种方法不能保证最小的班级规模。可以随机选择剩余的样本来填充类。
有谁知道我如何在熊猫中解决这个问题吗?
id A B C D E
0 1 1 0 0 0
1 1 0 0 1 0
2 0 1 1 0 0
3 0 1 0 0 0
4 1 1 1 0 1
5 0 1 0 1 1
6 0 0 0 1 1
7 1 0 0 0 1
8 1 0 1 1 1
9 0 0 0 0 0
10 1 1 0 0 0
11 1 0 0 1 0
12 0 1 1 0 0
13 0 1 0 0 0
14 1 1 1 0 1
15 0 1 0 1 1
16 0 0 0 1 1
17 1 0 0 0 1
18 1 0 1 1 1
19 0 0 0 0 0
sum 10 10 6 8 10
如果我理解正确的话,您试图从每个具有最高指数的字母中挑选至少4个样本。
选择最高索引的一种方法是根据索引出现的列数对索引进行排序-
high_index = []
for col in df.columns:
high_index.append(sorted(df[df[col] > 0].index.values, reverse=True))
这为您提供了每个列的最高索引-即对于A
,带1的最高索引是18
# print(high_index)
[[18, 17, 14, 11, 10, 8, 7, 4, 1, 0],
[15, 14, 13, 12, 10, 5, 4, 3, 2, 0],
[18, 14, 12, 8, 4, 2],
[18, 16, 15, 11, 8, 6, 5, 1],
[18, 17, 16, 15, 14, 8, 7, 6, 5, 4]]
然后你可以根据它们出现的次数对每个索引进行排名-
rank_index = list(enumerate([sum([x in y for y in high_index]) for x in range(df.index.size)]))
# print(rank_index)
[(0, 2),
(1, 2),
(2, 2),
(3, 1),
(4, 4),
(5, 3),
(6, 2),
(7, 2),
(8, 4),
(9, 0),
(10, 2),
(11, 2),
(12, 2),
(13, 1),
(14, 4),
(15, 3),
(16, 2),
(17, 2),
(18, 4),
(19, 0)]
或者,索引0
以2列1出现(您也可以通过对axis=1
求和得到相同的结果)
如果按这些秩重新排序df
,那么最小秩为4或更多的所有行都可以用于您的样本
reordered_index = [x for x, y in sorted(rank_index, reverse=True, key=lambda x: x[1])]
df_2 = df.loc[reordered_index, :]
df_2 = df_2.cumsum()
df_2['min_samples'] = df_2.min(axis=1)
# print(df_2)
A B C D E min_samples
id
4 1 1 1 0 1 0
8 2 1 2 1 2 1
14 3 2 3 1 3 1
18 4 2 4 2 4 2
5 4 3 4 3 5 3
15 4 4 4 4 6 4
0 5 5 4 4 6 4
1 6 5 4 5 6 4
2 6 6 5 5 6 5
6 6 6 5 6 7 5
7 7 6 5 6 8 5
10 8 7 5 6 8 5
11 9 7 5 7 8 5
12 9 8 6 7 8 6
16 9 8 6 8 9 6
17 10 8 6 8 10 6
3 10 9 6 8 10 6
13 10 10 6 8 10 6
9 10 10 6 8 10 6
19 10 10 6 8 10 6
您可以选择的最小示例是df_2
的前6行。
这就是我从你的问题中理解的。数据框为df
。
创建matches
列:
df = df.assign(matches=df.sum(axis=1))
对包含字母的行按匹配次数排序:
letter = "A"
ans = df[df[letter] == 1].sort_values(by="matches", ascending=False)
如果你需要一个随机的样本:
n = 4
ans = ans.sample(n)
最后,如果样本需要再次按匹配项排序:
ans = ans.sort_values(by="matches", ascending=False)
Forletter == "B"
:
>>> ans
A B C D E matches
15 0 1 0 1 1 3
10 1 1 0 0 0 2
0 1 1 0 0 0 2
3 0 1 0 0 0 1