【问题标题】:Slice pandas dataframe column into multiple columns using substring使用子字符串将熊猫数据框列切片为多列
【发布时间】:2022-11-22 19:36:10
【问题描述】:
数据框 'df' 具有以下数据 -
| Column A |
Column B |
| Item_ID1 |
Information - information for item that has ID as 1\nPrice - $7.99\nPlace - Albany, NY |
| Item_ID2 |
Information - item's information with ID as 2\nPrice - $5.99\nPlace - Ottawa, ON |
如何使用“信息”、“价格”和“地点”将 B 列中的值分离到不同的列中,例如 -
| Column A |
Information |
Price |
Place |
| Item_ID1 |
information for item that has ID as 1 |
$7.99 |
Albany, NY |
| Item_ID2 |
item's information with ID as 2 |
$5.99 |
Ottawa, ON |
我尝试根据 'Information - '、'Price - '、'Place - ' 等字符串值拆分 B 列,但这变得越来越复杂,第一个切片包含关于 Price 和 Place 的信息,这在其中不是必需的。
【问题讨论】:
标签:
python
pandas
dataframe
【解决方案1】:
您可以使用 pandas.Series.split 来解决这个问题:
df[["Information", "Price", "Place"]]= df.pop("Column B").str.split(r"\n", expand=True)
df= df.astype(str).apply(lambda x: x.replace(x.name, "", regex=True).str.strip(" - "))
# 输出 :
print(df.to_string())
Column A Information Price Place
0 Item_ID1 information for item that has ID as 1 $7.99 Albany, NY
1 Item_ID2 item's information with ID as 2 $5.99 Ottawa, ON
【解决方案2】:
对于不需要提前知道未来列的通用方法,可以使用 str.extractall 和 pivot:
out = df.drop(columns='Column B').join(
df['Column B']
.str.extractall(r'([^-]+) - ([^
]+)
?')
.droplevel('match')
.pivot(columns=0, values=1)
)
注意。我假设你有真正的换行符,如果你有两个字符 和 n,你可以用 df['Column B'] = df['Column B'].str.replace(r'\n', '
') 转换
输出:
Column A Information Place Price
0 Item_ID1 information for item that has ID as 1 Albany, NY $7.99
1 Item_ID2 item's information with ID as 2 Ottawa, ON $5.99
【解决方案3】:
另一种可能的解决方案,基于以下想法:
-
使用pandas.Series.str.split将Column B拆分为s-s|\n。
-
使用 numpy.reshape 重塑结果。
-
申请pandas.pivot_table。
(pd.concat([df['Column A'], pd.DataFrame(
df['Column B'].str.split(r's-s|\n', expand=True, regex=True).values
.reshape((-1,2)))
.pivot_table(columns=0, values=1, aggfunc=list)
.pipe(lambda d: d.explode(d.columns.tolist(), ignore_index=True))], axis=1))
输出:
Column A Information Place Price
0 Item_ID1 information for item that has ID as 1 Albany, NY $7.99
1 Item_ID2 item's information with ID as 2 Ottawa, ON $5.99