Вот мое предложение, используя combinations
из itertools
, как справедливо предложено @rpanai с groupby
и pipe
, что позволяет вам получать разные группы в рамках одной и той же операции. Вы возвращаете логическое значение для значения выше или ниже порогового значения 0,05, и вы ломаете l oop, когда логическое значение равно True:
np.random.seed(123)
df = pd.DataFrame(np.random.randint(0,1000,size=(100, 4)), columns=list('ABCD'))
df['Category'] = np.random.randint(1, 3, df.shape[0])
df.head()
list_iter = [idx for idx in combinations(df.Category.unique(), 2)]
test = dict()
for i, j in list_iter:
test[(i, j)] = df.groupby("Category").pipe(lambda g: ttest_ind(g["C"].get_group(i),
g["C"].get_group(j))[1] > 0.05)
if test[(i, j)]:
break
Здесь, в этом примере, словарь test
равен:
{(2, 1): True}
Работает с любым количеством групп, например, если в категории есть три группы, с df['Category'] = np.random.randint(1, 4, df.shape[0])
, вывод для test
будет выглядеть так:
{(2, 3): True}
РЕДАКТИРОВАТЬ : если вы хотите, чтобы значения A были успешными, вы можете сделать следующее:
list_iter = [idx for idx in combinations(df.Category.unique(), 2)]
test = dict()
for i, j in list_iter:
test[(i, j)] = df.groupby("Category").pipe(lambda g: ttest_ind(g["C"].get_group(i),
g["C"].get_group(j))[1] > 0.05)
if test[(i, j)]:
output = df.loc[df["Category"].isin([i,j]), ["Category", "A"]]
break
Я заменил D
на C
, потому что, перечитывая свой вопрос, вы говорите, что хотите сравнить C
по разным значениям Category
. Если это не C
, а C
и D
, combinations
не будет распространяться на все группы, которые вы хотите. Я также изменил логическое значение на значение выше 0,05, так как вы хотите, чтобы группы, которые существенно не различались.
Здесь у меня есть следующий результат для test
:
{(2, 3): True}
и для output
:
Category A
0 2 510
1 3 988
2 2 595
Вы получаете значения A
для двух категорий 2
и 3
, где значения C
были несущественно отличаются.