Python 熊猫:借助字典将变量子字符串从A列插入B列
我有一个Python 熊猫:借助字典将变量子字符串从A列插入B列,python,regex,string,pandas,Python,Regex,String,Pandas,我有一个pandasdataframe: df = pd.DataFrame(["LONG AAPL 2X CBZ","SHORT GOOG 10X VON"], columns=["Name"]) 我想在名称列中标识“AAPL”,通过字典“AAPL”:“Apple”,然后将其插入新列说明中的字符串中 期望输出: Name Description "LONG AAPL 2X CBZ" "Tracks Apple with 2X leverage."
pandas
dataframe:
df = pd.DataFrame(["LONG AAPL 2X CBZ","SHORT GOOG 10X VON"], columns=["Name"])
我想在名称
列中标识“AAPL”
,通过字典“AAPL”:“Apple”
,然后将其插入新列说明
中的字符串中
期望输出:
Name Description
"LONG AAPL 2X CBZ" "Tracks Apple with 2X leverage."
"SHORT GOOG 10X VON" "Tracks Google with -10X leverage."
我遇到的问题是在另一个字符串中输入一个变量子字符串,如“使用Y杠杆跟踪X。”
如果我不必这样做,只需从name
提取到description
即可:
df["Description"] = df["Name"].str.extract(r"\s(\S+)\s").map({"AAPL":"Apple", "GOOG":"Google"})
或者提取杠杆:
df["Description"] = df["Name"].str.extract(r"(\d+X)")
如果可能的话,我想使用regex
来提取变量,因为实际上我会做一些更详细的regex,例如检索不同格式的乘法器,例如X2
,2x
等等
注意:我可能需要设置另一列来通知杠杆是正还是负,并使用该列来决定是否将“-”
作为-10X杠杆追加到乘数前面。
df["direction"] = df["name"].map(lambda x: "Long" if "LONG" in x else "Short" if "SHORT " in x else "Long")
Name Direction Description
"LONG AAPL 2X CBZ" "Long" "Tracks Apple with 2X leverage."
"SHORT GOOG 10X VON" "Short" "Tracks Google with -10X leverage."
您可以定义一个显式函数来应用于整个
Name
系列
df = pd.DataFrame(["LONG AAPL 2X CBZ","SHORT GOOG 10X VON"], columns=["Name"])
dmap = {"AAPL":"Apple", "GOOG":"Google"}
signmap = {"LONG": "", "SHORT": "-"}
def f(strseries):
company = strseries.str.extract(r"\s(\S+)\s").map(dmap)
leverage = strseries.str.extract(r"(\d+X)")
sign = strseries.str.extract(r"(\S+)\s").map(signmap)
return "Tracks " + company + " with " + sign + leverage + " leverage."
df['Description'] = f(df['Name'])
编辑:一次完成正则表达式提取大约可以提高2倍的速度,但要牺牲一些可读性
def f2(strseries):
sub_df = strseries.str.extract('(?P<sign>\S+)\s(?P<company>\S+)\s(?P<leverage>\d+X)')
return "Tracks " + sub_df.company.map(dmap) + " with " + sub_df.sign.map(signmap) + sub_df.leverage + " leverage."
df['Description'] = f2(df['Name'])
def f2(标准系列):
sub_df=strseries.str.extract(“(?P\S+)\S(?P\S+)\S(?P\d+X)”
返回带有“+sub_-df.sign.map(signmap)+sub_-df.leverage+”的“Tracks”+sub_-df.company.map(dmap)+”
df['Description']=f2(df['Name'])
因为我们只关心前两个子字符串和后两个子字符串:
df = pd.DataFrame(["LONG AAPL 2X CBZ", "SHORT GOOG 10X VON", "BULL AXP UN X3 VON","LONG AXP X3 VON"], columns=["Name"])
maps = {"AAPL": "Apple", "GOOG": "Google"}
signs = {"SHORT": "-"}
def split(i):
spl = i.split()
a, b, c = spl[0], spl[1], spl[-2]
val = maps.get(b, b) # if name is not to be replaced keep original
return "Tracks {} with {}{} leverage".format(val, signs.get(a, ""), c)
df["Description"] = df["Name"].map(split)
输出:
Name Description
0 LONG AAPL 2X CBZ Tracks Apple with 2X leverage
1 SHORT GOOG 10X VON Tracks Google with -10X leverage
2 BULL AXP UN X3 VON Tracks AXP with X3 leverage
3 LONG AXP X3 VON Tracks AXP with X3 leverage
仅拆分比使用正则表达式更有效:
In [33]: df2 = pd.concat([df]*10000)
In [34]: timeit df2["Name"].map(split)
10 loops, best of 3: 57.5 ms per loop
In [35]: timeit f2(df2['Name'])
10 loops, best of 3: 168 ms per loop
如果您想添加更多的单词来替换,只需将它们添加到地图中,并使用符号来替换。是否应该是
“LONG AAPL 2X CBZ”
?谢谢,更正了数据框。这不能正确处理问题中描述的杠杆符号。@abeboparebop,我错过了那一部分,但这对我来说是微不足道的implement@PadraicCunningham如果中间有更多的文本怎么办?对于BULL AXP UN X3 VON
我得到:ValueError:太多的值无法解包
。不幸的是,这会有很大的变化,这使得按空格拆分很困难。@Winterflags,我们可以使用带有findall的正则表达式,我将进行编辑,当您没有带有AAPL或GOOG的行时,您希望发生什么?然后我们可以再次拆分!这个名字总是一个单词吗?我想使用这个解决方案,因为正则表达式对于许多不同的情况来说更加健壮。但是,如果在dmap
中没有匹配项,我如何让它将\s(\s+)\s
写为公司
?类似于:val=maps.get(b,b);返回“使用{}{}杠杆跟踪{}”。格式(val,signs.get(a,“”),c)