【问题标题】:Compare row with next row and create a new column from results, using Python Dataframe?使用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

【问题讨论】:

    标签: python pandas dataframe window-functions


    【解决方案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 - 这个解决方案效果很好。不幸的是,我确实需要条件检查。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-01
      • 1970-01-01
      相关资源
      最近更新 更多