2014-10-06 203 views
2

如果我有一些数据帧:唯一值,DF大熊猫

A B 
1 a 
1 a 
1 b 
1 c 
1 c 
1 d 
2 a 
2 b 
2 b 
2 d 

我可以使用groupby()命令,并从每一个独特的行计数事件的数量。但现在,我不想统计所有的独特的线。我只想计算B列中有多少个唯一值与列A中的某个值相对应。我现在的输出应该

A UniqueValuesFromB 
1 4 
2 3 

为此,我做了下面的代码:

userNumber = [] 
items = [] 
for pos in df[column].unique(): 
     dfEvent = df[df[column] == pos] 
     userNumber.append(len(numpy.unique(dfEvent[correspondingColumn]))) 
     items.append(pos) 

然后我从一个新的列表做新新DF ...什么是更好的方式来编写这个片段。特别是,我觉得我可以在这里使用groupby()命令或类似命令。 请强调时间性能提高,特别是pythonic方式(或者一些熊猫功能的实现)。

回答

1

使用value_counts另一种方法,这里的关键是要级数传递给count

In [32]: 

df.groupby('A')['B'].apply(pd.value_counts).count(level=0) 
Out[32]: 
A 
1 4 
2 3 
dtype: int64 

另一个变化:

In [48]: 

df.groupby('A')['B'].agg(lambda x: pd.Series.count(x.unique())) 
Out[48]: 
A 
1 4 
2 3 
Name: B, dtype: int64 
+0

好吧,我可以将函数' value_counts'和'groupby'通过'apply'函数。非常感谢你! – Guforu 2014-10-06 12:39:27

+0

非常整齐!但是,应用'pd.value_counts'似乎比在我的机器上使用'unique'进行汇总要慢一点(每个循环2.57 ms,每个循环829μs)。 – 2014-10-06 13:07:47

+0

@ajcr我尝试了一个100,000行的数据框,差异变成了11.4ms,而我的实现与你的实现差异为8.9ms。向量化的'value_counts'和调用'apply'之间可能会有一些争论/折衷,可能有更好的方法,但我还没有找到更好的方法 – EdChum 2014-10-06 13:13:23

1

使用groupby.nunique()

>>> df.groupby("A")["B"].nunique() 
A 
1 4 
2 3 
Name: B, dtype: int64 
+1

有一个内置的'独特'attri所以它可以像这样重写:'df.groupby('A')['B']。unique()。apply(lambda x:len(x))' – EdChum 2014-10-06 12:32:17