我目前正在开发一个项目,我现在的任务是我需要根据Bands列中给出的Band指定设备是否为2G。例如,
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 |
因此,如果“Bands”列只包含单词“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 :(得分:0)
您将数据分隔为带有制表符或空格的列,但您的代码表明您使用竖线(|
)作为分隔符。我不确定哪个是对的,但那是你的问题。
根据我的理解,您的条件是查看第二列中的各个子字段,用逗号分隔,如果每个子字段中包含文本字符串“GSM”,则返回一个值(true)在子字段中,但如果至少有一个子字段不包含该字符串,则返回不同的值(false)。正确?
让我们假设您在reader
中拥有自己的csv阅读器,如您的示例所示。 for-row-in循环是正确的,因为你想为每一行单独进行这种计算。
for row in reader:
在该循环中,您需要访问 Bands 列:
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
替换为实际的拆分表达式等。
答案 1 :(得分: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))
```