繁体   English   中英

在循环中删除数据框中的值

[英]Dropping value in a dataframe in a loop

我有一个带有排序值的数据框:

import numpy as np
import pandas as pd

sub_run = pd.DataFrame({'Runoff':[45,10,5,26,30,23,35], 'ind':[3, 10, 25,43,53,60,93]})

我想从Runoff (45) 中的最大值开始,删除所有“ind”差异小于 30 (10, 5) 的值,重新更新 DataFrame ,然后转到第二高值(35) :删除“ind”差异小于 30 的索引,然后是第三高值(30) 并删除 26 和 23... 我编写了以下代码:

pre_ind = []

for (idx1, row1) in sub_run.iterrows():
     var = row1.ind
     pre_ind.append(np.array(var))
     for (idx2,row2) in sub_run.iterrows():
         if (row2.ind != var) and (row2.ind not in pre_ind):
            test = abs(row2.ind - var)
            print("test" , test)
            if test <= 30:
                 sub_run = sub_run.drop(sub_run[sub_run.ind == row2.ind].index)
                 

我希望找到值 [45,35,30] 作为输出。 但是我只找到第一个。

非常感谢

尝试这个:

list_pre_max = []
while True:
    
    try:
        max_val = sub_run.Runoff.sort_values(ascending=False).iloc[len(list_pre_max)]
    except:
        break
    max_ind = sub_run.loc[sub_run['Runoff'] == max_val, 'ind'].item()
    list_pre_max.append(max_val)
    dropped_indices = sub_run.loc[(abs(sub_run['ind']-max_ind) <= 30) & (sub_run['ind'] != max_ind) & (~sub_run.Runoff.isin(list_pre_max))].index
    
    sub_run.drop(index=dropped_indices, inplace=True)

输出:

>>>sub_run
        Runoff  ind
0   45  3
4   30  53
6   35  93

你永远不应该修改你正在迭代的东西。 这不能保证在所有情况下都有效。 根据数据类型,迭代器返回一个副本而不是一个视图,写入它不会有任何效果。

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.iterrows.html

在您的情况下, sub_run的修改不会立即对迭代产生影响。 因此,在外循环中,在对45, 3进行迭代之后,迭代的下一行是35, 93 ,然后是30, 53 , 26, 43 , 23, 60 , 10, 10 , 5, 25 对于内部循环,您的修改有效,因为您通过外部循环的迭代重新进入一个新循环。

这是我的建议代码,灵感来自冒泡排序。

import pandas as pd

sub_run = pd.DataFrame({'Runoff': [45,10,5,26,30,23,35],
                        'ind': [3,10,25,43,53,60,93]})


sub_run = sub_run.sort_values(by=['Runoff'], ascending=False)
highestRow = 0

while highestRow < len(sub_run) - 1:
    cur_run = sub_run
    highestRunoffInd = cur_run.iloc[highestRow].ind
    for i in range(highestRow + 1, len(cur_run)):
        ind = cur_run.iloc[i].ind
        if abs(ind - highestRunoffInd) <= 30:
            sub_run = sub_run.drop(sub_run[sub_run.ind == ind].index)
    highestRow += 1
print(sub_run)

输出:

   Runoff  ind
0      45    3
6      35   93
4      30   53

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM