Python 使用重复索引值旋转数据帧

Python 使用重复索引值旋转数据帧,python,pandas,Python,Pandas,我有一个数据框,每个用户加入我的网站并进行购买时都有相应的行 +---+-----+--------------------+---------+--------+-----+ | | uid | msg | _time | gender | age | +---+-----+--------------------+---------+--------+-----+ | 0 | 1 | confirmed_settings | 1/29/15 | M

我有一个数据框,每个用户加入我的网站并进行购买时都有相应的行

+---+-----+--------------------+---------+--------+-----+
|   | uid |        msg         |  _time  | gender | age |
+---+-----+--------------------+---------+--------+-----+
| 0 |   1 | confirmed_settings | 1/29/15 | M      |  37 |
| 1 |   1 | sale               | 4/13/15 | M      |  37 |
| 2 |   3 | confirmed_settings | 4/19/15 | M      |  35 |
| 3 |   4 | confirmed_settings | 2/21/15 | M      |  21 |
| 4 |   5 | confirmed_settings | 3/28/15 | M      |  18 |
| 5 |   4 | sale               | 3/15/15 | M      |  21 |
+---+-----+--------------------+---------+--------+-----+
我想更改数据帧,使每一行对于uid都是唯一的,并且有一个名为
sale
confirmed\u settings
的列,它们具有操作的时间戳。请注意,并非每个用户都有
销售
,但每个用户都有
确认的\u设置
。如下图所示:

+---+-----+--------------------+---------+---------+--------+-----+
|   | uid | confirmed_settings |  sale   |  _time  | gender | age |
+---+-----+--------------------+---------+---------+--------+-----+
| 0 |   1 | 1/29/15            | 4/13/15 | 1/29/15 | M      |  37 |
| 1 |   3 | 4/19/15            | null    | 4/19/15 | M      |  35 |
| 2 |   4 | 2/21/15            | 3/15/15 | 2/21/15 | M      |  21 |
| 3 |   5 | 3/28/15            | null    | 3/28/15 | M      |  18 |
+---+-----+--------------------+---------+---------+--------+-----+
为此,我正在尝试:

df1 = df.pivot(index='uid', columns='msg', values='_time').reset_index()
df1 = df1.merge(df[['uid', 'gender', 'age']].drop_duplicates(), on='uid')
但我得到了这个错误:
ValueError:Index包含重复的条目,无法重新塑造

如何使用重复的索引值透视df以转换数据帧


编辑:
df1=df.pivot\u表(index='uid',columns='msg',values=''u time')。reset\u index()


给出此错误
DataError:没有要聚合的数值类型
,但我甚至不确定这是正确的路径。

x
是您作为输入的数据帧:

    uid               msg   _time   gender  age
0   1   confirmed_settings  1/29/15 M       37
1   1   sale                4/13/15 M       37
2   3   confirmed_settings  4/19/15 M       35
3   4   confirmed_settings  2/21/15 M       21
4   5   confirmed_settings  3/28/15 M       18
5   4   sale                3/15/15 M       21

y = x.pivot(index='uid', columns='msg', values='_time')
x.join(y).drop('msg', axis=1)
给你:

    uid _time   gender  age     confirmed_settings  sale
0   1   1/29/15     M   37                    NaN   NaN
1   1   4/13/15     M   37                1/29/15   4/13/15
2   3   4/19/15     M   35                    NaN   NaN
3   4   2/21/15     M   21                4/19/15   NaN
4   5   3/28/15     M   18                2/21/15   3/15/15
5   4   3/15/15     M   21                3/28/15   NaN

您可以使用groupby按常用因素进行聚合,用最长时间获取最新日期,然后取消堆叠消息以查看已确认的\u设置和并排销售:

df.groupby(['uid', 'msg', 'gender', 'age']).time.max().unstack('msg')

msg            confirmed_settings     sale
uid gender age                            
1   M      37             1/29/15  4/13/15
3   M      35             4/19/15      NaN
4   M      21             2/21/15  3/15/15
5   M      18             3/28/15      NaN

我怀疑确实存在重复的
uid
-
msg
条目/键(例如,
uid
2在
msg
下有两个已确认的设置条目),这是您在Fixxer回答的注释中提到的。如果存在,则不能使用
pivot
,因为您无法告诉它如何处理聚合过程中遇到的不同值(count?max?mean?sum?)。请注意,索引错误是结果数据透视表df1的索引上的错误,而不是原始数据帧df的错误

pivot\u table
允许您使用
aggfunc
参数执行此操作。像这样的怎么样

df1 = df.pivot_table(index = 'uid', columns = 'msg', values = '_time', aggfunc = len)

这将帮助您找出哪些用户msg记录具有重复条目(任何超过1的条目),在清除它们之后,您可以使用
df
上的
pivot
成功地透视
\u time

在post中有人使用pivot\u table()而不是pivot,并解决了相同的错误,可能值得一试吗?@benjamin我看到了那篇文章并在早些时候尝试过,但得到了一个错误-
DataError:没有要聚合的数值类型
,并且决定不继续沿着这条路径走下去,因为我更不了解这个错误。有什么想法吗?再试一次,只是这次先运行以下命令,将“uid”列强制为数字类型:
df['uid']=df['uid'].astype(int)
@benjamin仍然会遇到同样的错误抱歉,这是目前我所知道的最好的情况。希望有人能给你一个答案。仍然会出现这个错误
ValueError:Index包含重复的条目,不能在执行这段代码时重新格式化
y=x.pivot(Index='uid',columns='msg',values='u time')
我使用的是0.16版。你是哪一个?我的版本是
0.15.2
检查其他答案是否有效?或者升级到0.16?好的-所以我升级到了16.0,它没有解决问题,但我想我发现了我的问题。我的数据集比我的示例大得多,当用户有两个销售或两个确认设置时,一定会有一些数据错误。我将尝试更好地清理数据,您的解决方案应该会起作用。通过这个pivot_表,我发现(回想起来很明显),在11月份的“回落”中,有两个小时的时间戳相同,列数相同(这里是
'hub'
),但值不同。在这种情况下,我使用
df=df[~df.duplicated(subset=['Date','hub'],keep='first')]
来浪费第二个小时。