Как быстро создать списки ребер (стиль комбинаций itertools) из фрейма данных pandas с булевыми индексами (или другого быстрого решения?) - PullRequest
0 голосов
/ 29 января 2019

Я пытаюсь создать список ребер (уникальный набор a; b, a; c, a; f и т. Д., Где a; b == b; a) из очень большого (длинного) кадра данных pandas, которыйимеет две колонки.Требуемые граничные списки находятся между всеми комбинациями строк одного столбца, условно для другого столбца, имеющего одинаковое значение.Пример ниже показывает это:

df1 = pd.DataFrame({'A':['Mary', 'Mary', 'Mary', 'Clive','Clive','Clive', 'John', 'John'],
                   'B':['Apples','Oranges','Strawberries','Apples','Pears','Bananas','Bananas','Pears']})

И этот фрейм данных выглядит так:

    A   B
0   Mary    Apples
1   Mary    Oranges
2   Mary    Strawberries
3   Clive   Apples
4   Clive   Pears
5   Clive   Bananas
6   John    Bananas
7   John    Pears

с предполагаемым выводом, похожим на это:

Apples; Oranges
Apples; Strawberries
Oranges; Strawberries
Apples; Pears
Apples; Bananas
Pears; Bananas

Мое текущее решение чрезвычайно медленный и выполняет циклическое переключение по уникальным значениям A (с некоторой предварительной фильтрацией для обеспечения того, чтобы счетчик A был> 1 (в противном случае нет попарного края)), принимая логические индексы кадра данных:

for person in df1['A'].unique():
    temp = df1[df1['A']==person]
    ...
    perform some combination\itertools on df1['B']

Однако, поскольку мой df1 на самом деле очень большой, это занимает непомерное количество времени: есть ли здесь какой-то трюк с использованием лямбд и укладки, который я пропускаю?Очень ценю любую помощь!

Ответы [ 2 ]

0 голосов
/ 29 января 2019

Это превосходно, действительно здорово!Большое спасибо!он не рассматривает a; b и b; a (то есть, в частности, кортеж (Bananas, Pears) и (Pears, Bananas)) как одно и то же, поэтому в будущем это (неэффективное) расширение для распаковки ребер внабор:

df2 = pd.DataFrame(df1.groupby('A')['B'].apply(lambda x: list(itertools.combinations(x,2))))
set_of_edges = set()
for toople in df2['B'].tolist():
    for pair in toople:
        if (pair[0] + ';' + pair[1] not in set_of_edges) and\
           (pair[1] + ';' + pair[0] not in set_of_edges):
             set_of_edges.add(pair[0] + ';' + pair[1])
0 голосов
/ 29 января 2019

Как насчет этого?

In [10]: df1.groupby('A')['B'].apply(lambda x : list(itertools.combinations(x,2)))  
Out[10]:
A
Clive    [(Apples, Pears), (Apples, Bananas), (Pears, B...
John                                    [(Bananas, Pears)]
Mary     [(Apples, Oranges), (Apples, Strawberries), (O...
Name: B, dtype: object
...