基于输出到bool的列和行(替换'for'语句)

2024-10-02 18:18:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图根据多列中编码的信息以及索引的相对位置创建一个新列(bool)

我有一个数据帧,它有start列和end列,以及许多行。我希望保留不与其他行重叠的行,优先考虑最高的行/第一个观察值(DF已排序)

换句话说,如果一个范围(开始,结束)至少部分包含在一个索引号较低的范围(开始,结束)内,那么它将被分配False。如果没有发现重叠,将为其分配True

下面是一张图片,直观地解释了我要做的事情: viz_desc

我已经使用for循环实现了这一点,但是这很慢,即使使用大小适中的DFs也是如此。我正在寻找一种更为“pandas-y”的过滤方式,以便在<;=O(n)。这种for-loop方法会删除列(最终是我要做的),而不是创建一个新列,但我认为使用“for-loop-less”方法创建一个新的bool列要容易得多。以下是我用来完成此任务的代码:

import pandas as pd
df=pd.DataFrame(((5,12),(16,19),(7,14),(6,9),(17,18),(1,3)),columns=["start","end"])

dropIndexes=[]
for i in range(len(df) - 1, 0, -1):
    start=(df.iloc[i]['start'] >= df.iloc[list(range(0, i))][['start']]).start & (
           df.iloc[i]['start'] <= df.iloc[list(range(0, i))][['end']]).end    
    end  =(df.iloc[i]['end']   >= df.iloc[list(range(0, i))][['start']]).start & (
           df.iloc[i]['end']   <= df.iloc[list(range(0, i))][['end']]).end
    if True in (start|end).values: dropIndexes.append(i)
df=df.drop(dropIndexes)
df

此代码从DF中的“自下而上”开始,分别测试当前行的start值是否包含在具有较低索引的任何行的startend之间。然后对当前行的end值重复此操作。然后测试当前startend是否包含在索引范围较低的任何其他行中


Tags: 方法代码looptruepandasdfforrange
1条回答
网友
1楼 · 发布于 2024-10-02 18:18:46

假设startend列没有负值。 您可以将pandas.apply用于您的用例

import pandas as pd
df=pd.DataFrame(((5,12),(16,19),(7,14),(6,9),(17,18),(1,3)),columns=["start","end"])

start, end = -9999, -9999
def select_row(index_start, index_end):
    global start
    global end

    if start == -9999 and end == -9999:
        # case 1: initial case
        start = index_start
        end = index_end
        return True
    elif end < index_start:
        # case 2: towards the left
        end = index_end
        return True
    elif index_end < start:
        # case 3: towards the right
        start = index_start
        return True
    else:
        # case 4: overlapping
        return False

filt_index = df.apply(lambda row: select_row(row["start"], row["end"]), axis=1)
df = df.loc[filt_index, df.columns]
print(df)

另外,我不得不使用global变量,因为我得到了UnboundLocalError。另外,我不想将startend作为参数传递给数据帧中每一行的apply()

相关问题 更多 >