Pandas Dataframe :将每列中的唯一值更改为NaN

wdebmtf2  于 2023-01-11  发布在  其他
关注(0)|答案(2)|浏览(164)

我有一个DataFrame,其排列方式类似于:

ID   Sample_1   Sample_2
A    0.182      0.754
B    0.182      0.754
C    0.182      0.01
D    0.182      0.2
E    0.9        0.2

如您所见,有一些重复值(“真”测量值)和单个值(实际上是“坏”测量值),我需要做的是用NA替换所有唯一值(即所谓的“坏”值),这需要对所有列进行。
换句话说,最终的 Dataframe 应该如下所示:

ID   Sample_1   Sample_2
A    0.182      0.754
B    0.182      0.754
C    0.182      NaN
D    0.182      0.2
E    NaN        0.2

我考虑过的一个可能的解决方案是使用groupbyfilter来获取索引值(就像Get indexes of unique values in column (pandas)中那样),然后替换这些值,但问题是它一次只能用于一列:

unique_loc = df.groupby("Sample_1").filter(lambda x: len(x) == 1).index
df.loc[unique_loc, "Sample_1"] = np.nan

这意味着它需要在许多列中重复(实际数据中有许多列)。有没有更有效的解决方案?

hmae6n7t

hmae6n7t1#

对于集合NaN s使用DataFrame.where,其中掩码由Series.duplicated针对DataFrame.apply中的每列创建,对于选择所有列而不使用DataFrame.iloc

df.iloc[:, 1:]=df.iloc[:, 1:].where(df.iloc[:, 1:].apply(lambda x:x.duplicated(keep=False)))
print (df)
  ID  Sample_1  Sample_2
0  A     0.182     0.754
1  B     0.182     0.754
2  C     0.182       NaN
3  D     0.182     0.200
4  E       NaN     0.200

如果ID是索引:

df = df.set_index('ID')

df = df.where(df.apply(lambda x: x.duplicated(keep=False)))
print (df)
    Sample_1  Sample_2
ID                    
A      0.182     0.754
B      0.182     0.754
C      0.182       NaN
D      0.182     0.200
E        NaN     0.200
olmpazwi

olmpazwi2#

一种选择是通过np.unique获取这些值,并将其替换为pd.DataFrame.mask

arr, counts = np.unique(df.filter(like='Sample').to_numpy(), return_counts=True)
df.mask(df.isin(arr[counts==1]))

  ID  Sample_1  Sample_2
0  A     0.182     0.754
1  B     0.182     0.754
2  C     0.182       NaN
3  D     0.182     0.200
4  E       NaN     0.200

相关问题