我的数据在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 :(得分:72)
你可以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
这会恢复索引,但是大小聚合会转换为生成的列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
,因此它不会将分组的列设为索引,但会生成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 :(得分:2)
在 Pandas 1.1.0 中,您可以对数据帧使用 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
答案 2 :(得分:0)
有点相关,我一直在寻找独特的组合,然后我想到了这种方法:
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
答案 3 :(得分:0)
我尚未对此进行时间测试,但是尝试很有趣。基本上将两列转换为一列的元组。现在将 that 转换为数据框,执行'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']]
答案 4 :(得分:-1)
将@EdChum的非常好的答案放入函数中。万一您需要多次重复使用。
>>> 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