若一个集合有
n
n
n个元素,则其有
2
n
−
1
2^n-1
2n−1个子集;
集合种的每一个元素都只有两种状态:在或不在子集中;
可以通过二进制或向量表示元素在或不在子集的状态,例如:集合{a,b,c},当所有元素都不在子集时,向量表示为(0,0,0),对应二进制数为0,0也是用二级制表示元素在或或不在子集的最小二进制数;而所有元素都在时,向量表示为(1,1,1),对应二进制数为7,7则是用二进制表示元素在不在子集的最大二进制数,而
2
3
−
1
=
7
2^3-1=7
23−1=7。所以可以通过列举出0到
2
n
−
1
2^n-1
2n−1之间的所有整数的二进制数进而得出所有子集。
接下来将运用pandas DataFrame表示出集合的所有子集。直接上代码:
def get_subset(arr):
arr=list(set(arr)) #去除重复值
n=len(arr) #计算元素个数
main_set=[]
for i in range(0,2**n): #逐一列举0到2^n-1之间的整数
sub_set=format(i,"b") #十进制转化为整数,注意:是字符串格式
if len(sub_set)<n: #将“0”补全
sub_set=(n-len(sub_set))*"0"+sub_set
main_set.append(list(sub_set))
main_set=pd.DataFrame(main_set)
main_set=main_set.applymap(lambda x:int(x))#.applymap(lambda x:np.nan if x==0 else x)
return main_set
例如集合包含元素
1
,
2
,
3
1,2,3
1,2,3,用二进制表示所有子集的DataFrame格式如下:(而为了避免集合包含0,则需要将0替换为"NaN")
接下来,通过DataFrame相乘就可以得到所有子集:
A=[1,2,3]
main_set=get_subset(A).applymap(lambda x:np.nan if x==0 else x)
Arr=pd.DataFrame([A]*2**len(A))
subset=Arr*main_set
subset
将子集表示为DataFrame格式也为后续的运算带来了很多便利。