Серия Pandas - генерирует список всех столбцов с некоторым условием - PullRequest
0 голосов
/ 27 сентября 2019

У меня есть данные в пандах.тип серии.Индекс представляет собой список (из некоторых чисел), а значение для данного индекса снова является списком (из некоторых других чисел).

Я хочу сделать следующее: я беру все индексы, которые перечислены, которые отличаются только на один элемент (например, [1,2,3] и [1,2,4] отличаются на один элемент), а затем я создаю новый ряд, индексы которого являются объединением этих индексов, а соответствующие значения являются пересечениемзначений их соответствующих индексов.(например: если index - [1,2,3] имеет значение [11,21,13], а index- [1,2,4] имеет значение [11,22,13,12], то новая серия имеет индекс [1,2,3,4] со значением [11,13].)

Я так долго пытался, но я запутался в том, чтобы брать союзы и перекрестки.

Ответы [ 2 ]

0 голосов
/ 27 сентября 2019

Это на самом деле не вопрос панд, а просто вопрос комбинации.Кроме того, использование списков в качестве индекса - это плохо : список является не подлежащим изменению типом, поэтому вы не можете использовать ни loc, ни [].ИМХО, поэтому вы должны немедленно преобразовать его в управляемый контейнер, такой как dict, с кортежами (типа hashable) в качестве ключей и списками в качестве значений.

Предполагая, что ваша серия s:

[1, 2, 3]        [11, 21, 13]
[1, 2, 4]    [11, 22, 13, 12]
dtype: object

Я бы использовал:

data = {tuple(i): j for i,j in s.items()}
for i,j in itertools.combinations(data.keys(), 2):
    si = set(i)
    sj = set(j)
    if len(si.difference(sj)) == 1:
        key = si.union(sj)
        val = set(data[i]).intersection(set(data[j]))
        print((i,data[i]), (j, data[j]), '=>', (list(key), list(val)))

Что дает, как и ожидалось:

((1, 2, 3), [11, 21, 13]) ((1, 2, 4), [11, 22, 13, 12]) => ([1, 2, 3, 4], [11, 13])
0 голосов
/ 27 сентября 2019

Получение набора индексов, которые отличаются только одним элементом, является нетривиальным, поскольку может возникнуть несколько групп, которые имеют отдельные индексы.Кроме того, составной индекс может иметь разные наборы значений, как вы можете видеть ниже.Я советую вам соблюдать осторожность с таким правилом при объединении индексов.

Я включил пару помощников, чтобы получить генератор групп индексов.Пересечения легко выполняются с помощью наборов в функции 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]
"""
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...