如何在 Pandas 中的两个特定字符串术语之间获取字符串

时间:2021-03-30 01:41:08

标签: python regex pandas string web-scraping

晚上好。

我想了解如何在 Pandas (python) 中获取两个字符串之间的信息。

假设我有一个每个汽车经销商的汽车价格数据库,其中每个单元格都有与此类似的文本(注意:汽车经销商列可以是每行的索引):

<块引用>

"1 - 福特 (1) - 新:R$60000 / 二手:R$30000 轿车 2 - 梅赛德斯 - 奔驰 (1) - 全新:R$130000 / 二手:R$95000 银色轿车 3 - 奇瑞 (caoa) (1) - 新:R$80000 / 二手:R$60000 SUV 车 5 - 其他 (1) - 全新:90000 雷亚尔/二手:75500 雷亚尔掀背车”

Dataset example

感谢您的帮助!!

2 个答案:

答案 0 :(得分:0)

三步流程

  1. 使用 re.split() 将整个字符串拆分为行项目
  2. 使用 pandas extract 解析出行的组成部分
  3. 最终将数据框定形为宽...
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 福特 梅赛德斯-奔驰 奇瑞(caoa) 其他 60000 130000 80000 90000 30000 95000 60000 75500

答案 1 :(得分:0)

您可以使用 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
相关问题