2017-04-06 214 views
1

我想生成一个使用seaborn的热图,但是我的数据格式有一个小问题。大熊猫数据透视表热图

目前,我的数据的格式为:

Name  Diag Date 
A  1  2006-12-01 
A  1  1994-02-12 
A  2  2001-07-23 
B  2  1999-09-12 
B  1  2016-10-12 
C  3  2010-01-20 
C  2  1998-08-20 

我想在一个轴上创建热图(优选地在python)表示Name针对Diag - 如果发生。我试图转动使用pd.pivot表,但我得到了错误

ValueError: Index contains duplicate entries, cannot reshape

这个来自:

PIV = df.pivot_table(指数= '名称',列= 'Diag(诊断)')

时间是无关的,但我想显示哪些Names已经有哪些Diag和哪些Diag组合在一起。我是否需要为此创建一个新表,还是有可能?在某些情况下,Name并未与所有Diag

编辑相关: 因为我已经试过: PIV = df.pivot_table(指数= '名称',列= 'Diag(诊断)',值= '时间',aggfunc = “是什么意思”)

但是由于时间的日期时间格式,我结束了:
pandas.core.base.DataError:没有数字类型聚集

+1

这个问题可以从一些代码中得到很大的好处,这些代码显示了你实际上为你的pivot语法尝试了什么。只显示错误会让我们任何人阅读它都必须猜测很多。 –

回答

4

你需要pivot_table一些聚合函数,因为相同的索引和列有多个值,并且pivot只需要唯一值:

print (df) 
    Name Diag Time 
0 A  1 12 <-duplicates for same A, 1 different value 
1 A  1 13 <-duplicates for same A, 1 different value 
2 A  2 14 
3 B  2 18 
4 B  1  1 
5 C  3  9 
6 C  2  8 

df = df.pivot_table(index='Name',columns='Diag', values='Time', aggfunc='mean') 
print (df) 
Diag  1  2 3 
Name     
A  12.5 14.0 NaN 
B  1.0 18.0 NaN 
C  NaN 8.0 9.0 

替代解决方案:

df = df.groupby(['Name','Diag'])['Time'].mean().unstack() 
print (df) 
Diag  1  2 3 
Name     
A  12.5 14.0 NaN 
B  1.0 18.0 NaN 
C  NaN 8.0 9.0 

编辑:

您还可以通过duplicated检查所有重复:

df = df.loc[df.duplicated(['Name','Diag'], keep=False), ['Name','Diag']] 
print (df) 
    Name Diag 
0 A  1 
1 A  1 

编辑:

mean of datetimes不容易 - 需要将日期转换为nanoseconds,获取平均值并最后转换为日期时间。还有另一个问题 - 需要将NaN替换为某个标量,例如0什么转换为0 datetime - 1970-01-01

df.Date = pd.to_datetime(df.Date) 
df['dates_in_ns'] = pd.Series(df.Date.values.astype(np.int64), index=df.index) 
df = df.pivot_table(index='Name', 
        columns='Diag', 
        values='dates_in_ns', 
        aggfunc='mean', 
        fill_value=0) 
df = df.apply(pd.to_datetime) 
print (df) 
Diag     1   2   3 
Name           
A 2000-07-07 12:00:00 2001-07-23 1970-01-01 
B 2016-10-12 00:00:00 1999-09-12 1970-01-01 
C 1970-01-01 00:00:00 1998-08-20 2010-01-20 
+0

谢谢!这很有帮助。现在的问题可能是时间实际上是数据时间格式,所以不是数字。也许我应该只添加一列作为解决方法? – JB1

+0

我认为这是同样的问题。但我有想法如何检查这个值,给我一秒钟。 – jezrael

+0

pandas.core.base.DataError:没有要聚合的数字类型是我当前的错误。 Unfortunatley我没有把正确的数据类型放在时间的例子中,它的形式为'2016-12-12' – JB1