如果这是一个重复的问题,我很抱歉,在我觉得我必须发布一个问题之前,我确实四处寻找了一下。
我试图根据另外2列的值在新列devicevalue
中分配一个值。我dataframe看上去有点像;
devicename make devicevalue
switch1 cisco 0
switch1-web100 netgear 0
switch10 cisco 0
switch23 cisco 1
switch31-web200 netgear 0
switch31 cisco 1
switch41-new cisco 1
switch40e cisco 1
switch31-web200-new netgear 0
switch40e cisco 1
switch11-data100e netgear 0
我正在尝试根据这些标准添加一个值;
- 如果
make == netgear
(设置为0) - 如果开关后的值大于等于20(设置为1,否则设置为0)
(如果两个条件都满足,设为0,即条件"make == netgear
设置为0">优先。请注意,这与现有代码不同,在现有代码中,如果两个条件都满足,则第二个条件将覆盖(并覆盖结果值)。
我本来有一些帮助把这些放在一起但是现在有些设备有-new
和p
或a
或e
这打破了在字符串末尾查看数字的代码
我使用的代码基本上是;
def get_number_suffix(devicename: str) -> int:
i = 1
while i < len(devicename) and devicename[-i:].isnumeric():
i += 1
return int(devicename[-(i-1):])
def compute_devicevalue(row) -> int:
if 'netgear' in row['make']:
return 0
if 20 <= get_number_suffix(row['devicename']):
return 1
else:
return 0
df['devicevalue'] = df.apply(compute_devicevalue, axis=1)
在新添加到一些命名的末尾之前工作得很好,现在它显然中断了。我已经尝试了各种方法,但我找不到一个体面的方式,忽略-new
和p
或a
或e
编辑
对不起,我完全把我想问的搞砸了,我试图根据'switch'
之后的值来做值。
基本上使用现有的代码当它将字符串转换为整数并执行len
时它会落在任何有-new
和p
或a
或e
的名称后面
例如表示
ValueError: int()以10为基数的无效文字:'switch23-new'
您可以使用.loc
和str.extract()
,如下所示:
df['devicevalue'] = 0 # init value to 0
# Set to 1 if the value after 'switch' >= 20.
# Otherwise part is set during init to 0 at the first statement
df.loc[df['devicename'].str.extract(r'switch(d+)', expand=False).astype(float) >= 20, 'devicevalue'] = 1
# Set to 0 if `make` == 'netgear'
df.loc[df['make'] == 'netgear', 'devicevalue'] = 0
# If you have 2 or more values of `make` to match, use, e.g.:
#df.loc[df['make'].isin(['netgear', 'dell']), 'devicevalue'] = 0
Regexr'switch(d+)'
与str.extract()
一起工作,提取'switch'
之后的数字,无论它们是在末尾还是在中间。因此,它解决了之前的数字在末尾现在在中间的问题。
结果:
devicename make devicevalue
0 switch1 cisco 0
1 switch1-web100 netgear 0
2 switch10 cisco 0
3 switch23 cisco 1
4 switch31-web200 netgear 0
5 switch31 cisco 1
6 switch41-new cisco 1
7 switch40e cisco 1
8 switch31-web200-new netgear 0
9 switch40e cisco 1
10 switch11-data100e netgear 0
我尝试用regex从字符串中提取数字,例如这里。
为了简单起见,我将您的数据框架转换为列表
a = [{"devicename" : "switch1","make": "cisco", "devicevalue" :0}, {"devicename" : "switch1-web100", "make" : "netgear", "devicevalue" :0}, {"devicename" : "switch10" , "make" : "cisco", "devicevalue" :0}.... ]
然后我使用这个函数:
import re
def clean_data(data):
for i in range(len(data)): #remove this if using dataframe row
row = data[i] #Dict
if row["make"] == "netgear":
row["devicevalue"] = 0
tmp = -1
if "web" in row["devicename"]:
tmp = [int(s) for s in re.findall(r'd+', row["devicename"].split("web")[1])][0]
elif "data" in row["devicename"]:
tmp = [int(s) for s in re.findall(r'd+', row["devicename"].split("data")[1])][0]
if tmp >= 200:
row["devicevalue"] = 0
elif tmp == -1:
pass #Nothing to change
data[i] = row
return data #remove this and return row
得到如下
[{'devicename': 'switch1', 'make': 'cisco', 'devicevalue': 0}, {'devicename': 'switch1-web100', 'make': 'netgear', 'devicevalue': 0}, {'devicename': 'switch10', 'make': 'cisco', 'devicevalue': 0}, {'devicename': 'switch23', 'make': 'cisco', 'devicevalue': 1}, {'devicename': 'switch31-web200', 'make': 'netgear', 'devicevalue': 0}, {'devicename': 'switch31', 'make': 'cisco', 'devicevalue': 1}, {'devicename': 'switch40', 'make': 'cisco', 'devicevalue': 1}, {'devicename': 'switch23', 'make': 'cisco', 'devicevalue': 1}, {'devicename': 'switch31-web200-new', 'make': 'netgear', 'devicevalue': 0}, {'devicename': 'switch31-web100a', 'make': 'cisco', 'devicevalue': 1}, {'devicename': 'switch40', 'make': 'cisco', 'devicevalue': 1}, {'devicename': 'switch11-data100e', 'make': 'cisco', 'devicevalue': 1}]
由于您正在发送数据帧的行,请删除外部循环并在代码中返回行而不是数据