合并两列以消除重复的行

时间:2018-09-27 09:03:22

标签: python pandas

我目前处于一个数据帧看起来像这样的情况

          id  tp    dt        amt
0          1   CR  2017    94678.0
1          1   CR  2018    13508.0
2          1   DR  2017    78671.0
3          1   DR  2018    13797.0
4          2   CR  2017   111417.0
5          2   CR  2018    21479.0
6          2   DR  2017    95266.0
7          2   DR  2018     1864.0

我想要实现的是将tp和dt两列的值组合起来,并将其用作amt的列名,以可能摆脱具有相同id的多行。简而言之,它应该类似于以下内容

          id     CR2017   CR2018   DR2017  DR2018
0          1    94678.0  13508.0  78671.0  13797.0
1          2   111417.0  21479.0  95266.0   1864.0

我想知道这是否可能吗?我一直在玩一个小时的reset_index,set_index和ivot_table,但还是没有运气 在此先感谢您的帮助,

3 个答案:

答案 0 :(得分:2)

使用set_index与连接的列和unstack进行重塑:

df = df.set_index(['id', df['tp'] + df['dt'].astype(str)])['amt'].unstack().reset_index()
print (df)
   id    CR2017   CR2018   DR2017   DR2018
0   1   94678.0  13508.0  78671.0  13797.0
1   2  111417.0  21479.0  95266.0   1864.0

或创建新列:

df['new'] = df['tp'] + df['dt'].astype(str)
df = df.set_index(['id', 'new'])['amt'].unstack().rename_axis(None, axis=1).reset_index()
print (df)
   id    CR2017   CR2018   DR2017   DR2018
0   1   94678.0  13508.0  78671.0  13797.0
1   2  111417.0  21479.0  95266.0   1864.0

但是如果得到:

  

ValueError:索引包含重复的条目,无法重塑

这意味着重复的id中包含如下joinet对:

print (df)
   id  tp    dt       amt
0   1  CR  2017   94678.0 <-dupe 1 CR 2017
0   1  CR  2017   10000.0 <-dupe 1 CR 2017
1   1  CR  2018   13508.0
2   1  DR  2017   78671.0
3   1  DR  2018   13797.0
4   2  CR  2017  111417.0
5   2  CR  2018   21479.0
6   2  DR  2017   95266.0
7   2  DR  2018    1864.0

解决方案是聚合-通过groupby +聚合功能,例如meansumunstack

df = df.groupby(['id', df['tp'] + df['dt'].astype(str)])['amt'].mean().unstack().reset_index()

pivot_table(默认值为aggfunc='mean'

df = df.pivot_table(index='id',columns=df['tp'] + df['dt'].astype(str), values= 'amt').reset_index()

答案 1 :(得分:0)

df['tpdt'] = df['tp'].astype(str) + df['dt'].astype(str)
del df['tp']
del df['dt']
df = df.groupby(['id','tpdt'],as_index=False).sum()
df = df.reset_index().pivot(columns='tpdt', index='id', values='amt')

添加一些说明。 首先,创建一列,以连接dt和tp中的值。 然后,根据需要删除这些单独的列。 发布您对id和tpdt进行groupby的操作,它将汇总tp和dt的唯一对的amt值。 发布您可以通过tpdt对其进行透视,使其成为列标题。 您甚至可以探索unstack功能。

答案 2 :(得分:0)

一种方法是将pivot_table与默认aggfunc numpy.meanreset_indexrename_axis一起使用

pd.pivot_table(df,index='id', columns = df.tp.astype(str).str.cat(df.dt.astype(str)), values="amt").reset_index(col_level=1).rename_axis(None, axis=1)
  

输出:

    id  CR2017     CR2018    DR2017     DR2018
0   1   94678.0    13508.0   78671.0    13797.0
1   2   111417.0   21479.0   95266.0    1864.0