我正在使用DataQuest指导项目(https://www.dataquest.io/m/294/guided-project%3A-exploring-ebay-car-sales-data/)中提供的二手车数据集。我提供了此问题的数据样本。
我想做的是从汽车名称中删除多余的信息,例如品牌名称。品牌已经包含在数据的另一列中,并且此练习正在使用熊猫进行数据清理,因此,我想看看是否存在使用库功能替换此类子字符串的干净方法。我尝试将熊猫系列作为pat
中的Series.str.replace()
参数传递,但是显然它不起作用。在基于另一个系列的熊猫系列上执行矢量化替换的干净方法是什么?
理想情况下,'Peugeot_807_160_NAVTECH_ON_BOARD'
将变成'_807_160_NAVTECH_ON_BOARD'
,依此类推。
import pandas as pd
autos_dict = {
'brand': ['peugeot', 'bmw', 'volkswagen', 'smart', 'chrysler'],
'name': [
'Peugeot_807_160_NAVTECH_ON_BOARD',
'BMW_740i_4_4_Liter_HAMANN_UMBAU_Mega_Optik',
'Volkswagen_Golf_1.6_United',
'Smart_smart_fortwo_coupe_softouch/F1/Klima/Panorama',
'Chrysler_Grand_Voyager_2.8_CRD_Aut.Limited_Stow´n_Go_Sitze_7Sitze'
]
}
autos_df = pd.DataFrame.from_dict(autos_dict)
autos_df['name'].str.replace(autos_df['brand'], '', case=False)
返回以下错误消息:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/anaconda3/lib/python3.6/site-packages/pandas/core/strings.py", line 2429, in replace
flags=flags, regex=regex)
File "/anaconda3/lib/python3.6/site-packages/pandas/core/strings.py", line 656, in str_replace
compiled = re.compile(pat, flags=flags)
File "/anaconda3/lib/python3.6/re.py", line 233, in compile
return _compile(pattern, flags)
File "/anaconda3/lib/python3.6/re.py", line 289, in _compile
p, loc = _cache[type(pattern), pattern, flags]
File "/anaconda3/lib/python3.6/site-packages/pandas/core/generic.py", line 1489, in __hash__
' hashed'.format(self.__class__.__name__))
TypeError: 'Series' objects are mutable, thus they cannot be hashed
我可以使用原始Python做到这一点,所以只有在您具有基于熊猫的解决方案的情况下,请做出响应。
答案 0 :(得分:2)
您可以使用apply函数来做到这一点:
In [6]: def replace_brand(row):
...: return row['name'].lower().replace(row['brand'], '')
...:
In [8]: autos_df['name'] = autos_df.apply(lambda row: replace_brand(row), axis=1)
In [9]: autos_df
Out[9]:
brand name
0 peugeot _807_160_navtech_on_board
1 bmw _740i_4_4_liter_hamann_umbau_mega_optik
2 volkswagen _golf_1.6_united
3 smart __fortwo_coupe_softouch/f1/klima/panorama
4 chrysler _grand_voyager_2.8_crd_aut.limited_stow´n_go_s...
答案 1 :(得分:1)
没有apply
r = {v: '' for _, v in df.brand.to_dict().items()}
df.name.str.lower().replace(r, regex=True)
输出
0 _807_160_navtech_on_board
1 _740i_4_4_liter_hamann_umbau_mega_optik
2 _golf_1.6_united
3 __fortwo_coupe_softouch/f1/klima/panorama
4 _grand_voyager_2.8_crd_aut.limited_stow´n_go_s...
Name: name, dtype: object
答案 2 :(得分:1)
您只需要使用忽略大小写的正则表达式即可,即(?i)
与re.I
相同。由于df.replace
不带标志参数,因此您将手动调用它。这样可以确保所有其他字符都保持删除前的状态。也就是说,如果它们是资本,它们将保持不变,反之亦然
autos_df.name.replace(regex=r'(?i)'+ autos_df.brand,value="")
Out[1726]:
0 _807_160_NAVTECH_ON_BOARD
1 _740i_4_4_Liter_HAMANN_UMBAU_Mega_Optik
2 _Golf_1.6_United
3 __fortwo_coupe_softouch/F1/Klima/Panorama
4 _Grand_Voyager_2.8_CRD_Aut.Limited_Stow´n_Go_S...
Name: name, dtype: object