我有一个数据框如下:
Honda [edit]
Accord (4 models)
Civic (4 models)
Pilot (3 models)
Toyota [edit]
Prius (4 models)
Highlander (3 models)
Ford [edit]
Explorer (2 models)
Run Code Online (Sandbox Code Playgroud)
我希望重塑它,以便得到如下结果的2列数据框:
Honda Accord
Honda Civic
Honda Pilot
Toyota Prius
Toyota Highlander
Run Code Online (Sandbox Code Playgroud)
等等.我试过str.split尝试在编辑之间分割,但没有成功.任何建议都非常感谢!Python新手在这里...如果之前已经解决过这么道歉.谢谢!
到目前为止我试过了
maker=car['T'].str.extract('(.*\[edit\])', expand=False).str.replace('\[edit\]',"")
Run Code Online (Sandbox Code Playgroud)
这给了我制造商的名单:本田,丰田和福特.然而,我一直在寻找一种方法来提取制造商之间的模型来创建2 col DF.
sgD*_*ion 12
诀窍是首先提取汽车列,然后获取制造商.
import pandas as pd
import numpy as np
df['model'] = df['T'].apply(lambda x: x.split(
'(')[0].strip() if x.count('(') > 0 else np.NaN)
df['maker'] = df['T'].apply(lambda x: x.split('[')[0].strip(
) if x.count('[') > 0 else np.NaN).fillna(method="ffill")
df = df.dropna().drop('T', axis=1).reindex(
columns=['maker', 'model']).reset_index(drop=True)
Run Code Online (Sandbox Code Playgroud)
代码的第一行通过使用拆分和条带字符串操作提取所有汽车,如果包含的条目'('
,NaN
否则我们使用,NaN
以便我们可以在找到制造商后删除这些行.在此阶段,数据框df
将是:
+----+-----------------------+------------+
| | T | model |
|----+-----------------------+------------|
| 0 | Honda [edit] | nan |
| 1 | Accord (4 models) | Accord |
| 2 | Civic (4 models) | Civic |
| 3 | Pilot (3 models) | Pilot |
| 4 | Toyota [edit] | nan |
| 5 | Prius (4 models) | Prius |
| 6 | Highlander (3 models) | Highlander |
| 7 | Ford [edit] | nan |
| 8 | Explorer (2 models) | Explorer |
+----+-----------------------+------------+
Run Code Online (Sandbox Code Playgroud)
第二行是相同的,但对于'['
记录,这里NaNs
用于使用fillna填充空的制造商单元格
在此阶段,数据框架df
将是:
+----+-----------------------+------------+---------+
| | T | model | maker |
|----+-----------------------+------------+---------|
| 0 | Honda [edit] | nan | Honda |
| 1 | Accord (4 models) | Accord | Honda |
| 2 | Civic (4 models) | Civic | Honda |
| 3 | Pilot (3 models) | Pilot | Honda |
| 4 | Toyota [edit] | nan | Toyota |
| 5 | Prius (4 models) | Prius | Toyota |
| 6 | Highlander (3 models) | Highlander | Toyota |
| 7 | Ford [edit] | nan | Ford |
| 8 | Explorer (2 models) | Explorer | Ford |
+----+-----------------------+------------+---------+
Run Code Online (Sandbox Code Playgroud)
第三行删除额外记录并重新排列列以及重置索引
| | maker | model |
|----+---------+------------|
| 0 | Honda | Accord |
| 1 | Honda | Civic |
| 2 | Honda | Pilot |
| 3 | Toyota | Prius |
| 4 | Toyota | Highlander |
| 5 | Ford | Explorer |
Run Code Online (Sandbox Code Playgroud)
编辑:
一个更"可爱"的版本(我喜欢一个衬垫)
df = df['T'].str.extractall('(.+)\[|(.+)\(').apply(
lambda x: x.ffill()
if x.name==0
else x).dropna(subset=[1]).reset_index(
drop=True).rename(columns={1:'Model',0:'Maker'})
Run Code Online (Sandbox Code Playgroud)
以上工作如下
extractall
将返回一个包含两列的DataFrame; 列0
对应于在使用第一组中提取的正则表达式的组'(.+)\['
即与截至制造者记录; 和列1
,对应于所述第二组,即'(.+)\('
,apply
用于通过列迭代,命名列0
将被修改以通过前向传播"设备"值ffill
和列1
将被保持原样.dropna
然后用子集用于1
以除去其中在列中的值的所有行1
被NaN
,reset_index
用于删除所述MULT指数extractall
生成.最后使用rename
和对应字典重命名列
另一个班轮(func;))
df['T'].apply(lambda line: [line.split('[')[0],None] if line.count('[')
else [None,line.split('(')[0].strip()]
).apply(pd.Series
).rename(
columns={0:'Maker',1:'Model'}
).apply(
lambda col: col.ffill() if col.name == 'Maker'
else col).dropna(
subset=['Model']
).reset_index(drop=True)
Run Code Online (Sandbox Code Playgroud)
您可以extract
与ffill
. 然后删除包含[edit]
byboolean indexing
和 mask by 的行str.contains
,然后reset_index
为 create uniqueindex
和最后删除原始列col
by drop
:
df['model'] = df.col.str.extract('(.*)\[edit\]', expand=False).ffill()
df['type'] = df.col.str.extract('([A-Za-z]+)', expand=False)
df = df[~df.col.str.contains('\[edit\]')].reset_index(drop=True).drop('col', axis=1)
print (df)
model type
0 Honda Accord
1 Honda Civic
2 Honda Pilot
3 Toyota Prius
4 Toyota Highlander
5 Ford Explorer
Run Code Online (Sandbox Code Playgroud)
另一种解决方案使用extract
并按where
条件创建新列并boolean indexing
再次使用:
df['type'] = df.col.str.extract('([A-Za-z]+)', expand=False)
df['model'] = df['type'].where(df.col.str.contains('\[edit\]')).ffill()
df = df[df.type != df.model].reset_index(drop=True).drop('col', axis=1)
print (df)
type model
0 Accord Honda
1 Civic Honda
2 Pilot Honda
3 Prius Toyota
4 Highlander Toyota
5 Explorer Ford
Run Code Online (Sandbox Code Playgroud)
编辑:
如果需要type
用spaces
文字,用replace
所有值从(到最后,也被删除空格s\+
:
print (df)
col
0 Honda [edit]
1 Accord (4 models)
2 Civic (4 models)
3 Pilot (3 models)
4 Toyota [edit]
5 Prius (4 models)
6 Highlander (3 models)
7 Ford [edit]
8 Ford Expedition XL (2 models)
df['model'] = df.col.str.extract('(.*)\[edit\]', expand=False).ffill()
df['type'] = df.col.str.replace(r'\s+\(.+$', '')
df = df[~df.col.str.contains('\[edit\]')].reset_index(drop=True).drop('col', axis=1)
print (df)
model type
0 Honda Accord
1 Honda Civic
2 Honda Pilot
3 Toyota Prius
4 Toyota Highlander
5 Ford Ford Expedition XL
Run Code Online (Sandbox Code Playgroud)