python根据列的最大值选择行

2024-04-24 06:01:22 发布

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

我对Python不是很熟悉,但是我需要做一些事情。我有一个ASCII文件(空格分隔)的几列。在第一列中,有些值是重复的。例如,从这些重复值中,我需要选择第3列中具有较大值的行,然后返回一个数组。 我想要这样的东西:

#col1    col2    col3    col4    col5
1         1       2       3       4
1         2       1       5       3
2         2       5       2       1

将返回第1行和第3行。 到目前为止,我已经做到了:我定义了一个辅助函数来检测重复项的索引(所有第二个条目)

def list_duplicates(seq):
    seen = set()
    seen_add = seen.add
    return [idx for idx,item in enumerate(seq) if item in seen or seen_add(item)]

然后尝试用它来读取列表(我从一个文件中加载的)np.genfromtxt文件命名(每列)

def select_high(ndarray, dup_col, sel_col): #dup_col is the column where the duplicates are, sel_col is the column where we select the larger value
    result = []
    dup = list_duplicates(ndarray[dup_col])
    dupdup = [x-1 for x in dup]
    for i in range(len(ndarray[sel_col])):        
        if i in dup:
            mid = []
            maxi = max(ndarray[sel_col][i], ndarray[sel_col][i-1])
            maxi_index = np.where(ndarray[sel_col] == maxi)[0][0]
            for name in ndarray.dtype.names:
                mid.append(ndarray[name][maxi_index])
            result.append(mid)
        else:
            mid = []
            if i not in dupdup:
                for name in ndarray.dtype.names:
                    mid.append(ndarray[name][i])
            result.append(mid)

    return np.asarray(result)

但是发生的事情是,每当有重复的时候,我就必须删除else部分,否则它会给我一个错误,每当没有重复的时候,我就必须把它放回去。 感谢您的帮助,很抱歉发了这么长的帖子,希望我能说清楚


Tags: 文件thenameinforcolresultduplicates
1条回答
网友
1楼 · 发布于 2024-04-24 06:01:22

我想你(我也是)都沉浸在细节中了。以下是一个版本,它可以满足您的需要,但更简单:

m = [[1, 2, 1, 5, 3], [1, 1, 2, 3, 4], [2, 2, 5, 2, 1]]
s = sorted(m,  key=lambda r:(r[0], -r[2]))
print(s) 
seen = set()
print( [r for r in s if r[0] not in seen and not seen.add(r[0])])

第一行将m定义为从文件中获得的行列表。你知道吗

第二行按第一列中的值(r[0])对这些行排序,然后按第三列中的值排序,但从大到小(-r[2]):

s=[[1, 1, 2, 3, 4], [1, 2, 1, 5, 3], [2, 2, 5, 2, 1]]

现在,当您至少看到第一列中的值一次时,需要跳过这些行。我们使用一个集合seen来存储我们已经看到的r[0]值。如果r[0]不在seen中,我们应该保留该行并将其放入seen,这样我们下次看到r[0]时就会丢弃该行。这有点棘手:

if r[0] not in seen and not seen.add(r[0])

请注意,not seen.add(r[0])始终为真,因为seen.add返回None。因此:

  • 如果r[0]不在seen中,我们将r[0]放在seen中并保留该行

  • 如果r[0]seen中,则返回false并丢弃该行。

你也可以这样表达:

if not (r[0] in seen or seen.add(r[0]))

相关问题 更多 >