Как сводить / перекрёстные данные в Python 3? - PullRequest
3 голосов
/ 21 января 2012

Какое лучшее решение для сводных / перекрестных таблиц в Python 3?Есть ли встроенная функция, которая сделает это?В идеале я ищу решение Python 3, которое не имеет внешних зависимостей.Например, учитывая вложенный список:

nl = [["apples", 2 "New York"], 
      ["peaches", 6, "New York"],
      ["apples", 6, "New York"],
      ["peaches", 1, "Vermont"]]  

Я хотел бы иметь возможность переставить поля строк и данных в группах:

             apples    peaches
New York        2         6
Vermont         6         1

Вышеприведенный пример является тривиальным, но естьрешение, которое было бы проще, чем использовать itertools.groupby каждый раз, когда требуется разворот?В идеале, решение позволило бы поворачивать строчные данные в любом столбце.Я спорил об использовании панд , но это внешняя библиотека и имеет ограниченную поддержку Python 3.

Ответы [ 2 ]

1 голос
/ 21 января 2012

Вот простой код.Предоставление строки / столбца / общих итогов оставлено читателю в качестве упражнения.

class CrossTab(object):

    def __init__(
        self,
        missing=0, # what to return for an empty cell.
                   # Alternatives: '', 0.0, None, 'NULL'
        ):
        self.missing = missing
        self.col_key_set = set()
        self.cell_dict = {}
        self.headings_OK = False

    def add_item(self, row_key, col_key, value):
        self.col_key_set.add(col_key)
        try:
            self.cell_dict[row_key][col_key] += value
        except KeyError:
            try:
                self.cell_dict[row_key][col_key] = value
            except KeyError:
                self.cell_dict[row_key] = {col_key: value}

    def _process_headings(self):
        if self.headings_OK:
            return
        self.row_headings = list(sorted(self.cell_dict.keys()))
        self.col_headings = list(sorted(self.col_key_set))
        self.headings_OK = True

    def get_col_headings(self):
        self._process_headings()
        return self.col_headings

    def generate_row_info(self):
        self._process_headings()
        for row_key in self.row_headings:
            row_dict = self.cell_dict[row_key]
            row_vals = [
                row_dict.get(col_key, self.missing)
                for col_key in self.col_headings
                ]
            yield row_key, row_vals

if __name__ == "__main__":

    data = [["apples", 2, "New York"], 
      ["peaches", 6, "New York"],
      ["apples", 6, "New York"],
      ["peaches", 1, "Vermont"]]  

    ctab = CrossTab(missing='uh-oh')
    for s in data:
        ctab.add_item(row_key=s[2], col_key=s[0], value=s[1])
    print()
    print('Column headings:', ctab.get_col_headings())
    for row_heading, row_values in ctab.generate_row_info():
        print(repr(row_heading), row_values)

Вывод:

Column headings: ['apples', 'peaches']
'New York' [8, 6]
'Vermont' ['uh-oh', 1]

См. Также этот ответ .

И этот , о котором я забыл.

0 голосов
/ 21 января 2012

itertools.groupby именно для этой проблемы.Вам будет сложно найти что-то лучшее, особенно в стандартной библиотеке.

...