2017-04-19 40 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)) 

```

相關問題