gpt4 book ai didi

python - 如何匹配数据框中相反的值?

转载 作者:行者123 更新时间:2023-12-01 07:30:25 25 4
gpt4 key购买 nike

我基本上想从导入的数据框中消除相反的数量。

我的解决方案是构建一个新的数据框,忽略成对组合总和为零的行。

考虑以下数据框:

df = pd.DataFrame([
['31/07/17', 43020500, 13552.65],
['31/07/17', 43020500, 13552.65],
['31/07/17', 43020500, 13552.65],
['31/07/17', 43020500, 13552.65],
['31/08/17', 43020500, 241024.48],
['31/08/17', 43020500, 241024.48],
['31/08/17', 43020500, 241024.48],
['31/08/17', 43020500, 241024.48],
['31/08/17', 43020500, 241024.48],
['31/08/17', 43020500, -13552.65],
['31/08/17', 43020500, -13552.65],
['31/08/17', 43020500, -13552.65],
['31/08/17', 43020500, -13552.65],
['31/08/17', 43020500, -13552.65],
['30/06/17', 43020500, 133540.13],
], columns = ['Data', 'Account','Amount']
)

df
Out[34]:
Data Account Amount
0 31/07/17 43020500 13552.65
1 31/07/17 43020500 13552.65
2 31/07/17 43020500 13552.65
3 31/07/17 43020500 13552.65
4 31/08/17 43020500 241024.48
5 31/08/17 43020500 241024.48
6 31/08/17 43020500 241024.48
7 31/08/17 43020500 241024.48
8 31/08/17 43020500 241024.48
9 31/08/17 43020500 -13552.65
10 31/08/17 43020500 -13552.65
11 31/08/17 43020500 -13552.65
12 31/08/17 43020500 -13552.65
13 31/08/17 43020500 -13552.65
14 30/06/17 43020500 133540.13

data frame example

预期结果是由索引 4 到 8、13 和 14 组成的新数据框,但我的代码无法正常工作...

import numpy as np
import pandas as pd

pd.options.display.float_format = '{:,.2f}'.format

df = pd.read_excel('ContractAssets_copy.XLSX')
df.sort_values('Date')

dfToList = df['Amount'].tolist()

newdf = []

def index(a_list, value):
try:
return a_list.index(value)
except ValueError:
return None

for number in dfToList:
key = index(dfToList, dfToList[number] * -1)
if key == None:
newdf.append(df[number])

newdf

如何解决这个问题?

最佳答案

请注意,例如您有 4 个值 13552.65,但是相反值 (-13552.65) 为 5

因此,如果每个值仅消除一个相反的值,则在本例中为一个应保留负值(其他解决方案不尊重这一点原理)。

首先定义一个函数来消除“不需要的”行(从当前行组):

def eliminate(grp):
grpSorted = grp.sort_values('Amount')
amt = grpSorted.Amount
nNeg = np.count_nonzero(amt.lt(0))
nPos = amt.size - nNeg
if nNeg == 0 or nPos == 0: # No opposite values
return grp
vDiff = nNeg - nPos
return grpSorted.head(vDiff) if vDiff > 0 else grpSorted.tail(-vDiff)

然后添加AmountAbs列:

df['AmountAbs'] = df.Amount.abs()

因为我们应该仅根据金额的绝对值对行进行分组。

最后你可以进行所需的分组并将上述函数应用到每组:

df.groupby('AmountAbs').apply(eliminate)\
.reset_index(level=0, drop=True)\
.drop(columns=['AmountAbs'])

上述说明中的“完成 Action ”包括:

  • 从索引中删除AmountAbs(仅保留原始索引),
  • 删除AmountAbs列。

如果您愿意,您可以在上述指令中添加.sort_index(),以恢复原始行顺序。

编辑

还有更短的解决方案,无需创建任何辅助列(并在最后删除它)。

消除函数略有不同:

def elim(grp):
grpSorted = grp.sort_values('Amount')
amt = grpSorted.Amount
nNeg = np.count_nonzero(amt.lt(0)) # No of negative values
nPos = amt.size - nNeg # No of positive values
vDiff = nNeg - nPos
return grpSorted.head(vDiff) if vDiff > 0 else grpSorted.tail(-vDiff)

要应用它,请运行:

df.groupby(lambda x: abs(df.loc[x, 'Amount']))\
.apply(elim).reset_index(level=0, drop=True)

关于python - 如何匹配数据框中相反的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57228303/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com