Numpy数组使用if语句删除重复项

2024-09-22 20:31:33 发布

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

我有一个(112,7)形状的NumPy字符串数组。前几个元素只是字母,其余的是数字,如下所示

List[0] = array(['ID32', 'TRED', 'PLUS', '434','0.34', '11.9', '4.8'], dtype='<U14')
List[1] = array(['ID32', 'TRED', 'PLUS', '994','0.84', '44.3', '1.11'], dtype='<U14')
List[2] = array(['ID32', 'PROP', 'MINUS', '234','0.56', '44.3', '1.11'], dtype='<U14')

我想要实现的是IF语句检查前三个元素,如果它们相同,则计算第四个和第五个元素的比率,并从列表中删除较小的元素

例如List[0]List[1]具有相同的前三个元素,因此检查比率(434/0.34 = 1276.5994/0.84 = 1183),因此List[1]较小,应该从列表中删除

这是我失败的尝试

for i, val in enumerate(List):
    if val[i][0] == val[i][1]
        print(val[3].astype(np.float)/val[4].astype(np.float))

谢谢你的帮助


Tags: 元素列表npplusvalfloatarraylist
2条回答

首先制作一个掩码来跟踪要保留的行,并转换数字列:

keep = np.ones(len(arr), bool) # [True, True, True]
numer = arr[:,3].astype(float)
denom = arr[:,4].astype(float)

然后循环编辑要保留的行的掩码:

for ii in range(1, len(arr)): 
    if np.all(arr[ii-1,:3] == arr[ii,:3]): 
        if numer[ii-1] / denom[ii-1] < numer[ii] / denom[ii]: 
            keep[ii-i] = False 
        else: 
            keep[ii] = False 

现在您有了keep作为array([ True, False, True]),您可以很容易地使用它来获得最终结果:

arr[keep]

给你:

array([['ID32', 'TRED', 'PLUS', '434', '0.34', '11.9', '4.8'],
       ['ID32', 'PROP', 'MINUS', '234', '0.56', '44.3', '1.11']],
      dtype='<U14')

如果匹配字符串的数量与行总数相比较小,则这可能会更快:

matches = 1 + np.where((xxx[1:] == xxx[:-1]).all(1))[0] # [1]
for ii in matches: # now we already know the strings match
    if numer[ii-1] / denom[ii-1] < numer[ii] / denom[ii]: 
        keep[ii-i] = False 
    else: 
        keep[ii] = False 

这样代码仍然是可读的,但是循环只是迭代匹配的数量,而不是行的数量

如果您愿意使用pandas

import pandas as pd


# setup
l = [['ID32', 'TRED', 'PLUS', '434', '0.34', '11.9', '4.8'],
     ['ID32', 'TRED', 'PLUS', '994', '0.84', '44.3', '1.11'],
     ['ID32', 'PROP', 'MINUS', '234', '0.56', '44.3', '1.11']]

df = pd.DataFrame(l)

print (df.assign(ratio=df[3].astype(float)/df[4].astype(float))
         .sort_values([0,1,2,"ratio"], ascending=False)
         .drop_duplicates([0,1,2], keep="first")
         .sort_index()
         .drop("ratio", 1)
         .to_numpy())

结果:

[['ID32' 'TRED' 'PLUS' '434' '0.34' '11.9' '4.8']
 ['ID32' 'PROP' 'MINUS' '234' '0.56' '44.3' '1.11']]

相关问题 更多 >