在python pandas dataframe中对值进行分组并检查来自另一列的值是否相互抵消

3pvhb19x  于 2023-05-05  发布在  Python
关注(0)|答案(1)|浏览(177)

我需要检查一个数据框的“CP”列内的值,而我的数据框是由“中心”列分组的,是否相互抵消。
下面是一个例子:样品:
| 中心|CP|
| --------------|--------------|
| 3N7D|10个|
| 3N1F|二|
| 公司简介|-9|
| 3N7D|-1|
| 3N7D|-10|
| 8D92|一百九十八|
| 3N7D|-10|
| 公司简介|二|
| 8D92|一百九十五|
| 8D92|-3|
例外结果:
| 中心|CP|取消|
| --------------|--------------|--------------|
| 3N7D|10个|取消|
| 3N1F|二||
| 公司简介|-9||
| 3N7D|-1||
| 3N7D|-10|取消|
| 8D92|一百九十八|(不取消-195和-3,因为只有当有1个值取消时才需要取消,例如一次取消-198)|
| 3N7D|-10|(未取消,因为仅有的10个已取消)|
| 公司简介|二||
| 8D92|一百九十五||
| 8D92|-3||
以下是我尝试的:

grouped_df = df.groupby("Centre")
for name, group in grouped_df:
    cp_values = group["CP"].values
    for i in range(len(cp_values)):
        for j in range(i+1, len(cp_values)):
            if cp_values[i] == -cp_values[j]:
                print("i = ",i)
                print("j = ",j)
                print("CP = ",cp_values[i])
                print("CP2 = ",cp_values[j])

谢谢你的帮助。

nkhmeac6

nkhmeac61#

您可以使用自定义的pivot来识别一个数字与它的负对应部分(通过numpy.sign获得)的匹配。您需要使用groupby.cumcountpivot执行重复数据消除:

tmp = (
 df.assign(sign=np.sign(df['CP']),
           n=df.groupby(['Centre', 'CP']).cumcount(),
           abs=df['CP'].abs()
          ).reset_index()
   .pivot(index=['Centre', 'abs', 'n'], columns='sign', values='index')
)

keep = tmp.where(tmp.notna().all(axis=1)).stack().values

df.loc[keep, 'Cancel'] = 'Canceled'

输出:

Centre   CP    Cancel
0   3N7D   10  Canceled
1   3N1F    2       NaN
2   3N90   -9       NaN
3   3N7D   -1       NaN
4   3N7D  -10  Canceled
5   8D92  198       NaN
6   3N7D  -10       NaN
7   3N90    2       NaN
8   8D92 -195       NaN
9   8D92   -3       NaN

中间体tmp

sign           -1    1
Centre abs n          
3N1F   2   0  NaN  1.0
3N7D   1   0  3.0  NaN
       10  0  4.0  0.0  # indices 0 and 4 cancel each other
           1  6.0  NaN  # indice 6 is alone
3N90   2   0  NaN  7.0
       9   0  2.0  NaN
8D92   3   0  9.0  NaN
       195 0  8.0  NaN
       198 0  NaN  5.0

相关问题