Получение набора индексов, которые отличаются только одним элементом, является нетривиальным, поскольку может возникнуть несколько групп, которые имеют отдельные индексы.Кроме того, составной индекс может иметь разные наборы значений, как вы можете видеть ниже.Я советую вам соблюдать осторожность с таким правилом при объединении индексов.
Я включил пару помощников, чтобы получить генератор групп индексов.Пересечения легко выполняются с помощью наборов в функции aggregate
.Наконец, создается копия оригинальной серии для хранения новых данных, в противном случае она мешает генерации группы, если вы добавляете к той же серии:
import pandas as pd
from itertools import combinations
def match(index=None, seed=None, dist=1):
seed_set = set(seed)
index_set = set(index)
if len(index_set - seed_set) == dist and seed_set.issubset(index_set):
return True
return False
def index_groups(series):
indices = list(series.index)
# Get unique index group seeds
seeds = set()
for i in indices:
seeds |= set(combinations(i, len(i)-1))
# Produce index groups
for seed in seeds:
group = [i for i in indices if match(index=i, seed=seed)]
if len(group) > 1:
yield group
def aggregate_indices(series, index_list=[]):
new_index = set(index_list[0])
for next_index in index_list[1:]:
new_index = new_index | set(next_index)
new_index = tuple(new_index)
new_data = set(series[index_list[0]])
for next_index in index_list[1:]:
new_data = new_data & set(series[next_index])
new_data = list(new_data)
return pd.Series(index=[new_index], data=[new_data])
s = pd.Series(index=[(1,2,3), (2,3,4), (1,3,4)],
data=[[11,12,13,14], [13,14,15,16], [11,12,15,16]])
new_s = s.copy()
for index_group in list(index_groups(s)):
new_s = new_s.append(aggregate_indices(s, index_list=index_group))
print(new_s)
"""
Out:
(1, 2, 3) [11, 12, 13, 14]
(2, 3, 4) [13, 14, 15, 16]
(1, 3, 4) [11, 12, 15, 16]
(1, 2, 3, 4) [11, 12]
(1, 2, 3, 4) [13, 14]
(1, 2, 3, 4) [16, 15]
"""