使用.groupby()并确定列是否显示重复的分组值或varyinig值

时间:2017-10-02 05:56:29

标签: python pandas duplicates pandas-groupby

我希望按列['W']进行分组,然后确定列中的分组是否显示差异。我尝试了.groupby()后跟.duplicated()的几次迭代,但似乎无法使代码适合我想要的内容。

对于下面的df:

import pandas

df

W X Y Z
A 2 3 4
B 2 1 1
A 1 3 4
B 2 1 4
C 2 1 1

按['W']分组会产生以下结果:

df

W X Y Z
A 2 3 4
A 1 3 4

B 2 1 4
B 2 1 1

C 2 1 1

您在上面看到,当按['W']分组时,在分组A中的列['X']中出现方差,但在分组B和C中不出现。对于列['Y']和['Z'],任何分组都不会出现差异。

如果按['W']分组导致在[[X'],['Y']或['Z']列的至少一个分组中出现差异,则应在df2中输出整列作为“变化”。否则,该列将被列为“重复”。

X         Y           Z
Varying   Duplicated  Varying

非常感谢任何帮助或指示。

编辑:正如Zero指出的那样,我已经纠正了df,所以它们是相同的。另外,为了澄清,我希望看看在X分组之后X,Y或Z列是否有所不同。为此,我希望整个列都有一个输出。如果整个列中至少有1个分组不同,则整个列列为“变化”。谢谢!

编辑2:Z应该是变化的。

2 个答案:

答案 0 :(得分:1)

IIUC

f = lambda x: 'Duplicated' if x == 1 else 'Varying'
df.set_index('W').groupby('W').nunique().applymap(f)

            X           Y           Z
W                                    
A     Varying  Duplicated     Varying
B     Varying  Duplicated     Varying
C  Duplicated  Duplicated  Duplicated

答案 1 :(得分:1)

选项1] 使用np.std

In [280]: (df.groupby('W').agg(np.std)
             .fillna(0).eq(0).all()
             .replace({False: 'Varying', True: 'Duplicated'}))
Out[280]:
X       Varying
Y    Duplicated
Z       Varying
dtype: object

选项2] 使用nunique

In [272]: (df.groupby('W').agg(lambda x: x.nunique() != len(x) or len(x) == 1)
             .all()
             .replace({False: 'Varying', True: 'Duplicated'}))
Out[272]:
X       Varying
Y    Duplicated
Z       Varying
dtype: object

选项3] 使用duplicated

In [273]: (df.groupby('W').agg(lambda x: x.duplicated(keep=False).any() or len(x) == 1)
             .all()
             .replace({False: 'Varying', True: 'Duplicated'}))
Out[273]:
X       Varying
Y    Duplicated
Z       Varying
dtype: object

详细

In [275]: df
Out[275]:
   W  X  Y  Z
0  A  2  3  4
1  B  2  1  1
2  A  1  3  4
3  B  2  1  4
4  C  2  1  1

对于o1

In [281]: df.groupby('W').agg(np.std).fillna(0)
Out[281]:
          X    Y        Z
W
A  0.707107  0.0  0.00000
B  0.000000  0.0  2.12132
C  0.000000  0.0  0.00000

In [282]: df.groupby('W').agg(np.std).fillna(0).eq(0)
Out[282]:
       X     Y      Z
W
A  False  True   True
B   True  True  False
C   True  True   True

和o2

In [273]: df.groupby('W').agg(lambda x: x.nunique() != len(x) or len(x) == 1)
Out[273]:
       X     Y      Z
W
A  False  True   True
B   True  True  False
C   True  True   True

In [274]: df.groupby('W').agg(lambda x: x.nunique() != len(x) or len(x) == 1).all()
Out[274]:
X    False
Y     True
Z    False
dtype: bool