Pandas ValueError: Cannot set a frame with no defined index and a value that cannot be converted to a Series

Pandas ValueError: Cannot set a frame with no defined index and a value that cannot be converted to a Series

参考Rounak Banik的书"Hands on Recommendation Systems with Python",我正在尝试python中基于知识的推荐系统。我们有 IMDB 的电影数据集。

我在最终输出中遇到错误。请在下面查看我的整个代码,构建图表函数是我收到错误的地方。请帮我解决这个问题。谢谢你。

我无法在该平台上找到类似问题的答案。因此我发布了新问题。

import pandas as pd
import numpy as np

df = pd.read_csv('..../RecoSys/data/movies_metadata.csv')
#print all the features(or columns) of the dataFrame
df.columns

#only keep those that we require
df = df[['title', 'genres', 'release_date', 'runtime', 'vote_average', 'vote_count']]
df.head()
#convert release_date into pandas datetime format
df['release_date'] = pd.to_datetime(df['release_date'], errors='coerce')
df['year'] = df['release_date'].apply(lambda x: str(x).split('-')[0] if x!=np.nan else np.nan)
#Helper function to convert NaT to 0 and all other years to integers.

def convert_int(x):
    try:
        return int(x)
    except:
        return 0
#Apply convert_int to the year feature
df['year'] = df['year'].apply(convert_int)

#Drop the release_date column
df = df.drop('release_date', axis=1)

#Display the dataframe
df.head()

#Print genres of the first movie
df.iloc[0]['genres']

#Import the literal_eval function from ast
from ast import literal_eval
import json

#Define a stringified list and output its type
a = "[1,2,3]"
print(type(a))

#Apply literal_eval and output type
b = literal_eval(a)
print(type(b))

#Convert all NaN into stringified empty lists
df['genres'] = df['genres'].fillna('[]')

#Apply literal_eval to convert to the list object
df['genres'] = df['genres'].apply(literal_eval)
#df['genres'] = json.loads(df['genres'])

#Convert list of dictionaries to a list of strings
df['genres'] = df['genres'].apply(lambda x: [i['name'] for i in x] if isinstance(x, list) else [])
df.head()

#Create a new feature by exploding genres
s = df.apply(lambda x: pd.Series(x['genres']),axis=1).stack().reset_index(level=1, drop=True)

#Name the new feature as 'genre'
s.name = 'genre'

#Create a new dataframe gen_df which by dropping the old 'genres' feature and adding the new 'genre'.
gen_df = df.drop('genres', axis=1).join(s)

#Print the head of the new gen_df
gen_df.head(15)

def build_chart(gen_df, percentile=0.8):
    #Ask for preferred genres
    print("Please Input preferred genre")
    genre = input()

    #Ask for lower limit of duration
    print("Please Input shortest duration")
    low_time = int(input())

    #Ask for upper limit of duration
    print("Please Input Longesr Duration")
    high_time = int(input())

    #Ask for lower limit of timeline
    print("Input earliest year")
    low_year = int(input())

    #Ask for upper limit of timeline
    print("Input latest year")
    high_year = int(input())

    #Define a new movies variable to store the preferred movies. Copy the contents of gen_df to movies
    movies = gen_df.copy()

    #Filter based on the condition
    movies = movies[(movies['genre'] == genre) & 
                    (movies['runtime'] >= low_time) & 
                    (movies['runtime'] <= high_time) & 
                    (movies['year'] >= low_year) & 
                    (movies['year'] <= high_year)]

    #Compute the values of C and m for the filtered movies
    C = movies['vote_average'].mean()
    m = movies['vote_count'].quantile(percentile)

    #Only consider movies that have higher than m votes. Save this in a new dataframe q_movies
    q_movies = movies.copy().loc[movies['vote_count'] >= m]

    #Calculate score using the IMDB formula
    q_movies['score'] = q_movies.apply(lambda x: (x['vote_count']/(x['vote_count']+m) * x['vote_average']) 
                                       + (m/(m+x['vote_count']) * C), axis=1)
    #Sort movies in descending order of their scores
    q_movies = q_movies.sort_values('score', ascending=False)

    return q_movies

build_chart(gen_df).head()
Please Input preferred genre
animation
Please Input shortest duration
30
Please Input Longesr Duration
120
Input earliest year
1990
Input latest year
2005

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
~\Anaconda3\lib\site-packages\pandas\core\frame.py in _ensure_valid_index(self, value)
   3423             try:
-> 3424                 value = Series(value)
   3425             except (ValueError, NotImplementedError, TypeError):

~\Anaconda3\lib\site-packages\pandas\core\series.py in __init__(self, data, index, dtype, name, copy, fastpath)
    263 
--> 264                 data = SingleBlockManager(data, index, fastpath=True)
    265 

~\Anaconda3\lib\site-packages\pandas\core\internals\managers.py in __init__(self, block, axis, do_integrity_check, fastpath)
   1480         if not isinstance(block, Block):
-> 1481             block = make_block(block, placement=slice(0, len(axis)), ndim=1)
   1482 

~\Anaconda3\lib\site-packages\pandas\core\internals\blocks.py in make_block(values, placement, klass, ndim, dtype, fastpath)
   3094 
-> 3095     return klass(values, ndim=ndim, placement=placement)
   3096 

~\Anaconda3\lib\site-packages\pandas\core\internals\blocks.py in __init__(self, values, placement, ndim)
   2630         super(ObjectBlock, self).__init__(values, ndim=ndim,
-> 2631                                           placement=placement)
   2632 

~\Anaconda3\lib\site-packages\pandas\core\internals\blocks.py in __init__(self, values, placement, ndim)
     86                 'Wrong number of items passed {val}, placement implies '
---> 87                 '{mgr}'.format(val=len(self.values), mgr=len(self.mgr_locs)))
     88 

ValueError: Wrong number of items passed 6, placement implies 0

During handling of the above exception, another exception occurred:

ValueError                                Traceback (most recent call last)
<ipython-input-53-3c3d1bc1cf24> in <module>
     45     return q_movies
     46 
---> 47 build_chart(gen_df).head()

<ipython-input-53-3c3d1bc1cf24> in build_chart(gen_df, percentile)
     39     #Calculate score using the IMDB formula
     40     q_movies['score'] = q_movies.apply(lambda x: (x['vote_count']/(x['vote_count']+m) * x['vote_average']) 
---> 41                                        + (m/(m+x['vote_count']) * C), axis=1)
     42     #Sort movies in descending order of their scores
     43     q_movies = q_movies.sort_values('score', ascending=False)

~\Anaconda3\lib\site-packages\pandas\core\frame.py in __setitem__(self, key, value)
   3368         else:
   3369             # set column
-> 3370             self._set_item(key, value)
   3371 
   3372     def _setitem_slice(self, key, value):

~\Anaconda3\lib\site-packages\pandas\core\frame.py in _set_item(self, key, value)
   3442         """
   3443 
-> 3444         self._ensure_valid_index(value)
   3445         value = self._sanitize_column(key, value)
   3446         NDFrame._set_item(self, key, value)

~\Anaconda3\lib\site-packages\pandas\core\frame.py in _ensure_valid_index(self, value)
   3424                 value = Series(value)
   3425             except (ValueError, NotImplementedError, TypeError):
-> 3426                 raise ValueError('Cannot set a frame with no defined index '
   3427                                  'and a value that cannot be converted to a '
   3428                                  'Series')

ValueError: Cannot set a frame with no defined index and a value that cannot be converted to a Series

It seems I have entered wrong inputs, hence the reason I had this error. Below is the snapshot of the code results.

These are case sensitive inputs. That was the reason why I had this issue.