Создайте pandas dataframe с неравными строками и столбцами - PullRequest
0 голосов
/ 03 июля 2018

У меня есть файл JSON, из которого я взял ключи для использования в качестве строк для моего фрейма данных, затем я взял все значения из всех ключей и поместил их в плоский список. Я хочу использовать этот список значений в качестве столбцов. Однако есть восемь значений и 5 ключей

JSON:

{
"student1": [
"view_grades",
"view_classes"
],
"student2": [
"view_grades",
"view_classes"
],
"teacher": [
"view_grades",
"change_grades",
"add_grades",
"delete_grades",
"view_classes"
],
"principle": [
"view_grades",
"view_classes",
"change_classes",
"add_classes",
"delete_classes"
]
}

convert.py

def json_to_csv():
    with open('C:/Users/Elitebook/Documents/GitHub/permissions.json') as json_file:
        #convert to python dict
        py_dict = json.load(json_file)
        #first get a list of all the values(permissions) from the dict, flatten the list and return only unique values
        permissions = sorted(set([key for value in py_dict.itervalues() for key in value]))


        #create a dataframe from the python dictionary
        pd.DataFrame.from_dict(py_dict, orient='index', columns=permissions)

Я получаю ошибку AssertionError: 8 columns passed, passed data had 5 columns, я хочу, чтобы у меня было 8 столбцов и 5 строк. Затем я могу поместить то, что я хочу, в поля значений для фрейма данных

Ответы [ 2 ]

0 голосов
/ 03 июля 2018

Вот что вы можете сделать:

from collections import defaultdict


def json_to_csv():
    with open('C:/Users/Elitebook/Documents/GitHub/permissions.json') as json_file:
        # convert to python dict
        py_dict = json.load(json_file)

        # first get a list of all the values(permissions) from the dict, flatten the list and return only unique values
        # this is not necessary anymore since the code below automatically gets a list of unique permissions
        # but if you still want to to it this way it's quite possible
        # permissions = sorted(set([key for value in py_dict.itervalues() for key in value]))

        # create a dictionary of dictionaries in which to put values and populate it
        final = defaultdict(dict)

        # loop through the outer dictionary {'principle': ...}
        for k, v in py_dict.items():
            # loop through the inner list ['add_classes', 'change_classes' ...]
            for i in v:
                # create a key final['principle']['add_classes'] in the final dictionary
                # and set its value to True
                final[k][i] = True

        # This is what final looks like
        # defaultdict(<class 'dict'>,
        #     {'principle': {'add_classes': True,
        #                    'change_classes': True,
        #                    'delete_classes': True,
        #                    'view_classes': True,
        #                    'view_grades': True},
        #      'student1': {'view_classes': True, 'view_grades': True},
        #      'student2': {'view_classes': True, 'view_grades': True},
        #      'teacher': {'add_grades': True,
        #                  'change_grades': True,
        #                  'delete_grades': True,
        #                  'view_classes': True,
        #                  'view_grades': True}})

        # now create the dataframe
        # fillna basically replaces whatever is not available (eg. can student1 add_grades?) by False.
        df = pd.DataFrame(final).fillna(False)

Выход:

                student1  student2  teacher  principle
add_classes        False     False    False       True
add_grades         False     False     True      False
change_classes     False     False    False       True
change_grades      False     False     True      False
delete_classes     False     False    False       True
delete_grades      False     False     True      False
view_classes        True      True     True       True
view_grades         True      True     True       True

Если вы хотите наоборот, просто перенесите DataFrame:

df.T

Выход:

           add_classes  add_grades  change_classes     ...       delete_grades  view_classes  view_grades
student1         False       False           False     ...               False          True         True
student2         False       False           False     ...               False          True         True
teacher          False        True           False     ...                True          True         True
principle         True       False            True     ...               False          True         True
0 голосов
/ 03 июля 2018

Итак, основываясь на вашем описании, я считаю, что ваши столбцы и строки

columns = [
"view_grades",
"view_classes",
"change_grades",
"add_grades",
"delete_grades",
"change_classes",
"add_classes",
"delete_classes"]

rows = [
"student1",
"student2",
"teacher",
"principle"]

что вы хотите сделать, это установить строки в качестве индекса

df = pd.DataFrame(index=rows, columns=permissions)

print(df)
+-----------+-------------+--------------+---------------+------------+---------------+----------------+-------------+----------------+
|           | view_grades | view_classes | change_grades | add_grades | delete_grades | change_classes | add_classes | delete_classes |
+-----------+-------------+--------------+---------------+------------+---------------+----------------+-------------+----------------+
| student1  | NaN         | NaN          | NaN           | NaN        | NaN           | NaN            | NaN         | NaN            |
| student2  | NaN         | NaN          | NaN           | NaN        | NaN           | NaN            | NaN         | NaN            |
| teacher   | NaN         | NaN          | NaN           | NaN        | NaN           | NaN            | NaN         | NaN            |
| principle | NaN         | NaN          | NaN           | NaN        | NaN           | NaN            | NaN         | NaN            |
+-----------+-------------+--------------+---------------+------------+---------------+----------------+-------------+----------------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...