问题:熊猫数据框中选定列和计数中值的唯一组合
我将数据存储在pandas数据框中,如下所示:
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()
但是,事实证明,此类组合在单个列中。我想将组合中的每个值分隔到不同的列中,并且还要为计数结果增加一列。有可能这样做吗?请问您有什么建议吗?先感谢您。
回答 0
你可以groupby
上的cols“A”和“B”和呼叫size
,然后reset_index
和rename
生成列:
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
更新
简要说明一下,通过将2列分组,将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
这将还原索引,但是大小聚合将变成生成的column 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
确实接受了as_index
我们可以设置为的arg ,False
因此它不会使分组的列成为索引,但是这会生成a,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
回答 1
稍微相关,我一直在寻找独特的组合,然后我想到了这种方法:
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
回答 2
将@EdChum的非常好的答案放入函数中count_unique_index
。唯一方法仅适用于熊猫系列,不适用于数据框。下面的函数重现了R中唯一函数的行为:
unique返回向量,数据框或数组(如x),但删除了重复的元素/行。
并根据OP的要求添加发生次数。
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']})
def count_unique_index(df, by):
return df.groupby(by).size().reset_index().rename(columns={0:'count'})
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
回答 3
我还没有做时间测试,但是尝试很有趣。基本上将两列转换为一列的元组。现在将其转换为数据框,执行“ value_counts()”以查找唯一元素并对其进行计数。再次拉动拉链,然后按需要排列各列。您可能可以使步骤更优雅,但是对我来说,使用元组似乎更自然
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']]