将一个系列中的数字添加到同一数据框中的一系列字母,可能使用正则表达式
Adding numbers from one series to a series of letters within the same dataframes, possibly using regex
我有一个更大数据框的子集:
import pandas as pd
data = {'Name': ['car- at', 'car- ar', 'truck- br', 'car- at'],
'SysNum': [1, 2, 3, 4 ],
}
Name SysNum
0 car- at 1
1 car- ar 2
2 truck- br 3
3 car- at 4
我需要能够在 - 之后的名称中输入数字。每个名字都有破折号,所以我尝试使用几行 Regex 行,但到目前为止我无法得到它。数据框应如下所示:
Name SysNum Count
0 car- at 1 car-1 at
1 car- ar 2 car-2 ar
2 truck- br 3 truck-3 br
3 car- at 4 car-4 at
我以前用过类似的东西:
df['BaseName'] = [re.sub('(?<=-)\d{1,6}', '', s) for s in df['Name'].values]
df['SysNum'] = [int(re.search('(?<=-)\d{1,6}', s)[0]) for s in df['Name'].values]
df['NewName'] = df['BaseName'] + df['SysNum'].astype(str)
这会去掉 - 之后的数字,然后我将一组新数字添加回最后一行的末尾。我现在在末尾有一组字母,所以我需要能够在 - 之后输入一组新数字,并在末尾保留字母。
一个新的解决方案或一种使用正则表达式的方法来查看 - 并停止在下一组字母应该工作。谢谢
parts = df['Name'].str.split('-', n=1)
df['NewName'] = parts.str[0] + '-' + df['SysNum'].astype(str) + parts.str[1]
测试:
>>> df
Name SysNum NewName
0 car- at 1 car-1 at
1 car- ar 2 car-2 ar
2 truck- br 3 truck-3 br
3 car- at 4 car-4 at
一种方法:
df["Count"] = [f"{pre}-{num} {suf}" for num, [pre, suf] in zip(df["SysNum"], df["Name"].str.split("- "))]
print(df)
输出
Name SysNum Count
0 car- at 1 car-1 at
1 car- ar 2 car-2 ar
2 truck- br 3 truck-3 br
3 car- at 4 car-4 at
您可以使用
df['Count'] = df.apply(lambda x: x['Name'].replace('- ', f"-{x['SysNum']} "), axis=1)
# => df['Count']
# 0 car-1 at
# 1 car-2 ar
# 2 truck-3 br
# 3 car-4 at
# Name: Count, dtype: object
这只是将 -
+ space 替换为 -
+ SysNum 列值 + space.
如果您想确保在第一个带有 -
的单词后插入值,您可以使用正则表达式:
df['Count'] = df.apply(lambda x: re.sub(r'^\w+-', fr"\g<0>{x['SysNum']}", x["Name"]), axis=1)
# => df
# Name SysNum Count
# 0 car- at 1 car-1 at
# 1 car- ar 2 car-2 ar
# 2 truck- br 3 truck-3 br
# 3 car- at 4 car-4 at
这里,^\w+-
匹配字符串开头(^
),\w+
匹配一个或多个letters/digits/_
,然后-
匹配。替换为整个匹配值 (\g<0>
) + 来自 SysNum
列的值。
您可以使用 zip
和列表理解!
>>> df['NewCol'] = [name.replace("-", f"-{num}", 1) for name, num in zip(df.Name, df.SysNum)]
>>> df
Name SysNum NewCol
0 car- at 1 car-1 at
1 car- ar 2 car-2 ar
2 truck- br 3 truck-3 br
3 car- at 4 car-4 at
注意:replace
方法的第三个参数确保我们只替换第一次出现的 -
我有一个更大数据框的子集:
import pandas as pd
data = {'Name': ['car- at', 'car- ar', 'truck- br', 'car- at'],
'SysNum': [1, 2, 3, 4 ],
}
Name SysNum
0 car- at 1
1 car- ar 2
2 truck- br 3
3 car- at 4
我需要能够在 - 之后的名称中输入数字。每个名字都有破折号,所以我尝试使用几行 Regex 行,但到目前为止我无法得到它。数据框应如下所示:
Name SysNum Count
0 car- at 1 car-1 at
1 car- ar 2 car-2 ar
2 truck- br 3 truck-3 br
3 car- at 4 car-4 at
我以前用过类似的东西:
df['BaseName'] = [re.sub('(?<=-)\d{1,6}', '', s) for s in df['Name'].values]
df['SysNum'] = [int(re.search('(?<=-)\d{1,6}', s)[0]) for s in df['Name'].values]
df['NewName'] = df['BaseName'] + df['SysNum'].astype(str)
这会去掉 - 之后的数字,然后我将一组新数字添加回最后一行的末尾。我现在在末尾有一组字母,所以我需要能够在 - 之后输入一组新数字,并在末尾保留字母。 一个新的解决方案或一种使用正则表达式的方法来查看 - 并停止在下一组字母应该工作。谢谢
parts = df['Name'].str.split('-', n=1)
df['NewName'] = parts.str[0] + '-' + df['SysNum'].astype(str) + parts.str[1]
测试:
>>> df
Name SysNum NewName
0 car- at 1 car-1 at
1 car- ar 2 car-2 ar
2 truck- br 3 truck-3 br
3 car- at 4 car-4 at
一种方法:
df["Count"] = [f"{pre}-{num} {suf}" for num, [pre, suf] in zip(df["SysNum"], df["Name"].str.split("- "))]
print(df)
输出
Name SysNum Count
0 car- at 1 car-1 at
1 car- ar 2 car-2 ar
2 truck- br 3 truck-3 br
3 car- at 4 car-4 at
您可以使用
df['Count'] = df.apply(lambda x: x['Name'].replace('- ', f"-{x['SysNum']} "), axis=1)
# => df['Count']
# 0 car-1 at
# 1 car-2 ar
# 2 truck-3 br
# 3 car-4 at
# Name: Count, dtype: object
这只是将 -
+ space 替换为 -
+ SysNum 列值 + space.
如果您想确保在第一个带有 -
的单词后插入值,您可以使用正则表达式:
df['Count'] = df.apply(lambda x: re.sub(r'^\w+-', fr"\g<0>{x['SysNum']}", x["Name"]), axis=1)
# => df
# Name SysNum Count
# 0 car- at 1 car-1 at
# 1 car- ar 2 car-2 ar
# 2 truck- br 3 truck-3 br
# 3 car- at 4 car-4 at
这里,^\w+-
匹配字符串开头(^
),\w+
匹配一个或多个letters/digits/_
,然后-
匹配。替换为整个匹配值 (\g<0>
) + 来自 SysNum
列的值。
您可以使用 zip
和列表理解!
>>> df['NewCol'] = [name.replace("-", f"-{num}", 1) for name, num in zip(df.Name, df.SysNum)]
>>> df
Name SysNum NewCol
0 car- at 1 car-1 at
1 car- ar 2 car-2 ar
2 truck- br 3 truck-3 br
3 car- at 4 car-4 at
注意:replace
方法的第三个参数确保我们只替换第一次出现的 -