【问题标题】:How to iterate over previous rows to compare values in a Pandas DataFrame如何遍历前几行以比较 Pandas DataFrame 中的值
【发布时间】:2020-02-17 04:31:32
【问题描述】:

我有一个来自 pandas 的 Dataframe,如下所示:

import pandas as pd
raw_data = [{'Date': '1-10-19', 'Price':7, 'Check': 0}, 
            {'Date': '2-10-19','Price':8.5, 'Check': 0}, 
            {'Date': '3-10-19','Price':9, 'Check': 1}, 
            {'Date': '4-10-19','Price':50, 'Check': 1}, 
            {'Date': '5-10-19','Price':80, 'Check': 1}, 
            {'Date': '6-10-19','Price':100, 'Check': 1}]
df = pd.DataFrame(raw_data)
df.set_index('Date')

这就是它的样子:

           Price  Check
Date        
1-10-19     7.0      0
2-10-19     8.5      0 
3-10-19     9.0      1
4-10-19     50.0     1 
5-10-19     80.0     1
6-10-19     100.0    1

现在我要做的是,对于“检查”为 1 的每一行,我想检查价格低于该行价格 10% 的行之前的行数。对于例如,对于价格为 100 的第 6 行,我想遍历前面的行并计算行数,直到价格小于 10(100 的 10%),在这种情况下,价格会在 3 行之前是9。然后想将结果保存在新列中。

最终结果如下所示:

           Price  Check  Rows_till_small
Date        
1-10-19     7.0      0    NaN
2-10-19     8.5      0    NaN
3-10-19     9.0      1    Nan
4-10-19     50.0     1    NaN
5-10-19     80.0     1    4
6-10-19     100.0    1    3

我想了很多关于如何使用某种滚动功能来做到这一点,但我认为这是不可能的。我还考虑过使用 iterrows 或 itertuples 遍历整个 DataFrame,但我无法想象一种方法可以在不极其低效的情况下做到这一点。

【问题讨论】:

  • 为什么最后一行的 rows_till_small 为 3:6-10-19 100.0 1 3?我不明白逻辑,它应该仍然是4,不是吗?有 4 行计算价格低于 10。
  • @powerPixie 计数是相对于每一行的。所以对于最后一行,我是这样计算的:80、50,然后是 9,所以是 3 行。对于价格为 80 的倒数第二行,计数是这样的:50、9、8.5,然后是 7,所以 4 行。

标签: python pandas dataframe iterator data-science


【解决方案1】:

看看这个

diff = df['Price'].apply(lambda x:x > (df['Price']*.1))
RTS=[]
for i in range(len(df)):
    check = (diff)[i]
    ind = check.idxmax()
    if ind != 0:
        val = (i-ind)+1        
    else:
        val = np.nan
    RTS.append(val)
df['Rows_till_small'] = RTS
print(df)

输出

       Date     Price   Check   Rows_till_small
0   1-10-19     7.0     0       NaN
1   2-10-19     8.5     0       NaN
2   3-10-19     9.0     1       NaN
3   4-10-19     50.0    1       NaN
4   5-10-19     80.0    1       4.0
5   6-10-19     100.0   1       3.0

【讨论】:

    【解决方案2】:

    您可以通过以下方式解决问题:

    import pandas as pd
    raw_data = [{'Date': '1-10-19', 'Price': 7, 'Check': 0},
                {'Date': '2-10-19', 'Price': 8.5, 'Check': 0},
                {'Date': '3-10-19', 'Price': 9, 'Check': 1},
                {'Date': '4-10-19', 'Price': 50, 'Check': 1},
                {'Date': '5-10-19', 'Price': 80, 'Check': 1},
                {'Date': '6-10-19', 'Price': 100, 'Check': 1}]
    df = pd.DataFrame(raw_data)
    
    new_column = [None] * len(df["Price"])  # create new column
    
    for i in range(len(df["Price"])):
        if df['Check'][i] == 1:
            percent_10 = df['Price'][i] * 0.1
            for j in range(i, -1, -1):
                print(j)
                if df['Price'][j] < percent_10:
                    new_column[i] = i - j
                    break
    
    
    df["New"] = new_column  # add new column
    
    print(df)
    

    希望答案对你有用,欢迎提问。

    【讨论】:

    • 这不会检查每一行,只检查从开始到索引值行小于 10 的价格。当价格低于特定行价格的 10% 时,我需要遍历所有行并计算每行之前的行数。
    • @SameerZahid 已解决。我编辑了我的答案,请检查。
    猜你喜欢
    • 2017-05-14
    • 1970-01-01
    • 2022-10-25
    • 2021-02-01
    • 1970-01-01
    • 2012-05-30
    相关资源
    最近更新 更多