使用Python Dataframe将行与下一行进行比较并从结果中创建一个新列?
Posted
技术标签:
【中文标题】使用Python Dataframe将行与下一行进行比较并从结果中创建一个新列?【英文标题】:Compare row with next row and create a new column from results, using Python Dataframe? 【发布时间】:2020-10-27 21:26:23 【问题描述】:我想比较两列中的两个连续行,如果它们的值相同,则根据第三列值之间的差异创建一个新列。请参阅下面的输入和预期输出:
输入:
df = pd.Dataframe('Account Number': [123,123,123,456,456,456], 'Value':['ABC', 'ABC', 'ABC', 'DEF', 'DEF', 'DEF'],'Positions':[10,10,20,20,20,15])
预期输出:
df = pd.Dataframe('Account Number': [123,123,123,456,456,456],'Value':['ABC', 'ABC', 'ABC', 'DEF', 'DEF', 'DEF'],'Positions':[10,10,20,20,20,15], 'new_col': [0,0,10,0,0,-5])
在excel中,公式很简单:
IF(AND(B2=B1,C2=C1), D2-D1, 0)
其中:B = 帐号,C = 价值,D = new_col
到目前为止,我已经尝试了两次尝试 - (1) 使用 iloc(这会产生 IndexError: Single positional indexer is out of bounds")和 (2) 使用 rolling(n) - 但我不能甚至编译。请参阅下面我在 (1) 处的尝试,任何帮助都会很棒。谢谢!
a = 0
if a != len(df):
for a in range(len(df)):
df['new_col'] = np.where((df["Account Number"].iloc[a+1] == df["Account Number"].iloc[a]) and (df["Value"].iloc[a+1] == df["Value"].iloc[a]), df["Positions"].iloc[a+1] df["Positions"].iloc[a], 0)
a+= 1
【问题讨论】:
【参考方案1】:您应该使用一种称为.diff()
的简单且性能更高的pandas 方法而不是循环:
df['new_col'] = df.groupby('Account Number')['Positions'].diff().fillna(0).astype(int)
完整代码:
df = pd.DataFrame('Account Number': [123,123,123,456,456,456], 'Value':['ABC', 'ABC', 'ABC', 'DEF', 'DEF', 'DEF'],'Positions':[10,10,20,20,20,15])
df['new_col'] = df.groupby('Account Number')['Positions'].diff().fillna(0).astype(int)
df
Out[1]:
Account Number Value Positions new_col
0 123 ABC 10 0
1 123 ABC 10 0
2 123 ABC 20 10
3 456 DEF 20 0
4 456 DEF 20 0
5 456 DEF 15 -5
【讨论】:
谢谢大卫 - 但是,这个解决方案不是我想要的,因为它不会检查 (1) 'Account Number' 的当前行和下一行是否相同并且 (2 ) 'Value' 的当前行和下一行是相同的。但是,您提出了一个很好的观点,即使用 diff 方法来进行逐行比较,而不是循环。你知道该怎么做吗? @samoa_like_Moana 简单!只是 groupby 帐号。查看更新的答案! 是的!实际上 groupby 需要同时具有“帐号”和“价值”,然后它就是解决方案。谢谢大卫!!【参考方案2】:对于范围内的(len(df)-1):
注意 -1。 没有它 - 是的,你会遇到索引错误
【讨论】:
【参考方案3】:应该避免循环遍历 pandas 结构,但我不知道如何在没有循环或修改数据结构的情况下为您提供帮助
new_col=[0]
for a in range(len(df)-1):
if (df["Account Number"].iloc[a+1] == df["Account Number"].iloc[a]) and (df["Value"].iloc[a+1] == df["Value"].iloc[a]):
new_col.append(df["Positions"].iloc[a+1] - df["Positions"].iloc[a])
else:
new_col.append(0)
df["new_col"]=new_col
print(df)
给出以下输出
Account Number Value Positions new_col
0 123 ABC 10 0
1 123 ABC 10 0
2 123 ABC 20 10
3 456 DEF 20 0
4 456 DEF 20 0
5 456 DEF 15 -5
【讨论】:
我看到已经发布了一个利用 pandas 功能的答案。如果您不需要您提到的条件检查,您应该选择 David Erickson diff() 解决方案。如果你不这样做,找到一种避免循环的方法仍然是件好事。 谢谢 TriGiamp - 这个解决方案效果很好。不幸的是,我确实需要条件检查。以上是关于使用Python Dataframe将行与下一行进行比较并从结果中创建一个新列?的主要内容,如果未能解决你的问题,请参考以下文章
用于将当前行与下一行进行比较并根据条件打印其中一行的 awk 解决方案