RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1058727
Accepted
danilshik
danilshik
Asked:2020-12-15 04:36:42 +0000 UTC2020-12-15 04:36:42 +0000 UTC 2020-12-15 04:36:42 +0000 UTC

数据框中的字典

  • 772

我已经解析了一些数据,现在我需要将数据从 dict 转换为 dataframe。我不是熊猫的朋友,所以希望能得到你的帮助

df = pd.DataFrame(text)
print(df)

不知何故不清楚

0   {'film_name': '21 мост', 'film_genres': ['боев...
1   {'film_name': 'FORD против FERRARI', 'film_gen...
2   {'film_name': 'Аббатство Даунтон', 'film_genre...
3   {'film_name': 'Арахисовый сокол', 'film_genres...
4   {'film_name': 'Война токов', 'film_genres': ['...
5   {'film_name': 'Давай разведемся', 'film_genres...

text:

{
  'filmes': [
    {
      'film_name': '21 мост', 
      'film_genres': ['боевик', 'триллер'], 
      'cinames': [
        {
          'cinema': 'Nescafe-IMAX', 
          'sessions': [
            {
              'time': '23:55', 
              'price': '190 ₽', 
              'format': '2D'
            }
          ]
        }, 
        {
          'cinema': 'Каро 13 Кунцево', 
          'sessions': [
            {
              'time': '23:25', 
              'price': '430 ₽', 
              'format': '2D'
            }
          ]
        }, 
        {
          'cinema': 'Каро 8 Теплый Стан', 
          'sessions': [
            {
              'time': '23:25', 
              'price': '350 ₽', 
              'format': '2D'
            }
          ]
        }, 
        {
          'cinema': 'Киномакс Мозаика', 
          'sessions': [
            {
              'time': '23:50', 
              'price': '290 ₽', 
              'format': '2D'
            }
          ]
        },
      ]
    }
  ]
}
python
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Евгений
    2020-12-15T06:17:05Z2020-12-15T06:17:05Z

    为了更清晰,稍微补充了输入数据:

    text = {
      'filmes': [
        {
          'film_name': '21 мост', 
          'film_genres': ['боевик', 'триллер'], 
          'cinames': [
            {
              'cinema': 'Nescafe-IMAX', 
              'sessions': [
                {
                  'time': '23:55', 
                  'price': '190 ₽', 
                  'format': '2D'
                },
                {
                  'time': '23:50', 
                  'price': '290 ₽', 
                  'format': '2D'
                }
              ]
            }, 
            {
              'cinema': 'Каро 13 Кунцево', 
              'sessions': [
                {
                  'time': '23:25', 
                  'price': '430 ₽', 
                  'format': '2D'
                },
                {
                  'time': '23:25', 
                  'price': '430 ₽', 
                  'format': '2D'
                },
                {
                  'time': '23:55', 
                  'price': '190 ₽', 
                  'format': '2D'
                }
              ]
            }, 
            {
              'cinema': 'Каро 8 Теплый Стан', 
              'sessions': [
                {
                  'time': '23:25', 
                  'price': '350 ₽', 
                  'format': '2D'
                }
              ]
            }, 
            {
              'cinema': 'Киномакс Мозаика', 
              'sessions': [
                {
                  'time': '23:50', 
                  'price': '290 ₽', 
                  'format': '2D'
                }
              ]
            },
          ]
        },
        {
          'film_name': '21 мост', 
          'film_genres': ['боевик', 'триллер'], 
          'cinames': [
            {
              'cinema': 'Nescafe-IMAX', 
              'sessions': [
                {
                  'time': '23:55', 
                  'price': '190 ₽', 
                  'format': '2D'
                },
                {
                  'time': '23:50', 
                  'price': '290 ₽', 
                  'format': '2D'
                }
              ]
            }, 
            {
              'cinema': 'Каро 13 Кунцево', 
              'sessions': [
                {
                  'time': '23:25', 
                  'price': '430 ₽', 
                  'format': '2D'
                },
                {
                  'time': '23:25', 
                  'price': '430 ₽', 
                  'format': '2D'
                },
                {
                  'time': '23:55', 
                  'price': '190 ₽', 
                  'format': '2D'
                }
              ]
            }, 
            {
              'cinema': 'Каро 8 Теплый Стан', 
              'sessions': [
                {
                  'time': '23:25', 
                  'price': '350 ₽', 
                  'format': '2D'
                }
              ]
            }, 
            {
              'cinema': 'Киномакс Мозаика', 
              'sessions': [
                {
                  'time': '23:50', 
                  'price': '290 ₽', 
                  'format': '2D'
                }
              ]
            },
          ]
        }
      ]
    }
    

    现在有两部电影(我很懒,所以他们有相同的数据)+一些电影院现在有几场放映。

    我的问题解决方案:

    import pandas as pd
    text = {} # тут входные данные, которые приводил выше
    
    # добавляем первую строку-заголовок
    dat = [['Фильм', 'Жанры', 'Кинотеарты', 'Время', 'Цена', ' Формат']]
    # работаем с каждым фильмом отдельно
    for film in text['filmes']:
        # для удобства выносим в отдельные переменные жанры и кинотеатры
        film_genres = film['film_genres']
        cinames = film['cinames']
    
        # узнаём, сколько же всего строк будут занимать все данные о нашем фильме
        n = len(film_genres) if len(film_genres) > len(cinames) else len(cinames)
        k = 0
        for c in cinames:
            k += len(c['sessions'])
        n = k if k > n else n
    
        # т.к. для предыдущей операции k себя исчерпал, и он не нужен, используем его в других целях
        # k - количество сеансов, которые осталось вывести для текущего кинотеатра
        k = 0
        # cin - номер текущего кинотеатра
        cin = 0
        # работаем с каждой строкой текущего фильма
        for i in range(n):
            # создаём список, который содержит поля строки
            l = []
    
            # если это первая строка, в ней нужно вывести заголовок. Иначе - выводим пустую строку, чтобы просто занять ячейку
            if i == 0:
                l.append(film['film_name'])
            else:
                l.append('')
    
            # если i меньше, чем количество жанров - на этой строке можно вывести жанр. Иначе - занимаем ячейку пустой строкой
            if i < len(film_genres):
                l.append(film_genres[i])
            else:
                l.append('')
            
            # если все строки для предыдущего кинотеатра уже выведены (осталось вывести 0 строк), то
            if not k:
                # записываем название следующего кинотеатра, в k - сколько строк выделить для этого кинотеатра (сколько сессий в этом театре), увеличиваем индекс кинотеатра
                l.append(cinames[cin]['cinema'])
                k = len(cinames[cin]['sessions'])
                cin += 1
            else:
                # если выведены ещё не все строки - просто занимаем ячейку, где должно быть название (чтобы не дублировать его по 100 раз)
                l.append('')
            
            # добавляем время, цену и формат текущего сеанса. 
            # Сеансы начинаются с конца (тот, что указан последним, выведется первым. 
            # Если нужен прямой порядок - меняем [k-1] на [1-k]
            l.append(cinames[cin-1]['sessions'][k-1]['time'])
            l.append(cinames[cin-1]['sessions'][k-1]['price'])
            l.append(cinames[cin-1]['sessions'][k-1]['format'])
            # переходим к следующему сеансу
            k -= 1
            # сохраняем полученную строку в наш список
            dat.append(l)
      
    # список всех строк укомплектован, делаем из него датафрейм и выводим в консоль
    df = pd.DataFrame(dat)
    print(df)
    

    结果:

              0        1                   2      3      4        5
    0     Фильм    Жанры          Кинотеарты  Время   Цена   Формат
    1   21 мост   боевик        Nescafe-IMAX  23:50  290 ₽       2D
    2            триллер                      23:55  190 ₽       2D
    3                        Каро 13 Кунцево  23:55  190 ₽       2D
    4                                         23:25  430 ₽       2D
    5                                         23:25  430 ₽       2D
    6                     Каро 8 Теплый Стан  23:25  350 ₽       2D
    7                       Киномакс Мозаика  23:50  290 ₽       2D
    8   21 мост   боевик        Nescafe-IMAX  23:50  290 ₽       2D
    9            триллер                      23:55  190 ₽       2D
    10                       Каро 13 Кунцево  23:55  190 ₽       2D
    11                                        23:25  430 ₽       2D
    12                                        23:25  430 ₽       2D
    13                    Каро 8 Теплый Стан  23:25  350 ₽       2D
    14                      Киномакс Мозаика  23:50  290 ₽       2D
    

    也许,他们Pandas有一些自己的想法,可以在任意数量的嵌套级别上解包这样的可迭代对象,但我不知道它们。我们珍惜我们所拥有的。

    • 1
  2. Best Answer
    Andrey
    2020-12-15T06:30:58Z2020-12-15T06:30:58Z

    您可以使用将字典扩展为数据框json_normalize()。

    In [51]: from pandas.io.json import json_normalize                                                 
    
    In [52]: # Преобразуем списки жанров в строки                                                      
    
    In [53]: for f in d['filmes']: 
        ...:     f['film_genres'] = ', '.join(f['film_genres']) 
        ...:                                                                                           
    
    In [54]: d                                                                                         
    Out[54]: 
    {'filmes': [{'film_name': '21 мост',
       'film_genres': 'боевик, триллер',
       'cinames': [{'cinema': 'Nescafe-IMAX',
         'sessions': [{'time': '23:55', 'price': '190 ₽', 'format': '2D'}]},
        {'cinema': 'Каро 13 Кунцево',
         'sessions': [{'time': '23:25', 'price': '430 ₽', 'format': '2D'}]},
        {'cinema': 'Каро 8 Теплый Стан',
         'sessions': [{'time': '23:25', 'price': '350 ₽', 'format': '2D'}]},
        {'cinema': 'Киномакс Мозаика',
         'sessions': [{'time': '23:50', 'price': '290 ₽', 'format': '2D'}]}]}]}
    
    In [55]: df = (json_normalize(d['filmes'],  
        ...:                      record_path=['cinames', 'sessions'], 
        ...:                      meta=['film_name', 'film_genres', ['cinames', 'cinema']]) 
        ...:       .rename(columns={'cinames.cinema': 'cinema'}) 
        ...:       .reindex(columns=['film_name', 'film_genres', 'cinema', 'format', 'time', 'price']) 
        ...: )                                                                                         
    
    In [56]: df                                                                                        
    Out[56]: 
      film_name      film_genres              cinema format   time  price
    0   21 мост  боевик, триллер        Nescafe-IMAX     2D  23:55  190 ₽
    1   21 мост  боевик, триллер     Каро 13 Кунцево     2D  23:25  430 ₽
    2   21 мост  боевик, триллер  Каро 8 Теплый Стан     2D  23:25  350 ₽
    3   21 мост  боевик, триллер    Киномакс Мозаика     2D  23:50  290 ₽
    

    对于多部电影,您可以指定多列作为索引:

    In [80]: df                                                                                        
    Out[80]: 
       film_name      film_genres              cinema format   time  price
    0    21 мост  боевик, триллер        Nescafe-IMAX     2D  23:55  190 ₽
    1    21 мост  боевик, триллер        Nescafe-IMAX     2D  23:50  290 ₽
    2    21 мост  боевик, триллер     Каро 13 Кунцево     2D  23:25  430 ₽
    3    21 мост  боевик, триллер     Каро 13 Кунцево     2D  23:25  430 ₽
    4    21 мост  боевик, триллер     Каро 13 Кунцево     2D  23:55  190 ₽
    5    21 мост  боевик, триллер  Каро 8 Теплый Стан     2D  23:25  350 ₽
    6    21 мост  боевик, триллер    Киномакс Мозаика     2D  23:50  290 ₽
    7    22 мост  боевик, триллер        Nescafe-IMAX     2D  23:55  190 ₽
    8    22 мост  боевик, триллер        Nescafe-IMAX     2D  23:50  290 ₽
    9    22 мост  боевик, триллер     Каро 13 Кунцево     2D  23:25  430 ₽
    10   22 мост  боевик, триллер     Каро 13 Кунцево     2D  23:25  430 ₽
    11   22 мост  боевик, триллер     Каро 13 Кунцево     2D  23:55  190 ₽
    12   22 мост  боевик, триллер  Каро 8 Теплый Стан     2D  23:25  350 ₽
    13   22 мост  боевик, триллер    Киномакс Мозаика     2D  23:50  290 ₽
    
    In [81]: df.set_index(['film_name', 'cinema', 'film_genres'])                                      
    Out[81]: 
                                                 format   time  price
    film_name cinema             film_genres                         
    21 мост   Nescafe-IMAX       боевик, триллер     2D  23:55  190 ₽
                                 боевик, триллер     2D  23:50  290 ₽
              Каро 13 Кунцево    боевик, триллер     2D  23:25  430 ₽
                                 боевик, триллер     2D  23:25  430 ₽
                                 боевик, триллер     2D  23:55  190 ₽
              Каро 8 Теплый Стан боевик, триллер     2D  23:25  350 ₽
              Киномакс Мозаика   боевик, триллер     2D  23:50  290 ₽
    22 мост   Nescafe-IMAX       боевик, триллер     2D  23:55  190 ₽
                                 боевик, триллер     2D  23:50  290 ₽
              Каро 13 Кунцево    боевик, триллер     2D  23:25  430 ₽
                                 боевик, триллер     2D  23:25  430 ₽
                                 боевик, триллер     2D  23:55  190 ₽
              Каро 8 Теплый Стан боевик, триллер     2D  23:25  350 ₽
              Киномакс Мозаика   боевик, триллер     2D  23:50  290 ₽
    
    • 1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    根据浏览器窗口的大小调整背景图案的大小

    • 2 个回答
  • Marko Smith

    理解for循环的执行逻辑

    • 1 个回答
  • Marko Smith

    复制动态数组时出错(C++)

    • 1 个回答
  • Marko Smith

    Or and If,elif,else 构造[重复]

    • 1 个回答
  • Marko Smith

    如何构建支持 x64 的 APK

    • 1 个回答
  • Marko Smith

    如何使按钮的输入宽度?

    • 2 个回答
  • Marko Smith

    如何显示对象变量的名称?

    • 3 个回答
  • Marko Smith

    如何循环一个函数?

    • 1 个回答
  • Marko Smith

    LOWORD 宏有什么作用?

    • 2 个回答
  • Marko Smith

    从字符串的开头删除直到并包括一个字符

    • 2 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5