簡體   English   中英

僅選擇低於特定閾值的值

[英]Pick values only below a certain threshold

說我有很多值:(左列只是值計數:1、2、3等;右邊是實際值)

1 5.2
2 1.43
3 3.54
4 887
5 0.35

我想做的是將值從減小到增大(從上到下)重新排序,然后我想讓python遍歷這些值並繼續選擇這些值(以后用作輸出),直到遇到一個等於或高於某個閾值的值。 例如:

5 0.35
2 1.43
3 3.54
1 5.2
4 887

說,我的閾值是5.0,所以在這里我希望程序放棄1和4(高值),並給出5、2和3及其對應的值作為輸出。 我希望這是有道理的。 同樣,如果(出於某種原因)我的閾值僅允許2個值,我想讓它忽略所有內容並給出類似“未找到值”的信息,這也是一個棘手的技巧。

他們將要從中找到它們的文件(值和計數)大致如下所示:

  ID  some: value  another: value another: value another: value another: value another: value 1: 5.2

等等,每個上述值對應文件中的新行。 因此,我感興趣的東西分別位於第x行第14列和第15列。

實際的行如下所示:

Mod# 2 11494    Chi^2:  1.19608371367   Scale:  0.567691651772  Tin:    1499    Teff:   3400    Luminosity:     568.0   L   M-dot: 4.3497e-08   Tau: 2.44E-01   Dust composition: Fe    IRx1:   0.540471121182

我對IRx1及其后的值感興趣。

假設文件每行有一個數字:

threshold = 5
with open('path/to/file') as infile:
    numbers = [float(line.strip()) for line in infile]
numbers.sort(reverse=True)
bigger = list(itertools.takewhile(lambda n: n<threshold, numbers))

如果您的文件如下所示:

1 5.2
2 1.43
3 3.54
4 887
5 0.35

並且您希望將輸出set([2,3,5]) ,然后:

with open('path/to/file') as infile:
    numbers = dict([float(i) for i in line.strip()] for line in infile)
lines = sorted(numbers, key=numbers.__getitem__, reverse=True)
answer = list(itertools.takewhile(lambda n: numbers[n]<threshold, lines))

給定一個看起來像這樣的文件:

Mod# 2 11494    Chi^2:  1.19608371367   Scale:  0.567691651772  Tin:    1499    Teff:   3400    Luminosity:     568.0   L   M-dot: 4.3497e-08   Tau: 2.44E-01   Dust composition: Fe    IRx1:   0.540471121182

如果有一個制表符( \\t )分隔11494Chi^2 ,則以下腳本應該起作用:

def takeUntil(fpath, colname, threshold):
    lines = []
    with open(fpath) as infile:
        for line in infile:
            ldict = {}
            firsts = line.split('\t', 2)
            ldict[firsts[0] = float(firsts[1])
            splits = firsts[2].split('\t')
            ldict.update(dict(zip(firsts, itertools.islice(firsts, 1, len(firsts)))))
            lines.append(ldict)
    lines.sort(reverse=True, key=operator.itemgetter(colname))
    return [row['Mod#'] for row in itertools.takewhile(lambda row: row[colname]<threshold, lines)]

使用該功能,您應該能夠指定要檢查的列值是否在閾值以下。 盡管此算法確實具有較高的空間復雜度(使用的RAM超出絕對必要的數量),但是您應該能夠在讀取文件后編組/戳lines ,然后從那里繼續進行后續運行。 如果您有一個龐大的輸入文件需要花費一些時間來處理(我懷疑您可能已經擁有),則此功能特別有用

以下解決方案假定將數據作為元組列表讀入。

例如:

[(1,5.2),
(2,1.43),
(3,3.54),
(4,887),
(5,0.35)]

將是問題中示例數據的列表。

def cutoff(threshold, data):
    sortedData = sorted(data, key=lambda x: x[1])
    finalList = filter(lambda x: x[1] < threshold, sortedData)
    return finalList if len(finalList) > 2 else 'No values found'

函數的第一行按元組第二個位置的值對列表進行排序。

然后,函數的第二行將過濾結果列表,以便僅保留值低於閾值的元素。

如果它包含兩個以上元素,則第三行返回結果排序列表,否則返回“找不到值”,這應該可以完成您要嘗試的操作,但要減少文件輸入。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM