从 Pandas 数据帧的每一行中为现有变量创建新变量。

5

我有一个数据框,看起来像这样:

0  target_year ID   v1  v2  
1  2000         1  0.3   1
2  2000         2  1.2   4
...
10 2001         1    3   2
11 2001         2    2   2

我能提供以下输出:

0   ID   v1_1  v2_1  v1_2  v2_2  
1    1    0.3     1     3     2 
2    2    1.2     4     2     2

你有任何想法如何做到这一点吗?

3个回答

6
你可以使用pd.pivot_table,使用IDGroupBy.cumcount作为列。
然后我们可以使用带有f-strings的列表推导式将MultiIndex标题合并为单个级别:
cols = df.groupby('ID').ID.cumcount() + 1
df_piv = (pd.pivot_table(data = df.drop('target_year', axis=1)[['v1','v2']],
                         index = df.ID, 
                         columns = cols)
df_piv.columns = [f'{i}_{j}' for i,j in df_piv.columns]


     v1_1  v1_2  v2_1  v2_2
ID                        
1    0.3   3.0     1     2
2    1.2   2.0     4     2

1
好的回答,为了使它更符合预期输出,你可能应该执行 cols = df.groupby('ID').ID.cumcount() + 1 - Erfan
谢谢你建议@erfan。 - yatu
看起来不错,谢谢!只需要稍微修改一下以适应我的真实数据框。 - Thomuf

2
使用GroupBy.cumcount来生成计数器列,然后使用DataFrame.set_indexDataFrame.unstack进行重塑,最后可以用列表推导式和f-string来扁平化结果:最初的回答
g = df.groupby('ID').ID.cumcount() + 1

df = df.drop('target_year', axis=1).set_index(['ID', g]).unstack()
df.columns = [f'{a}_{b}' for a, b in df.columns]
df = df.reset_index()
print (df)
   ID  v1_1  v1_2  v2_1  v2_2
0   1   0.3   3.0     1     2
1   2   1.2   2.0     4     2

0

如果您的数据仅有两年,您还可以使用 merge 进行合并:

cols = ['ID','v1', 'v2']
df[df.target_year.eq(2000)][cols].merge(df[df.target_year.eq(2001)][cols],
                                 on='ID',
                                 suffixes=['_1','_2'])

输出

    ID  v1_1    v2_1    v1_2    v2_2
0   1   0.3     1       3.0     2
1   2   1.2     4       2.0     2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接