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