2017-04-19 29 views
2

我目前工作的一个项目,我在这里的任务声明,现在是我需要指定设备是否是2G还是不是基于波段在Bands栏中给出。例如,过滤特定的词来获得一个特定的关键字作出,如果在python

Device ID |Bands|2G(New added column) 
123 |GSM 1800, GSM 700 |            
124 | GSM 1800, GSM 700, GSM 1, LTE TDD |        
125 | TD-SCDMA,1 SIM |            
126 |GSM850 (GSM800),WCDMA FDD Band I,WCDMA FDD Band VIII,2 SIM | 

所以,如果列“带”仅包含单词“GSM”,那么它是2G的,否则,N.

我使用re模块都试过,但我停留在一些点。

import re 
import csv 
... 
two_G_only = [] 
... 
with open('filepath.txt', "rU") as f: 
    reader = csv.DictReader(f, delimiter = "|") 
    for row in reader: 
     ... 
     ... 
     if 'GSM' in row['Bands']: 
     gsm_only = " ".join(re.findall("[a-zA-Z]+", row['Bands'])) 
     #Im stuck at here because I don't know how to test whether there is only GSM or else   
    else: 
     two_G_only.append('N') 
     ... 
     ... 

我需要什么样的结果

Device ID | Bands | 2G 
123 | GSM 1800, GSM 700 | Y 
124 |GSM 1800, GSM 700, GSM 1, LTE TDD | N 
125 |TD-SCDMA,1 SIM | N 
126 |GSM850 (GSM800),WCDMA FDD Band I,WCDMA FDD Band VIII,2 SIM|N 

谢谢你在前进,做评论,如果我的问题是不理解。我已经在网站上搜索了一些解决方案,但我确信所问的问题不是同一个问题/概念。

回答

0

你给分离成制表符或空格列中的数据,但你的代码表明您正在使用一个竖线(|)作为分隔符。我不确定哪个是对的,但那是你的问题。

根据我的理解,您的条件是查看第二列中用逗号分隔的各个子字段,如果每个子字段都包含文本字符串“GSM”,则返回一个值(true)如果至少有一个子字段不包含该字符串,则返回不同的值(假)。对?

那么让我们假设你的csv阅读器在reader,如你的例子所示。 for-row-in循环是正确的,因为你想为每一行分别进行这种计算。

for row in reader: 

在这一循环中,你需要访问柱:

bands = row['Bands'] 

为了检验该子区,让我们使用基本str.split功能,用逗号分割子字段:

subfields = bands.split(',') 

现在,让我们将字符串列表转换为布尔值列表,并使用Python的内置any函数来评估整个列表。我们将与列表理解做到这一点:

if any([ ('GSM' not in band) for band in subfields ]): 
     _2g_or_not_2g = 'N' 

    else: 
     _2g_or_not_2g = 'Y' 

这个if语句会做大致也是这样说的:如果带中的任何一个不包含“GSM”,它将匹配。

有,你可以写代码的一些其他方式。例如,你可以使用Python的all功能使阴性检测到阳性结果。这将扭转if语句的“意义”,并切换武器:

if all([ 'GSM' in band for band in subfields ]): 
     _2g_or_not_2g = 'Y' 
    else: 
     _2g_or_not_2g = 'N' 

此外,您还可以使用... if condition修改器列表解析来过滤列表下降到一个较小的列表。

最后,当然,你可以开始合并表述为彼此 - 取代subfields实际分割表达等

+0

其实这是我的错,因为我想让它更容易阅读,所以我改变从管道分隔到选项卡或空间中的原始数据分隔。问题编辑。 – yunaranyancat

0

有一两件事要注意,在每一行,乐队分别用逗号隔开。
你可以利用这一点。
split()函数可以为您提供该行的字符串列表,每个字符串都包含单个乐队的名称。

现在问题就简单多了:如果任何一个乐队都缺少子字符串'GSM',那么该行将被取消资格:返回'N'。
如果该行中没有条带被取消资格(即所有名称中都包含'GSM'),则返回该行的'Y'。

您可以使用find()函数来查看一个字符串是否包含给定的子字符串。
例如'LTE TDD'.find('GSM')返回值-1,因为它没有。

请注意,您甚至不需要删除设备ID - 它可以是包含第一个乐队的项目的一部分。保持简单:所有你想知道的是,如果在任何给定的行上,所有文本块(用逗号隔开)都包含子字符串'GSM'..或者不是。

def is_GSM(bands): 
    for band in bands: 
     if (band.find('GSM') = -1: 
      return('N') 
    return('Y') 

for row in reader: 
    bands = row.split(',')    
    two_G_only.append(is_GSM(bands)) 

```

def is_GSM(bands): 
    for band in bands: 
     if (band.find('GSM') = -1: 
      # "GSM" wasn't in the band name 
      return('N') 

    # we looked at all the bands, and did not find a disqualifier.. 
    # This row must be "GSM' only 2G bands. 
    return('Y') 

for row in reader: 
    # not needed: first strip off the device_id in this row's string. 
    # row = row[3:] 

    bands = row.split(',') 
    # ie: bands = ['124 GSM 1800', ' GSM 700', ' GSM 1', ' LTE TDD'] 

    # send this list to is_GSM(), and append the result     
    two_G_only.append(all_are_GSM(bands)) 

```

相关问题