Python 熊猫:合并数据帧和系列/填充缺失的数据点

Python 熊猫:合并数据帧和系列/填充缺失的数据点,python,pandas,Python,Pandas,我想合并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) >&g

我想合并
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
。 我想将此数据用作
x
中的
movie
列。 使用
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=[100200300400]
y
类似。

您可以使用
groupby
reindex
来重新索引
y.values
上的每个ID。然后,您可以重置索引,并将
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

您可以使用
groupby
reindex
,对
y.values
上的每个ID重新编制索引。然后,您可以重置索引,并将
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

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

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

我个人更喜欢@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

我个人更喜欢@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

请解释您想要如何组合这两个对象。从您的示例中不清楚。@DYZ系列
[100,200,300]
似乎是重复的,必须用不同的重复系列
[100,200,300,400]
替换。请解释如何组合这两个对象。从您的示例中不清楚。@DYZ系列
[100200300]
似乎是一个重复的系列,必须用不同的重复系列
[100200300400]
来替换。非常棒的解决方案;不过,在pandas 0.23.4上,我最终得到了名为
['user','level_1','rating']
的列。@fuglede我认为版本的不同可能会导致输出略有不同。非常棒的解决方案;不过,在pandas 0.23.4上,我最终得到了名为
['user','level_1','rating']
的列。@fuglede我认为版本不同可能会导致输出略有不同。