提问者:小点点

如果2个或更多行值相同,则将这些值(但1)更改为np.nan,但等于0的相同值除外


我有一个能源使用数据框架。 为了对数据进行后处理,我需要确保我只使用可靠的能源。 这里的一个步骤是确保数据帧行中的值不相同,因为这表明数据库中存在错误(多年来,除了零能源使用(由于可再生能源安装)外,家庭的能源使用几乎从来都不相同)。

关于一个简单的例子DF,问题如下:

  • 数据帧可以包含空单元格(np.nan)。
  • 如果2个或更多行值相同,则保留其中一个
    相同值,并将其余值设置为np.nan,除非相同值为零。

在下面的示例中,第2行和第4行被替换为np.nan,但最后一行没有被替换,因为相同的值都是零。

有人知道如何从最初的df到想要的df吗? 除了相同值为零的情况外,代码可以正常工作,这些值不应更改为np.nan(请参见df中的最后一行)

初始DF:

   y_2010  y_2011  y_2012
      4.0     6.0     3.0
      2.0     7.0     7.0
      9.0     NaN     NaN
      3.0     3.0     3.0
      2.0     4.0     6.0
      0.0     0.0     NaN

所需DF:

   y_2010  y_2011  y_2012
      4.0     6.0     3.0
      2.0     7.0     NaN
      9.0     NaN     NaN
      3.0     NaN     NaN
      2.0     4.0     6.0
      0.0     0.0     NaN

尝试的代码:

import pandas as pd
import numpy as np

df = pd.DataFrame({"y_2010": [4,2,9,3,2,0],
                   "y_2011": [6,7,np.nan,3,4,0],
                   "y_2012": [3,7,np.nan,3,6,np.nan]})
print(df)

mask = df.apply(pd.Series.duplicated, 1)
df = df.mask(mask, np.nan)

print(df)

   y_2010  y_2011  y_2012
      4.0     6.0     3.0
      2.0     7.0     NaN
      9.0     NaN     NaN
      3.0     NaN     NaN
      2.0     4.0     6.0
      0.0     NaN     NaN  -> 0 changed to NaN and I don't want that

共2个答案

匿名用户

让我们尝试添加0检查

df = df.mask(df.apply(pd.Series.duplicated, 1) & df.ne(0))
   y_2010  y_2011  y_2012
0     4.0     6.0     3.0
1     2.0     7.0     NaN
2     9.0     NaN     NaN
3     3.0     NaN     NaN
4     2.0     4.0     6.0
5     0.0     0.0     NaN

匿名用户

您可以尝试:

df.apply(lambda x: x.mask(x.duplicated()&x.ne(0)), axis=1)

输出:

   y_2010  y_2011  y_2012
0     4.0     6.0     3.0
1     2.0     7.0     NaN
2     9.0     NaN     NaN
3     3.0     NaN     NaN
4     2.0     4.0     6.0
5     0.0     0.0     NaN