Панды: объединить кадр данных и серию / заполнить отсутствующие точки данных - PullRequest
0 голосов
/ 27 августа 2018

Я хочу объединить pd.DataFrame и pd.Series, включая все отсутствующие данные.

print(x)

>>> movie  rating  user
0    100       1     1
1    200       4     1
2    300       3     1
3    100       5     2
4    200       3     2
5    300       2     3

x - это pd.DataFrame.

print(y)

>>> 0    100
1    200
2    300
3    400

y - это pd.Series. Я хочу использовать эти данные в качестве movie столбца в x. С x и y я хочу получить такой результат, как:

    movie  rating  user
0     100     1.0     1
1     200     4.0     1
2     300     3.0     1
3     400     NaN     1
4     100     5.0     2
5     200     3.0     2
6     300     NaN     2
7     400     NaN     2
8     100     NaN     3
9     200     NaN     3
10    300     2.0     3
11    400     NaN     3

Объединенные данные должны быть в основном x со столбцом movie=[100,200,300,400], как в y для каждого пользователя.

Ответы [ 3 ]

0 голосов
/ 27 августа 2018

unstack + stack + reindex

x.set_index(['user','movie']).rating.unstack().\
     reindex(columns=y).\
        stack(dropna=False).\
           reset_index(name='rating')
Out[40]: 
    user  movie  rating
0      1    100     1.0
1      1    200     4.0
2      1    300     3.0
3      1    400     NaN
4      2    100     5.0
5      2    200     3.0
6      2    300     NaN
7      2    400     NaN
8      3    100     NaN
9      3    200     NaN
10     3    300     2.0
11     3    400     NaN
0 голосов
/ 27 августа 2018

Лично я очень предпочитаю решение @ Wen, но в качестве альтернативы отметим, что вы можете создать нужные столбцы user и movie, а затем объединить их с исходными DataFrame:

pd.DataFrame(list(itertools.product(set(x.user), y)), columns=['user', 'movie'])\
  .merge(x, how='outer')

Out[76]:
    user  movie  rating
0      1    100     1.0
1      1    200     4.0
2      1    300     3.0
3      1    400     NaN
4      2    100     5.0
5      2    200     3.0
6      2    300     NaN
7      2    400     NaN
8      3    100     NaN
9      3    200     NaN
10     3    300     2.0
11     3    400     NaN
0 голосов
/ 27 августа 2018

Вы можете использовать groupby и reindex, чтобы переиндексировать каждый идентификатор на y.values. Затем вы можете сбросить индекс и ffill и bfill столбец user по каждой группе, чтобы заполнить значения NaN:

new = (x.groupby('user',as_index=False)
       .apply(lambda i: i.set_index('movie').reindex(y.values))
       .reset_index('movie'))

new['user'] = new.groupby(new.index)['user'].ffill().bfill().astype(int)

>>> new
   movie  rating  user
0    100     1.0     1
0    200     4.0     1
0    300     3.0     1
0    400     NaN     1
1    100     5.0     2
1    200     3.0     2
1    300     NaN     2
1    400     NaN     2
2    100     NaN     3
2    200     NaN     3
2    300     2.0     3
2    400     NaN     3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...