我有这个数据框:
user day
A 1
A 4
B 2
B 4
我想将数据框更改为此:
user day_1 day_2 day_3 day_4
A 1 0 0 1
B 0 1 0 1
因此,即使day_3上没有用户,它也会自动生成day_3
我已经尝试过使用此代码,但是它不起作用
for index, row in grouped_user.iterrows():
grouped_user["day_" + str(int(row.active_period))] = 1
答案 0 :(得分:3)
您可以使用函数pivot_table()
:
df.assign(vals=1).\
pivot_table(index='user', columns='day', values='vals', fill_value=0).\
reindex(range(df['day'].min(), df['day'].max()+1), fill_value=0, axis=1).\
add_prefix('day_')
结果:
day day_1 day_2 day_3 day_4
user
A 1 0 0 1
B 0 1 0 1
答案 1 :(得分:2)
使用get_dummies
转换为字符串并聚合max
:
df1 = pd.get_dummies(df.astype(str), columns=['day']).groupby('user', as_index=False).max()
print (df1)
user day_1 day_2 day_4
0 A 1 0 1
1 B 0 1 1
如有必要,添加缺少的天数将user
转换为索引,将get_dummies
与DataFrame.reindex
一起用于将所有可能的天数添加到列中:
days = [f'day_{x}' for x in range(df['day'].min(), df['day'].max() + 1)]
df1 = (pd.get_dummies(df.set_index('user').astype(str))
.max(level=0)
.reindex(columns=days, fill_value=0)
.reset_index())
print (df1)
user day_1 day_2 day_3 day_4
0 A 1 0 0 1
1 B 0 1 0 1
使用crosstab
和DataFrame.clip
的另一种解决方案:
df1 = (pd.crosstab(df['user'], df['day'])
.clip(upper=1)
.reindex(range(df['day'].min(), df['day'].max()+1), fill_value=0, axis=1)
.add_prefix('day_')
.rename_axis(None, axis=1)
.reset_index())
print (df1)
user day_1 day_2 day_3 day_4
0 A 1 0 0 1
1 B 0 1 0 1