【问题标题】:How to get strings between two specific strings terms in Pandas如何在 Pandas 中的两个特定字符串术语之间获取字符串
【发布时间】:2021-06-26 01:03:05
【问题描述】:
晚上好。
我想帮助我了解如何在 pandas (python) 中的两个字符串之间获取信息。
假设我有一个每个汽车经销商的汽车价格数据库,其中每个单元格都有类似于此的文本(注意:汽车经销商列可以是每一行的索引):
"1 - 福特 (1) - 新:60000 雷亚尔 / 二手:30000 雷亚尔轿车 2 - 梅赛德斯 -
奔驰 (1) - 新:R$130000 / 二手:R$95000 银色轿车 3 - 奇瑞
(caoa) (1) - 新:R$80000 / 二手:R$60000 SUV 汽车 5 - 其他 (1) -
新:90000 雷亚尔 / 二手:75500 雷亚尔掀背车"
感谢您的帮助!
【问题讨论】:
标签:
python
regex
pandas
string
web-scraping
【解决方案1】:
三步流程
- 使用
re.split()将整个字符串拆分为行项目
- 使用pandas extract解析出行的组成部分
- 最终将数据框塑造成宽...
import re
import pandas as pd
import numpy as np
s = "1 - Ford (1) - new:R$60000 / used:R$30000 sedan car 2 - Mercedes - Benz (1) - new:R$130000 / used:R$95000 silver sedan car 3 - Chery (caoa) (1) - new:R$80000 / used:R$60000 SUV car 5 - Others (1) - new:R$90000 / used:R$75500 hatch car"
# there as a car after "<n> - ". split into lines
df = pd.DataFrame(re.split("[ ]?[0-9] - ", s)).replace("", np.nan).dropna()
# parse out each of the strings
df = df[0].str.extract("(?P<car>.*) \([0-9]\) - new:R\$(?P<new>[0-9]*) \/ used:R\$(?P<used>[0-9]*).*")
# finally format as wide format...
df = (df.melt().assign(car=lambda dfa: dfa.groupby("variable").cumcount(),
col=lambda dfa: dfa.variable + (dfa.car+1).astype(str))
.drop(columns=["variable","car"])
.set_index("col")
.T
)
|
car1 |
car2 |
car3 |
car4 |
new1 |
new2 |
new3 |
new4 |
used1 |
used2 |
used3 |
used4 |
| value |
Ford |
Mercedes - Benz |
Chery (caoa) |
Others |
60000 |
130000 |
80000 |
90000 |
30000 |
95000 |
60000 |
75500 |
【解决方案2】:
您可以使用extractall 获取multiIndex 数据框,该数据框总而言之将包含经销商、车号和从正则表达式命名组中提取的值。在extractall 之后,使用stack 重塑数据框和最内层索引,这将允许您设置格式为[(dealer, carN)...] 和随后groupby 相同的第一个索引级别的新索引以保持捕获命令。将每个经销商数据附加到列表中并创建数据框。
import pandas as pd
import re
df = pd.DataFrame(
["1 - Ford (1) - new:R$60000 / used:R$30000 sedan car 2 - Mercedes - Benz (1) - new:R$130000 / used:R$95000 silver sedan car 3 - Chery (caoa) (1) - new:R$80000 / used:R$60000 SUV car 5 - Others (1) - new:R$90000 / used:R$75500 hatch car",
"2 - Toyota (1) - new:R$10543 / used:R$9020 silver sedan car",
"3 - Honda (1) - new:R$123600 / used:R$34400 sedan car 2 - Fiat (1) - new:R$1955 / used:R$877 silver sedan car 3 - Cadillac (1) - new:R$174500 / used:R$12999 SUV car"])
regex = re.compile(
r"\d\s-\s(?P<car>.*?)(?:\s\(\d+\)?\s)-\s"
r"new:R\$(?P<new>[\d\.\,]+)\s/\s"
r"used:R\$(?P<used>[\d\.\,]+).*?car"
)
df_out = df[0].str.extractall(regex).stack()
df_out.index = [df_out.index.get_level_values(0), \
df_out.index.map(lambda x: f'{x[2]+str(x[1]+1)}')]
dealers = []
for n, g in df_out.groupby(level=0):
dealers.append(g.droplevel(0))
df1 = pd.DataFrame(dealers).rename_axis('Dealer')
print(df1)
df1的输出
car1 new1 used1 car2 new2 used2 car3 new3 used3 car4 new4 used4
Dealer
0 Ford 60000 30000 Mercedes - Benz 130000 95000 Chery (caoa) 80000 60000 Others 90000 75500
1 Toyota 10543 9020 NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 Honda 123600 34400 Fiat 1955 877 Cadillac 174500 12999 NaN NaN NaN