2014-02-07 355 views
8

计数独特的价值观,我们有一个数据帧,看起来像这样:大熊猫:在数据帧

> df.ix[:2,:10] 
    0 1 2 3 4 5 6 7 8 9 10 
0 NaN NaN NaN NaN 6 5 NaN NaN 4 NaN 5 
1 NaN NaN NaN NaN 8 NaN NaN 7 NaN NaN 5 
2 NaN NaN NaN NaN NaN 1 NaN NaN NaN NaN NaN 

我们只是希望在数据帧的所有唯一值的计数。一个简单的解决办法是:

df.stack().value_counts() 

然而: 1.它看起来像stack返回一个副本,而不是一个视图,它是存储在这种情况下,令人望而却步。它是否正确? 2.我想按行对数据框进行分组,然后获取每个分组的不同直方图。如果我们忽略stack的内存问题并立即使用它,那么如何正确进行分组?

d = pd.DataFrame([[nan, 1, nan, 2, 3], 
       [nan, 1, 1, 1, 3], 
       [nan, 1, nan, 2, 3], 
       [nan,2,2,2, 3]]) 

len(d.stack()) #14 
d.stack().groupby(arange(4)) 
AssertionError: Grouper and axis must be same length 

堆叠数据帧有一个多指标,与一些数量小于n_rows*n_columns的长度,因为nan s的除去。我们不知道如何建立我们的分组。只是在第一级进行操作会好得多,但之后我仍然坚持如何应用我实际需要的分组。

d.stack().groupby(level=0).groupby(list('aabb')) 
KeyError: 'a' 

编辑:一种解决方案,不使用叠加:

f = lambda x: pd.value_counts(x.values.ravel()) 
d.groupby(list('aabb')).apply(f) 
a 1 4 
    3 2 
    2 1 
b 2 4 
    3 2 
    1 1 
dtype: int64 

看起来笨重,虽然。如果有更好的选择,我很高兴听到它。

编辑:丹的评论显示我有一个错字,虽然纠正仍然没有让我们走到终点。

+0

''df.stack().groupby(list('aaaabbb'))。value_counts()''适合我。 –

+0

@DanAllan嗯,value_counts快捷方式已经在0.13以上关闭(以为它已被列入白名单,但不要猜...) –

回答

7

我认为你正在做一个行/列明智的操作,从而可以使用apply

In [11]: d.apply(pd.Series.value_counts, axis=1).fillna(0) 
Out[11]: 
    1 2 3 
0 1 1 1 
1 4 0 1 
2 1 1 1 
3 0 4 1 

注:有一个在作品0.14 value_counts数据帧的方法......这将使它更高效和简洁。

值得注意的是,熊猫value_counts功能还工作的numpy的阵列上,这样就可以把它传递数据帧的值(如使用np.ravel 1-d阵列视图):

In [21]: pd.value_counts(d.values.ravel()) 
Out[21]: 
2 6 
1 6 
3 4 
dtype: int64 

而且,你很接近得到这个正确的,但你需要堆和拆散:

In [22]: d.stack().groupby(level=0).apply(pd.Series.value_counts).unstack().fillna(0) 
Out[22]: 
    1 2 3 
0 1 1 1 
1 4 0 1 
2 1 1 1 
3 0 4 1 

这个错误似乎有点自我解释(4!= 16):

len(d.stack()) #16 
d.stack().groupby(arange(4)) 
AssertionError: Grouper and axis must be same length 

也许你想传递:

In [23]: np.repeat(np.arange(4), 4) 
Out[23]: array([0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]) 
+0

谢谢,安迪。这会变得很紧密,但分组依然不太正确。请参阅我将要放入原始问题的示例。另外,栈是否返回一个副本而不是一个视图? – jeffalstott

+0

问题是nans使行数变化,所以我们不能提前知道如何为'd.stack()'构造一个合适的石斑鱼。正如你所做的那样,不用像'stack'一样操作会更好;我只是没有办法在那里获得适当的分组。 – jeffalstott

+0

@jeffalstott你groupby级别,堆栈是副本。我很困惑最后的结果是你真正想要什么...... –

1

没有足够的代表处发表评论,但安迪的回答:

pd.value_counts(d.values.ravel()) 

是我亲自使用,似乎对我来说,它是迄今为止最通用,最易读的解决方案。另一个优点是,它很容易使用的列的子集:

pd.value_counts(d[[1,3,4,6,7]].values.ravel()) 

pd.value_counts(d[["col_title1","col_title2"]].values.ravel()) 

是否有任何缺点这种方式,或者你要使用堆栈和GROUPBY什么特别的原因?