我有一个如下数据框。
user cat val
u1 cat1 1
u1 cat2 2
u1 cat3 3
u2 cat1 5
u3 cat4 4
并希望如此变换它。
user cat val(avg)
u1 cat1 1
u1 cat2 2
u1 cat3 3
u1 cat4 4
u2 cat1 5
u2 cat2 2
u2 cat3 3
u2 cat4 4
u3 cat1 3
u3 cat2 2
u3 cat3 3
u3 cat4 4
cat右边还有几个数字列,希望可以用两个NA填充;或者如果可能的话平均出来。
答案 0 :(得分:1)
一种解决方法,
l1=df['user'].unique().tolist()
l2=df['cat'].unique().tolist()
new_df = pd.DataFrame(list(itertools.product(l1,l2))).rename(columns={0:'user',1:'cat'})
new_df=pd.merge(new_df,df,on=['user','cat'],how='left')
输出:
user cat val
0 u1 cat1 1.0
1 u1 cat2 2.0
2 u1 cat3 3.0
3 u1 cat4 NaN
4 u2 cat1 5.0
5 u2 cat2 NaN
6 u2 cat3 NaN
7 u2 cat4 NaN
8 u3 cat1 NaN
9 u3 cat2 NaN
10 u3 cat3 NaN
11 u3 cat4 4.0
答案 1 :(得分:0)
您想要的是每个列的唯一值之间的交叉联接
您可以执行以下操作以创建两个数据帧,每个数据帧的值都唯一
df_col1 = pd.DataFrame(df['user'].unique(), columns=['user'])
df_col2 = pd.DataFrame(df['cat'].unique(), columns=['cat'])
# This step will make a dummy var in each dataframe which will be used to
# merge the dataframes
merged = df_col1.assign(key=1).merge(df_col2.assign(key=1)).drop(['key'], 1)
答案 2 :(得分:0)
您基本上希望为DataFrame
重新编制索引。
from itertools import product
idx = list(product(df['user'].unique(), df['cat'].unique()))
df = df.set_index(['user', 'cat']).reindex(idx).reset_index()
第二部分似乎是将缺失值(在本例中为重新索引后的NaN
)设置为该类别的平均值。您可以通过映射和groupby
来计算平均值。
df.loc[df.val.isnull(), 'val'] = df.loc[df.val.isnull(), 'cat'].map(df.groupby('cat').val.mean())
df
现在是:
user cat val
0 u1 cat1 1.0
1 u1 cat2 2.0
2 u1 cat3 3.0
3 u1 cat4 4.0
4 u2 cat1 5.0
5 u2 cat2 2.0
6 u2 cat3 3.0
7 u2 cat4 4.0
8 u3 cat1 3.0
9 u3 cat2 2.0
10 u3 cat3 3.0
11 u3 cat4 4.0