[英]Pandas dataframe: select list items in a column, then transform string on the items
我要导入到我的数据框中的一列是一个列表。 我需要从所述列表中选择某些值,转换该值并将其添加到数据框中的两个新列之一。 前:
姓名 | Listed_Items |
---|---|
汤姆 | [“dr_md_coca_cola”、“dr_od_water”、“土豆”、“草”、“ot_other_stuff”] |
史蒂夫 | [“dr_od_orange_juice”、“土豆”、“草”、“ot_other_stuff”、“dr_md_pepsi”] |
菲尔 | [“dr_md_dr_pepper”、“土豆”、“草”、“dr_od_coffee”、“ot_other_stuff”] |
根据我的阅读,我可以将该列变成一个列表
df["listed_items"] = df["listed_items"].apply(eval)
但是我看不到如何找到任何以dr_md 开头的列表项,提取该项目,删除起始 dr_md ,替换任何下划线,将第一个字母大写并将其添加到行中的新MD列中。 然后对dr_od再次进行同样的操作。 列表中只有一项在每一行中以dr_md和dr_od开头。 期望的输出
姓名 | 医学博士 | 外径 |
---|---|---|
汤姆 | 可口可乐 | 水 |
史蒂夫 | 百事可乐 | 橙汁 |
菲尔 | 胡椒博士 | 咖啡 |
使用pivot_table
df = df.explode('Listed_Items')
df = df[df.Listed_Items.str.contains('dr_')]
df['Type'] = df['Listed_Items'].str.contains('dr_md').map({True: 'MD',
False: 'OD'})
df.pivot_table(values='Listed_Items',
columns='Type',
index='Name',
aggfunc='first')
Type MD OD
Name
Phil dr_md_dr_pepper dr_od_coffee
Steve dr_md_pepsi dr_od_orange_juice
Tom dr_md_coca_cola dr_od_water
从这里开始,只需按照您的意愿美化您的数据集。
您需要做的是创建一个为您执行处理的函数,您可以将其传递给apply
(或在本例中为map
)。 或者,您可以将列表列扩展为多个列,然后再处理它们,但这仅在您的列表始终处于相同顺序时才有效(请参阅panda expand columns with list into multiple columns )。 因为您只有一个输入列,所以您可以使用map
而不是apply
。
def process_dr_md(l:list):
for s in l:
if s.startswith("dr_md_"):
# You can process your string further here
return l[6:]
def process_dr_od(l:list):
for s in l:
if s.startswith("dr_od_"):
# You can process your string further here
return l[6:]
df["listed_items"] = df["listed_items"].map(eval)
df["MD"] = df["listed_items"].map(process_dr_md)
df["OD"] = df["listed_items"].map(process_dr_od)
我希望这能让你上路!
我采取了与以前的答案略有不同的方法。 给定一个 df 形式:
Name Items
0 Tom [dr_md_coca_cola, dr_od_water, potatoes, grass...
1 Steve [dr_od_orange_juice, potatoes, grass, ot_other...
2 Phil [dr_md_dr_pepper, potatoes, grass, dr_od_coffe...
并做出以下假设:
我创建了以下函数来解析列表:
import re
def parse_Items(tgt_mask: str, itmList: list) -> str:
p = re.compile(tgt_mask)
for itm in itmList:
if p.match(itm):
return itm[p.search(itm).span()[1]:].replace('_', ' ')
然后,您可以使用以下内容修改原始数据场:
df['MD'] = [parse_Items('dr_md_', x) for x in df['Items'].to_list()]
df['OD'] = [parse_Items('dr_od_', x) for x in df['Items'].to_list()]
df.pop('Items')
这会产生以下结果:
Name MD OD
0 Tom coca cola water
1 Steve pepsi orange juice
2 Phil dr pepper coffee
我会在放入数据框之前对数据进行规范化:
import pandas as pd
from typing import Dict, List, Tuple
def clean_stuff(text: str):
clean_text = text[6:].replace('_', ' ')
return " ".join([
word.capitalize()
for word in clean_text.split(" ")
])
def get_md_od(stuffs: List[str]) -> Tuple[str, str]:
md_od = [s for s in stuffs if s.startswith(('dr_md', 'dr_od'))]
md_od = sorted(md_od)
print(md_od)
return clean_stuff(md_od[0]), clean_stuff(md_od[1])
dirty_stuffs = [{'Name': 'Tom',
'Listed_Items': ["dr_md_coca_cola",
"dr_od_water",
"potatoes",
"grass",
"ot_other_stuff"]},
{'Name': 'Tom',
'Listed_Items': ["dr_md_coca_cola",
"dr_od_water",
"potatoes",
"grass",
"ot_other_stuff"]}
]
normalized_stuff: List[Dict[str, str]] = []
for stuff in dirty_stuffs:
md, od = get_md_od(stuff['Listed_Items'])
normalized_stuff.append({
'Name': stuff['Name'],
'MD': md,
'OD': od,
})
df = pd.DataFrame(normalized_stuff)
print(df)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.