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

Using .groupby() and determining if columns are showing duplicated grouped values or varyinig values

我希望按列 ['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 中输出为 "Varying." 否则,该列将被列为 "Duplicated."

X         Y           Z
Varying   Duplicated  Varying

如有任何帮助或指导,我们将不胜感激。


编辑:正如零指出的那样,我已经更正了 df,因此它们是相同的。另外,为了澄清,我正在查看按 W 分组后 X、Y 或 Z 列是否有所不同。为此,我希望整个列都有一个输出。如果整列中至少有 1 个分组不同,则整列列为 "Varying." Thanks!!

编辑 2:Z 应该有所不同。

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] 使用 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