【问题标题】:Excluding values in pandas data frame if already occurred in a specific pattern如果已经以特定模式出现,则排除 pandas 数据框中的值
【发布时间】:2019-10-15 10:57:43
【问题描述】:

我在 pycharm 中使用带有 pandas 的 python 3.4

我已将我的数据排列在一个看起来或多或少像这样的 pandas 数据框中:

import pandas as pd
data = {'step': [1, 2, 2, 3, 4, 4, 4, 5, 5, 4, 5, 6, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8],
        'trials': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]}
temp_df = pd.DataFrame(data=data) 

问题在于 row[15] 处的“step”和 row[16] 处的 step 分别为 8 和 1,这种差异对于我正在运行的分析类型是不能容忍的。所以我想排除/删除/删除第 15 行和值“步骤”返回到行 [15] 的行之间的所有行,在这种情况下为 8,可以在行 [23 ]。 [收到第一个答案后编辑] 请记住,规则是任何后续值只能是 +/- 1。因此,例如,第 [9] 行的“步”是 4,它小于“步”在row[8] 是 5。这样的差异是允许的,任何大于 +- 1 的差异都是不允许的。

这只是一个例子,真实数据有几十万行,所以我希望在我的数据框中不止一次出现这个问题。

我一直在寻找使用 for 循环等来遍历行的方法,但有人警告我这些方法非常慢。在任何情况下,我都想不出一个有效的 for 循环。

我也未能找到一种无需循环且仅使用 pandas 和某种逻辑索引的智能编程方式。我什至不确定这是否可能不进行迭代。现在我可以成功找到所有行 [i] 和行 [i+1] 的差异大于模数1 的行并在逻辑上对其进行索引,但我被困在这一点上。

最终我会创建一个数据框,其中排除了 16 到 22 的行。

【问题讨论】:

    标签: python pandas dataframe iteration


    【解决方案1】:

    如果有人会发布更短的解决方案'我会删除它,但我发现创建一个df,他会为每个步骤找到第一个trials,如果已经有更高的@987654323 @在以前的trials 然后删除它:

    first_apps = temp_df.sort_values(['step', 'trials']).drop_duplicates('step')
    first_apps['next_step'] = first_apps['trials'].shift(-1)
    temp_df = temp_df.merge(first_apps.drop('trials', axis=1), how='left')
    temp_df = temp_df[~(temp_df['trials'] > temp_df['next_step'])].drop('next_step', axis=1)
    

    【讨论】:

    • 非常感谢您的解决方案,不幸的是我没有很好地解释我的问题。看,应该允许试验 n 和试验 +1 之间的 +/- 1 差异。大于 +/-1 的差异是不允许的。我会在原始问题中更清楚地说明这一点。
    • @antcolony 所以第 22 行是可以的,不应该被排除在外(它的step 是 7,第 15 行的 step 是 8)?
    • 好吧,在这种特殊情况下,第 22 行不行。但如果这个特定规则使编码变得更难,我可以放弃它
    【解决方案2】:

    经过更多研究,我自己的解决方案是循环和数据框操作的组合。

    我首先创建了两个额外的列:一个在每行之间的“步长”中移动,下一行列步长移动了一行temp_df['shift'] = temp_df.shift(-1);还有一个叫做 jump ,如果新列中的任何值大于 1 temp_df['jump'] = temp_df['diff'] > 1

    ,则将其设置为 True 的简单逻辑索引

    然后我基本上创建所有“跳转”的索引并运行一个 for 循环,其中: 1)我提取系列中第一个跳转的索引和值('curr_idx'和'curr_value') 2)我将原始数据帧的一个子集从索引到末尾复制到一个新数据帧('temp_df2' 3)我在新的数据帧('last_value')中寻找第一次跳转的值的第一次出现的索引 4)我将原始数据框中的行从第一个索引删除到最后一个索引('curr_idx:last_value')

    我还在“尝试:”下执行所有操作,因为此解决方案引发了我无法解决的错误。很抱歉。

    代码如下:

    import pandas as pd
    import matplotlib.pyplot as plt
    
    data = {'step': [1, 2, 2, 3, 4, 4, 4, 5, 5, 4, 5, 6, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8]}
    temp_df = pd.DataFrame(data=data)
    
    temp_df['diff'] = temp_df['step'] - temp_df['step'].shift(-1)
    temp_df['jump'] = temp_df['diff'] > 1
    temp_df = temp_df.reset_index(drop=True)
    
    old_df = temp_df
    
    all_values = temp_df[temp_df['jump']]['step']
    
    try:
        for i in range(0,len(all_values)):
    
            # find all positions at which jump is true
            all_values = temp_df[temp_df['jump']]['step']
            curr_idx = temp_df[temp_df['jump']].index.values.astype(int)[0]
            curr_value = all_values.iloc[0]
    
            temp_df2 = temp_df.drop(temp_df.index[0:curr_idx+1])
            last_value = temp_df2[temp_df2['step'] == curr_value].index.values.astype(int)[0]
    
            temp_df = temp_df.drop(temp_df.index[curr_idx:last_value])
            temp_df = temp_df.reset_index(drop=True)
    except:
        pass
    
    plt.subplot(121)
    ax1 = plt.plot(old_df['step'])
    
    plt.subplot(122)
    ax2 = plt.plot(temp_df['step'])
    

    这里是输出:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-23
      • 2021-11-11
      • 1970-01-01
      • 1970-01-01
      • 2023-01-19
      • 2020-05-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多