大熊猫数据框中选定列中值的唯一组合和计数

我在熊猫数据框中的数据如下:

df1 = pd.DataFrame({'A':['yes','yes','yes','yes','no','no','yes','yes','yes','no'],
'B':['yes','no','no','no','yes','yes','no','yes','yes','no']})

我的数据是这样的

----------------------------
index         A        B
0           yes      yes
1           yes       no
2           yes       no
3           yes       no
4            no      yes
5            no      yes
6           yes       no
7           yes      yes
8           yes      yes
9            no       no
-----------------------------

我想把它转换成另一个数据帧。预期的输出可以在下面的 python 脚本中显示:

output = pd.DataFrame({'A':['no','no','yes','yes'],'B':['no','yes','no','yes'],'count':[1,2,4,3]})

我的预期输出是这样的

--------------------------------------------
index      A       B       count
--------------------------------------------
0         no       no        1
1         no      yes        2
2        yes       no        4
3        yes      yes        3
--------------------------------------------

实际上,我可以通过使用以下命令来找到所有的组合并计数它们: mytable = df1.groupby(['A','B']).size()

然而,结果是这样的组合在一个单独的列中。我希望将组合中的每个值分成不同的列,并为计数结果再添加一列。有可能做到吗?我可以听听你的建议吗?先谢谢你。

221936 次浏览

你可以调用‘ A’和‘ B’的 groupby,然后调用 size,然后调用 reset_indexrename生成的列:

In [26]:


df1.groupby(['A','B']).size().reset_index().rename(columns={0:'count'})
Out[26]:
A    B  count
0   no   no      1
1   no  yes      2
2  yes   no      4
3  yes  yes      3

更新

一个小小的解释,通过对两列进行分组,将 A 和 B 值相同的行分组,我们调用 size,它返回唯一组的数目:

In[202]:
df1.groupby(['A','B']).size()


Out[202]:
A    B
no   no     1
yes    2
yes  no     4
yes    3
dtype: int64

现在,为了恢复分组的列,我们调用 reset_index:

In[203]:
df1.groupby(['A','B']).size().reset_index()


Out[203]:
A    B  0
0   no   no  1
1   no  yes  2
2  yes   no  4
3  yes  yes  3

这将恢复索引,但是大小聚合将转换为生成的列 0,因此我们必须重命名它:

In[204]:
df1.groupby(['A','B']).size().reset_index().rename(columns={0:'count'})


Out[204]:
A    B  count
0   no   no      1
1   no  yes      2
2  yes   no      4
3  yes  yes      3

groupby确实接受了 arg as_index,我们可以将其设置为 False,因此它不会将分组列作为索引,但是这会生成一个 series,而且您仍然需要恢复索引,以此类推... ... :

In[205]:
df1.groupby(['A','B'], as_index=False).size()


Out[205]:
A    B
no   no     1
yes    2
yes  no     4
yes    3
dtype: int64

稍微有点关联,我在寻找独特的组合,我想出了这个方法:

def unique_columns(df,columns):


result = pd.Series(index = df.index)


groups = meta_data_csv.groupby(by = columns)
for name,group in groups:
is_unique = len(group) == 1
result.loc[group.index] = is_unique


assert not result.isnull().any()


return result

如果你只想断言所有的组合都是唯一的:

df1.set_index(['A','B']).index.is_unique

将@EdChum 的非常好的答案放入函数 count_unique_index中。 这种独特的方法只适用于熊猫系列,而不适用于数据帧。 下面的函数在 R 中重现了 独一无二函数的行为:

惟一返回一个向量、数据框架或数组,如 x,但删除了重复的元素/行。

并根据 OP 的要求添加出现次数的计数。

def count_unique_index(df, by):
return df.groupby(by).size().reset_index().rename(columns={0:'count'})


df1 = pd.DataFrame({'A':['yes','yes','yes','yes','no','no','yes','yes','yes','no'],
'B':['yes','no','no','no','yes','yes','no','yes','yes','no']})
                                                                                                                                                                                 

count_unique_index(df1, ['A','B'])
A    B  count
0   no   no      1
1   no  yes      2
2  yes   no      4
3  yes  yes      3

我还没有用这个做过时间测试,但是尝试起来很有趣。基本上是将两列转换为一列的元组。现在将 那个转换成一个数据帧,执行‘ value _ count ()’命令,查找唯一的元素 还有对它们进行计数。再次摆弄压缩文件,并按照您想要的顺序放置列。您可以使这些步骤更加优雅,但是对于这个问题,使用元组似乎更加自然

b = pd.DataFrame({'A':['yes','yes','yes','yes','no','no','yes','yes','yes','no'],'B':['yes','no','no','no','yes','yes','no','yes','yes','no']})


b['count'] = pd.Series(zip(*[b.A,b.B]))
df = pd.DataFrame(b['count'].value_counts().reset_index())
df['A'], df['B'] = zip(*df['index'])
df = df.drop(columns='index')[['A','B','count']]

在 Panda 1.1.0中,你可以使用带有 DataFrames 的 value_counts方法:

df.value_counts() # or df[['A', 'B']].value_counts()

结果:

A    B
yes  no     4
yes    3
no   yes    2
no     1
dtype: int64

将索引转换为列并按值计数进行排序:

df.value_counts(ascending=True).reset_index(name='count')

结果:

     A    B  count
0   no   no      1
1   no  yes      2
2  yes  yes      3
3  yes   no      4

基于公认的答案和@Bryan P 关于 Count ()和 size ()之间差异的评论,我选择 count ()作为清洁代码,如下所示:

df1.groupby(['A','B']).count().reset_index()