12. 当多个观察单位被存储于同一张表时进行清理

  1. # 读取movie_altered数据集
  2. In[88]: movie = pd.read_csv('data/movie_altered.csv')
  3. movie.head()
  4. out[88]:

12. 当多个观察单位被存储于同一张表时进行清理 - 图1

  1. # 插入新的列,用来标识每一部电影
  2. In[89]: movie.insert(0, 'id', np.arange(len(movie)))
  3. movie.head()
  4. out[89]:

12. 当多个观察单位被存储于同一张表时进行清理 - 图2

  1. # 用wide_to_long,将所有演员放到一列,将所有Facebook likes放到一列
  2. In[90]: stubnames = ['director', 'director_fb_likes', 'actor', 'actor_fb_likes']
  3. movie_long = pd.wide_to_long(movie,
  4. stubnames=stubnames,
  5. i='id',
  6. j='num',
  7. sep='_').reset_index()
  8. movie_long['num'] = movie_long['num'].astype(int)
  9. movie_long.head(9)
  10. out[90]:

12. 当多个观察单位被存储于同一张表时进行清理 - 图3

  1. # 将这个数据分解成多个小表
  2. In[91]: movie_table = movie_long[['id','title', 'year', 'duration', 'rating']]
  3. director_table = movie_long[['id', 'director', 'num', 'director_fb_likes']]
  4. actor_table = movie_long[['id', 'actor', 'num', 'actor_fb_likes']]
  5. In[92]: movie_table.head(9)
  6. out[90]:

12. 当多个观察单位被存储于同一张表时进行清理 - 图4

  1. In[93]: director_table.head(9)
  2. out[93]:

12. 当多个观察单位被存储于同一张表时进行清理 - 图5

  1. In[94]: actor_table.head(9)
  2. out[94]:

12. 当多个观察单位被存储于同一张表时进行清理 - 图6

  1. # 做一些去重和去除缺失值的工作
  2. In[95]: movie_table = movie_table.drop_duplicates().reset_index(drop=True)
  3. director_table = director_table.dropna().reset_index(drop=True)
  4. actor_table = actor_table.dropna().reset_index(drop=True)
  5. In[96]: movie_table.head()
  6. out[96]:

12. 当多个观察单位被存储于同一张表时进行清理 - 图7

  1. In[97]: director_table.head()
  2. out[97]:

12. 当多个观察单位被存储于同一张表时进行清理 - 图8

  1. # 比较内存的使用量
  2. In[98]: movie.memory_usage(deep=True).sum()
  3. out[98]: 2318234
  4. In[99]: movie_table.memory_usage(deep=True).sum() + \
  5. director_table.memory_usage(deep=True).sum() + \
  6. actor_table.memory_usage(deep=True).sum()
  7. out[99]: 2624898
  1. # 创建演员和导演的id列
  2. In[100]: director_cat = pd.Categorical(director_table['director'])
  3. director_table.insert(1, 'director_id', director_cat.codes)
  4. actor_cat = pd.Categorical(actor_table['actor'])
  5. actor_table.insert(1, 'actor_id', actor_cat.codes)
  6. director_table.head()
  7. out[100]:

12. 当多个观察单位被存储于同一张表时进行清理 - 图9

  1. In[101]: actor_table.head()
  2. out[101]:

12. 当多个观察单位被存储于同一张表时进行清理 - 图10

  1. # 可以用这两张表生成要用的中间表。先来做director表
  2. In[102]: director_associative = director_table[['id', 'director_id', 'num']]
  3. dcols = ['director_id', 'director', 'director_fb_likes']
  4. director_unique = director_table[dcols].drop_duplicates().reset_index(drop=True)
  5. director_associative.head()
  6. out[102]:

12. 当多个观察单位被存储于同一张表时进行清理 - 图11

  1. In[103]: director_unique.head()
  2. out[103]:

12. 当多个观察单位被存储于同一张表时进行清理 - 图12

  1. # 再来做actor表
  2. In[104]: actor_associative = actor_table[['id', 'actor_id', 'num']]
  3. acols = ['actor_id', 'actor', 'actor_fb_likes']
  4. actor_unique = actor_table[acols].drop_duplicates().reset_index(drop=True)
  5. actor_associative.head()
  6. out[104]:

12. 当多个观察单位被存储于同一张表时进行清理 - 图13

  1. In[105]: actor_unique.head()
  2. out[105]:

12. 当多个观察单位被存储于同一张表时进行清理 - 图14

  1. # 查看新的表所使用的内存量
  2. In[106]: movie_table.memory_usage(deep=True).sum() + \
  3. director_associative.memory_usage(deep=True).sum() + \
  4. director_unique.memory_usage(deep=True).sum() + \
  5. actor_associative.memory_usage(deep=True).sum() + \
  6. actor_unique.memory_usage(deep=True).sum()
  7. out[106]: 1833402
  1. In[107]: movie_table.head()
  2. out[107]:

12. 当多个观察单位被存储于同一张表时进行清理 - 图15

  1. # 可以通过将左右表组合起来形成movie表。首先将附表与actor/director表结合,然后将num列pivot,再加上列的前缀
  2. In[108]: actors = actor_associative.merge(actor_unique, on='actor_id') \
  3. .drop('actor_id', 1) \
  4. .pivot_table(index='id', columns='num', aggfunc='first')
  5. actors.columns = actors.columns.get_level_values(0) + '_' + \
  6. actors.columns.get_level_values(1).astype(str)
  7. directors = director_associative.merge(director_unique, on='director_id') \
  8. .drop('director_id', 1) \
  9. .pivot_table(index='id', columns='num', aggfunc='first')
  10. directors.columns = directors.columns.get_level_values(0) + '_' + \
  11. directors.columns.get_level_values(1).astype(str)
  12. In[109]: actors.head()
  13. out[109]:

12. 当多个观察单位被存储于同一张表时进行清理 - 图16

  1. In[110]: directors.head()
  2. out[110]:

12. 当多个观察单位被存储于同一张表时进行清理 - 图17

  1. In[111]: movie2 = movie_table.merge(directors.reset_index(), on='id', how='left') \
  2. .merge(actors.reset_index(), on='id', how='left')
  3. In[112]: movie2.head()
  4. out[112]:

12. 当多个观察单位被存储于同一张表时进行清理 - 图18

  1. In[113]: movie.equals(movie2[movie.columns])
  2. out[113]: True