我正在处理一些包含冲销的财务数据。反转基本上是对表的一种更正,它通过在表中添加等量的相反符号来抵消表中的另一个值。我的工作是清除这些价值观。
以这个数据框为例:

df = pd.DataFrame({"a":["a","b","c","a","a"],
                  "b":[-2,5,2,2,7],
                 "xtra_col":["X","X","X","X","X"]})

    a   b   xtra_col
0   a   -2  X
1   b   5   X
2   c   2   X
3   a   2   X
4   a   7   X


在这种情况下,第3行与第0行相反,因此必须将其删除。同时,第2行不是第0行的反转,尽管值相反,因为它们在a列上不匹配。
结果必须如此。

    a   b   xtra_col
0   b   5   X
1   c   2   X
2   a   7   X


问题是,如何从表格中删除此类冲销?我已经看过drop_duplicates()的子集为a和b,但那行不通,因为它只会匹配相同的值,而不会匹配相反的值。
我感觉可以使用groupby达成某些目标,但是我不确定如何组织它。

补充说明,它在负数为奇数的情况下也应起作用。考虑以下情况,输出应如下所示:

df = pd.DataFrame({"a":["a","b","c","a","a"],
                  "b":[-2,5,2,2.0,-2],
                 "xtra_col":["X","X","X","X","X"]})


a   b   xtra_col
0   a   -2.0    X
1   b   5.0 X
2   c   2.0 X
3   a   2.0 X
4   a   -2.0    X


输出应为:

a   b   xtra_col
1   b   5.0 X
2   c   2.0 X
3   1   -2.0    X

最佳答案

如果可能只有一个数字列b,则创建已过滤的DataFrame,将b转换为多个-1,并将行匹配为DataFrame.merge,最后通过Series.isinboolean indexing筛选出索引值:

df1 = df[df['b'].lt(0)].copy()
df1['b'] *= -1

df2 = df1.reset_index().merge(df.reset_index(), on=['a','b']).filter(like='index_')
print (df2)
   index_x  index_y
0        0        3

df = df[~df.index.isin(df2.values.ravel())]
print (df)
   a  b xtra_col
1  b  5        X
2  c  2        X
4  a  7        X


如果可能,另a 2行,并且您需要避免将其删除(因为不与另一a -2配对),在过滤后的原始GroupBy.cumcount中为计数器列添加DataFrame

df = pd.DataFrame({"a":["a","b","c","a","a",'a'],
                  "b":[-2,5,2,2,7,2],
                 "xtra_col":["X","X","X","X","X",'X']})


df1 = df[df['b'].lt(0)].copy()
c = df1.select_dtypes(np.number).columns
df1[c] *= -1

df1['g'] = df1.groupby(['a','b']).cumcount()
df['g'] = df.groupby(['a','b']).cumcount()
df2 = df1.reset_index().merge(df.reset_index(), on=['a','b','g']).filter(like='index_')
print (df2)


df = df[~df.index.isin(df2.values.ravel())]
print (df)
   a  b xtra_col  g
1  b  5        X  0
2  c  2        X  0
4  a  7        X  0
5  a  2        X  1

关于python - 如何将 Pandas 中的行放在一列上并满足另一列上的方程式?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56664826/

10-11 03:07