Python видит список слов в виде строки: как анализировать? - PullRequest
0 голосов
/ 10 июня 2018

Я учусь в науке о данных, но у меня пока мало опыта работы с кодом.

Моя проблема: как я могу получить список диктов из строки, которая уже находится в форме спискадиктует, но воспринимается пандами как строка?

Вот набор данных (титры): https://www.kaggle.com/tmdb/tmdb-movie-metadata/data

В столбцах «cast» и «crew» у меня есть такие клетки:

[
{"credit_id": "52fe420dc3a36847f800012d", "department": "Directing", "gender": 1, "id": 3110, "job": "Director", "name": "Allison Anders"}, 
{"credit_id": "52fe420dc3a36847f80001c9", "department": "Writing", "gender": 1, "id": 3110, "job": "Writer", "name": "Allison Anders"}
]

(очевидно, существуют десятки диктов для каждой ячейки)

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

creditsB = pd.read_csv('folder\\tmdb_5000_credits.csv')
creditsDF = pd.DataFrame(creditsB)
type(creditsDF.loc[0,'crew'])
# str

И если я попытаюсь применить к нему list (),он просто создает список из отдельных символов.

dct = list(creditsDF.loc[0,'crew'])
dct
 # output:
 ['[',
 '{',
 '"',
 'c',
 'r',
 'e',
 # and so on

Как я могу заставить python понять, что это на самом деле список диктов, и также обработать его?

Мне нужно выполнить некоторые основные операциикак «для каждого фильма, рассчитать количество актеров» или «для каждого фильма, комсуть число директоров ".Это было бы действительно легко, если бы я только что решил эту большую проблему.

Заранее благодарен за любую помощь!

Ответы [ 3 ]

0 голосов
/ 10 июня 2018

Попробуйте ast.literal_eval :

import ast

text = '''
[
{"credit_id": "52fe420dc3a36847f800012d", "department": "Directing", "gender": 1, "id": 3110, "job": "Director", "name": "Allison Anders"}, 
{"credit_id": "52fe420dc3a36847f80001c9", "department": "Writing", "gender": 1, "id": 3110, "job": "Writer", "name": "Allison Anders"}
]
'''

dicts = ast.literal_eval(text)
# [{'name': 'Allison Anders', 'department': 'Directing', 'credit_id': '52fe420dc3a36847f800012d', 'gender': 1, 'job': 'Director', 'id': 3110}, 
# {'name': 'Allison Anders', 'department': 'Writing', 'credit_id': '52fe420dc3a36847f80001c9', 'gender': 1, 'job': 'Writer', 'id': 3110}]
print(len(dicts))
# 2
print(dicts[0]['department'])
# Directing

Для эффективного применения изменений попробуйте apply :

df['col'] = df['col'].apply(lambda x: ast.literal_eval(x))

Извлечение нужных полей изсловари:

dicts = ast.literal_eval(text)
[d['department'] for d in dicts]
# ['Directing', 'Writing']
0 голосов
/ 10 июня 2018

Итак, у вас есть список словарей, но они отображаются в вашем фрейме данных в виде строк.Это крайне неэффективно.Вы должны стремиться улучшить рабочий процесс upstream , чтобы вы могли читать словари непосредственно в Python.

Однако, учитывая то, что у вас есть, вы можете использовать ast.literal_eval для буквального чтения ваших строк.Затем подайте в pd.DataFrame.Это работает, потому что pd.DataFrame принимает список словарей напрямую.

Оказавшись в кадре данных, вы можете:

  • Подсчитать количество словарей через len(df.index).
  • Используйте логическую индексацию Pandas для фильтрации, например, df.loc[df['job'] == 'Director', 'name'] будет фильтровать имена директоров.

Вот пример:

import pandas as pd
from itertools import chain
from ast import literal_eval

s = pd.Series(['[{"credit_id": "52fe420dc3a36847f800012d", "department": "Directing", "gender": 1, "id": 3110, "job": "Director", "name": "Allison Anders"},{"credit_id": "52fe420dc3a36847f80001c9", "department": "Writing", "gender": 1, "id": 3110, "job": "Writer", "name": "DEF GHI"}]',
               '[{"credit_id": "52fe420dc3a36847f800012e", "department": "Costume", "gender": 0, "id": 4110, "job": "Dresser", "name": "A B"},{"credit_id": "52fe420dc3a36847f80001c8", "department": "Videography", "gender": 1, "id": 3111, "job": "Other", "name": "Joe Smith"}]',
               '[{"credit_id": "52fe420dc3a36847f800012f", "department": "Music", "gender": 1, "id": 5110, "job": "Composer", "name": "C D"},{"credit_id": "52fe420dc3a36847f80001c7", "department": "Production", "gender": 0, "id": 3112, "job": "Writer", "name": "Ben Andrews"}]'])

print(s)

# 0    [{"credit_id": "52fe420dc3a36847f800012d", "de...
# 1    [{"credit_id": "52fe420dc3a36847f800012e", "de...
# 2    [{"credit_id": "52fe420dc3a36847f800012f", "de...
# dtype: object

chained = chain.from_iterable(literal_eval(i) for i in s)

df = pd.DataFrame(list(chained))

print(df)

#                   credit_id   department  gender    id       job  \
# 0  52fe420dc3a36847f800012d    Directing       1  3110  Director   
# 1  52fe420dc3a36847f80001c9      Writing       1  3110    Writer   
# 2  52fe420dc3a36847f800012e      Costume       0  4110   Dresser   
# 3  52fe420dc3a36847f80001c8  Videography       1  3111     Other   
# 4  52fe420dc3a36847f800012f        Music       1  5110  Composer   
# 5  52fe420dc3a36847f80001c7   Production       0  3112    Writer   

#              name  
# 0  Allison Anders  
# 1         DEF GHI  
# 2             A B  
# 3       Joe Smith  
# 4             C D  
# 5     Ben Andrews  
0 голосов
/ 10 июня 2018

Вы должны добавить dict в список

 movies = [ {"credit_id": "52fe420dc3a36847f800012d", "department": "Directing", "gender": 1, "id": 3110, "job": "Director", "name": "Allison Anders"}, {"credit_id": "52fe420dc3a36847f80001c9", "department": "Writing", "gender": 1, "id": 3110, "job": "Writer", "name": "Allison Anders"} ]

    for movie in movies:
        print movie["name"]

    # count movies in list
    print len(movies)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...