Python Sunburst Chart - преобразование фрейма данных в формат вложенного списка - PullRequest
0 голосов
/ 14 мая 2018

Я перешел по указанной ниже ссылке для создания диаграммы Sunburst в Python: Как создать диаграмму Sunburst в R или Python?

Прилагается блокнот для справки.

Однако данные требуются в определенном формате для функции создания диаграммы (список, вложенный по уровню).Пример:

data = [
    ('/', 100, [
        ('home', 70, [
            ('Images', 40, []),
            ('Videos', 20, []),
            ('Documents', 5, []),
        ]),
        ('usr', 15, [
            ('src', 6, [
                ('linux-headers', 4, []),
                ('virtualbox', 1, []),

            ]),
            ('lib', 4, []),
            ('share', 2, []),
            ('bin', 1, []),
            ('local', 1, []),
            ('include', 1, []),
        ]),
    ]),
]
sunburst(data)

В том же примере, если кто-то дает мне вывод дерева решений в файле Excel с иерархией узлов в качестве уровней, есть ли способ преобразовать этот вывод Excel (см. Ниже) в список выше?так что я могу создать Sunburst, используя данную функцию.

Выход в Excel:

Level0,Level1,Level2,Level3,Volume
/,,,,15
/,home,Images,,40
/,home,Videos,,20
/,home,Documents,,5
/,home,,,5
/,usr,src,linux-headers,4
/,usr,src,virtualbox,1
/,usr,src,,1
/,usr,lib,,4
/,usr,share,,2
/,usr,bin,,1
/,usr,local,,1
/,usr,include,,1

Ответы [ 2 ]

0 голосов
/ 15 декабря 2018

Nam Nguyen ответ очень хороший, но имеет небольшую ошибку в случаях, когда на определенном уровне есть только одна запись, тогда это утверждение len(dataframe) == 1 становится True, и что одно значение для определенного уровня не включается в результат. Я обновил его ответ, чтобы рассчитывать и для этого случая:

def df_to_nested(dataframe, _groupby, level, col):
"""
- dataframe: source data
- _groupby: groupby columns
- level: start from this level (0 by default)
- col: value to aggregate
"""
result = []
if len(dataframe) == 1:        
    try:
        df = dataframe.groupby(_groupby[level])                    
        for key, val in df: # Iterate through groups                
            result.append(tuple([key, val[col].sum(), []]))
    except Exception: # Reached max depth
        pass
else:
    df = dataframe.groupby(_groupby[level])
    level += 1 # Level0 -> Level1 (increase level)
    for key, val in df: # Iterate through groups
        result.append(tuple([key, val[col].sum(), df_to_nested(val, _groupby, level, col)]))
    level -= 1 # Level1 -> Level0 (decrease level)

return result
0 голосов
/ 05 ноября 2018

Вы можете сделать это с пандами DataFrame и рекурсия:

import pandas as pd

def df_to_nested(dataframe, _groupby, level, col):
    """
    - dataframe: source data
    - _groupby: groupby columns
    - level: start from this level (0 by default)
    - col: value to aggregate
    """
    if len(dataframe) == 1:
        return [] # Reached max depth
    else:
        result = []
        df = dataframe.groupby(_groupby[level])
        level += 1 # Level0 -> Level1 (increase level)
        for key, val in df: # Iterate through groups
            result.append(tuple([key, val[col].sum(), df_to_nested(val, _groupby, level, col)]))
        level -= 1 # Level1 -> Level0 (decrease level)
        return result

df = pd.read_csv('test.csv') # Read your file

_groupby = ['Level0', 'Level1', 'Level2', 'Level3'] # Group by cols

result = df_to_nested(df, _groupby, 0, 'Volume')

print(result)

Пример вывода:

[
    ('/', 100, [
        ('home', 70, [
            ('Documents', 5, []),
            ('Images', 40, []),
            ('Videos', 20, [])
        ]),
        ('usr', 15, [
            ('bin', 1, []),
            ('include', 1, []),
            ('lib', 4, []),
            ('local', 1, []),
            ('share', 2, []),
            ('src', 6, [
                ('linux-headers', 4, []),
                ('virtualbox', 1, [])
            ])
        ])
    ])
]
...