[英]Pandas distribute columns to disjoint groups by triplets in rows
給定一個帶有布爾值的 dataframe,其中每行至少有三個 True,每列至少有一個 True,如果可能,我需要將列分配到 N 個不相交的組中,每組中至少有三列。
例如 N = 2
Dataframe:
a b c d e f
0 False True True True False False
1 True False True True True True
2 False False True False True True
唯一可能的結果:b,c,d 和 a,e,f
在較大的數據幀中可能有不止一種解決方案,我需要任何一種解決方案。 如果解決方案需要,可以跳過列,但最好使用盡可能多的列。 結果組可以是任意大小,但不少於三個。 例如,大小為 9、3、11 的 3 個組是 N=3 和具有 30 列的 dataframe 的有效結果。
dataframe 的示例,其中無法分發(在上面的示例中重置 e1)
a b c d e f
0 False True True True False False
1 True False True True False True
2 False False True False True True
我使用了 RichieV 的建議,並通過跳舞鏈接解決了這個問題。
import pandas as pd
from typing import List, Tuple, Set
from itertools import combinations
def distribute_columns_by_triplets(df: pd.DataFrame, group_num: int,
result: List[Tuple[str]], tested: Set[Tuple[str]] = None) -> bool:
if not group_num:
return True
if not df.shape[0]:
return False
if df.shape[1] < 3 * group_num:
return False
if tested is None:
tested = set()
for index, row in df.iterrows():
positives = row[row].index
for i in range(positives.size, 2, -1):
current = combinations(positives, i)
for combination in current:
if combination in tested:
continue
tested.add(combination)
if distribute_columns_by_triplets(df.drop(columns=list(combination)),
group_num - 1, result, tested):
result.append(combination)
return True
df.drop(index, inplace=True)
return False
d = {
'a': [False, True, False],
'b': [True, False, False],
'c': [True, True, True],
'd': [True, True, False],
'e': [False, True, True],
'f': [False, True, True],
}
df = pd.DataFrame(d)
df['device_number'] = df.sum(axis=1)
df.sort_values(by='device_number', inplace=True)
df.drop('device_number', axis=1, inplace=True)
group_num = 2
result = []
if distribute_columns_by_triplets(df.copy(), group_num, result):
print(result)
else:
print('Failed')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.